-
Notifications
You must be signed in to change notification settings - Fork 38
propose .make method to create Features without needing to specify all parameters #174
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
base: main
Are you sure you want to change the base?
propose .make method to create Features without needing to specify all parameters #174
Conversation
Actually I just wanted to add a default value to the class Feature(_GeoJsonBase, Generic[Geom, Props]):
"""Feature Model"""
type: Literal["Feature"] = "Feature"
geometry: Union[Geom, None] = Field(...)
properties: Union[Props, None] = Field(...)
id: Optional[Union[StrictInt, StrictStr]] = None but then I realized that this will stop pydantic to raise I'm not entirely happy with the
|
@kopp Are you sure that breaks? It's a bit hard to tell because your example is not repeatable. This is working for me: from typing import Generic, Literal, Union, Optional
from pydantic import Field, StrictInt, StrictStr
from geojson_pydantic.base import _GeoJsonBase
from geojson_pydantic.features import Props, Geom
class Feature(_GeoJsonBase, Generic[Geom, Props]):
"""Feature Model"""
type: Literal["Feature"] = "Feature"
geometry: Union[Geom, None] = Field(...)
properties: Union[Props, None] = Field(...)
id: Optional[Union[StrictInt, StrictStr]] = None
feat = {
"geometry": {
"type": "Polygon",
"coordinates": [
[[100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0]]
],
},
"properties": {"prop0": "value0", "prop1": {"this": "that"}},
}
m = Feature.model_validate(feat)
assert m.type == "Feature" We won't be able to have the Pydantic isn't aware if your data is coming from a JSON document or from constructing the model directly. |
I'd recommend subclassing if you have a use-case that does require an optional from typing import Literal
from geojson_pydantic.features import Feature
class FeatureWithOptionalType(Feature):
"""Feature Model"""
type: Literal["Feature"] = "Feature"
feat = {
"geometry": {
"type": "Polygon",
"coordinates": [
[[100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0]]
],
},
"properties": {"prop0": "value0", "prop1": {"this": "that"}},
}
m = FeatureWithOptionalType.model_validate(feat)
assert m.type == "Feature" |
Thanks @geospatial-jeff for the reply and sorry for not being precise in my post. My point was, that your first example should actually fail with a ValidationError, because the type is missing. You do not want to allow a json/dict without type. (At least that is my understanding of the design choices in the library.) Subclassing (also my first attempt) will also allow that you parse an invalid GeoJSON. My point is, I actually want to still only allow valid GeoJSON to be read and written, but when creating python objects I do not want to repeat myself (DRY) I saying that a Feature is of type Feature. Using .make in python code is a workaround that satisfied these two requirements. |
You can consider this proposal as compromise for the same issue raised in #171 . |
I understand your point, and I do wish that pydantic had better behavior here. Personally I prefer the However I'm not sure that
While the GeoJSON spec says that
|
Yes, exactly. I would even extend that -- users wanting validation should call a If I'm not mistaken, calling Accessing the |
Thanks for jumping into this @geospatial-jeff 🙏 To be honest this feels a bit weird to have to use if we were to move forward with this, users will come and ask for this to be implemented for feature collections and Geometries... at the end of the day it will add a lot to maintain. I get the frustration of having to pass |
I would like to propos to add a
make
function to the pydantic models that will take the arguments but with 'sane defaults'.Using this, some redundant information can be omitted:
If you think this is a fair idea, I can add
make
s for the other types as well.