-
Notifications
You must be signed in to change notification settings - Fork 35
This issue was moved to a discussion.
You can continue the conversation there. Go to discussion →
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
FastAPI shows no attributes for models. #150
Comments
can you add another pydantic model (outside geojson-pydantic) because I feel this is a pydantic issue not directly a geojson-pydantic one can you try with |
I've edited the code: from fastapi import FastAPI
from geojson_pydantic import FeatureCollection
from pydantic import BaseModel, Field
class SomeModel(BaseModel):
lorem: str = Field(..., description="describe me")
ipsum: int
app = FastAPI(
title="Test geojson-pydantic",
version="1.0"
)
@app.get("/{dataset}", response_model=FeatureCollection)
def get_dataset(dataset: str):
raise NotImplementedError
@app.get("/another/{dataset}", response_model=SomeModel)
def get_another_dataset(dataset: str):
raise NotImplementedError which results in: |
No change with |
There's definitely something going one with fastapi/pydantic if you add from fastapi import FastAPI, Body
from geojson_pydantic import FeatureCollection
from pydantic import BaseModel, Field
from typing_extensions import Annotated
class SomeModel(BaseModel):
lorem: str = Field(..., description="describe me")
ipsum: int
app = FastAPI(
title="Test geojson-pydantic",
version="1.0"
)
@app.get("/{dataset}", response_model=FeatureCollection)
def get_dataset(dataset: str):
raise NotImplementedError
@app.get("/another/{dataset}", response_model=SomeModel)
def get_another_dataset(dataset: str):
raise NotImplementedError
@app.get("/{dataset}", response_model=FeatureCollection)
def get_dataset(body: Annotated[FeatureCollection, Body()]):
raise NotImplementedError |
"FeatureCollection-Input": {
"properties": {
"bbox": {
"anyOf": [
{
"prefixItems": [
{
"type": "number"
},
{
"type": "number"
},
{
"type": "number"
},
{
"type": "number"
}
],
"type": "array",
"maxItems": 4,
"minItems": 4
},
{
"prefixItems": [
{
"type": "number"
},
{
"type": "number"
},
{
"type": "number"
},
{
"type": "number"
},
{
"type": "number"
},
{
"type": "number"
}
],
"type": "array",
"maxItems": 6,
"minItems": 6
},
{
"type": "null"
}
],
"title": "Bbox"
},
"type": {
"const": "FeatureCollection",
"title": "Type"
},
"features": {
"items": {
"$ref": "#/components/schemas/Feature-Input"
},
"type": "array",
"title": "Features"
}
},
"type": "object",
"required": [
"type",
"features"
],
"title": "FeatureCollection",
"description": "FeatureCollection Model"
},
"FeatureCollection-Output": {
"type": "object",
"title": "FeatureCollection",
"description": "FeatureCollection Model"
}, interesting that when |
Replacing from typing import Any, Dict, Generic, Iterator, List, Literal, Optional, TypeVar, Union
from pydantic import BaseModel, Field, StrictInt, StrictStr, field_validator
# from geojson_pydantic.base import _GeoJsonBase
from geojson_pydantic.geometries import Geometry
Props = TypeVar("Props", bound=Union[Dict[str, Any], BaseModel])
Geom = TypeVar("Geom", bound=Geometry)
class Feature(BaseModel, Generic[Geom, Props]):
"""Feature Model"""
type: Literal["Feature"]
geometry: Union[Geom, None] = Field(...)
properties: Union[Props, None] = Field(...)
id: Optional[Union[StrictInt, StrictStr]] = None
__geojson_exclude_if_none__ = {"bbox", "id"}
@field_validator("geometry", mode="before")
def set_geometry(cls, geometry: Any) -> Any:
"""set geometry from geo interface or input"""
if hasattr(geometry, "__geo_interface__"):
return geometry.__geo_interface__
return geometry
Feat = TypeVar("Feat", bound=Feature)
class FeatureCollection(BaseModel, Generic[Feat]):
"""FeatureCollection Model"""
type: Literal["FeatureCollection"]
features: List[Feat]
def __iter__(self) -> Iterator[Feat]: # type: ignore [override]
"""iterate over features"""
return iter(self.features)
def __len__(self) -> int:
"""return features length"""
return len(self.features)
def __getitem__(self, index: int) -> Feat:
"""get feature at a given index"""
return self.features[index] |
narrowing down this to geojson-pydantic/geojson_pydantic/base.py Lines 55 to 73 in b1ecd86
if we remove ☝️ it's fine! |
:)), yep, I just got there myself. |
confirmed this is not a geojson-pydantic issue. It's more a FastAPI (or a pydantic) one! from typing import Any, Dict
from fastapi import FastAPI
from pydantic import BaseModel, Field, SerializationInfo, model_serializer
class SomeModel(BaseModel):
lorem: str = Field(..., description="describe me")
ipsum: int
@model_serializer(when_used="always", mode="wrap")
def clean_model(self, serializer: Any, info: SerializationInfo) -> Dict[str, Any]:
data: Dict[str, Any] = serializer(self)
return data
app = FastAPI()
@app.get("/another/{dataset}", response_model=SomeModel)
def get_another_dataset(dataset: str):
raise NotImplementedError |
This issue was moved to a discussion.
You can continue the conversation there. Go to discussion →
This simple FastAPI script:
Creates this result in
/docs
:See here for a simple project.
Edit:
The text was updated successfully, but these errors were encountered: