Skip to content
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

make feature geometry optional #47

Merged

Conversation

yellowcap
Copy link
Member

What I am changing

According to the specs, the geometry attribute of a geojson Feature can be set to null. See https://datatracker.ietf.org/doc/html/rfc7946#section-3.2 . But the geometry in the Feature definition in geosjon-pydantic is required.

How I did it

Wrap the geometry value with an Optional[] tag in the feature definition.

How you can test it

I added a test for this case, but I am not sure if the test is sufficient the way I wrote it. I am not very familiar with pydantic.

Related Issues

Fixes #46

I came across this problem while using stac-fastapi, which uses stac-pydantic, which uses this library. The downstream issues are the following:
stac-utils/stac-pydantic#107
stac-utils/stac-fastapi#350

@vincentsarago
Copy link
Member

thanks @yellowcap

@geospatial-jeff can you double check that this change is ok?

Copy link
Contributor

@geospatial-jeff geospatial-jeff left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@geospatial-jeff
Copy link
Contributor

geospatial-jeff commented Feb 25, 2022

One note on this change. Because the Optional is implemented inside of the model any generic type that is passed in through Geom will be optional. If the Optional was implemented outside of the model in the typevar itself the generic type may be required.

Not really sure which is best. I guess there are use cases where you want to enforce that the geometry IS there, so maybe we should do the latter?

@vincentsarago
Copy link
Member

Not really sure which is best. I guess there are use cases where you want to enforce that the geometry IS there, so maybe we should do the latter?

🤔 I'm not sure to follow, can we write tests or pseudo code?

@geospatial-jeff
Copy link
Contributor

geospatial-jeff commented Feb 27, 2022

It's just a difference in where the Optional is declared.

# Optional defined inside pydantic model
class Feature(GenericModel, Generic[Geom, Props]):
    geometry: Optional[Geom]
    ....

# Or it can be defined in the `Geom` typevar
Geom = TypeVar("Geom", bound=Optional[Geometry])

If its declared inside the model, a user might set the Geom typevar to lets say geojson_pydantic.MultiPoint and that type will be coerced to Optional[MultiPoint]:

feat = Feature[MultiPoint, Props]
feat(geometry=None)

If it is declared in the typevar it's up to the user to define if the geometry is optional or not, which I think provides a better and more declarative interface:

feat = Feature[Optional[MultiPoint], Props]
feat(geometry=None)

Conversely, with the Optional defined in the typevar you can also specify that the geometry is required (this is not possible if Optional is baked into the pydantic model):

# Raises `ValidationError`
feat = Feature[MultiPoint, Props]
feat(geometry=None)

@vincentsarago
Copy link
Member

I think I prefer the typeVar way!

any feedback @yellowcap ?

@yellowcap yellowcap force-pushed the make-feature-geometry-optional branch from e5ecc3b to 8c408ab Compare March 2, 2022 21:20
@yellowcap
Copy link
Member Author

The question about where to put the Optional wrapper is a small but important point. Great explanation of the difference, it helped me a lot to understand what you were referring to. Thaks for that @geospatial-jeff!

I agree with @vincentsarago , the typeVar way is the way. It covers a more general use case of the geojson Feature type, and still makes the geom attribute optional in the default Feature type.

I changed the PR accordingly, please have another look and let me know if its ok like that.

@codecov-commenter
Copy link

codecov-commenter commented Mar 4, 2022

Codecov Report

Merging #47 (8c408ab) into master (4608687) will not change coverage.
The diff coverage is 100.00%.

Impacted file tree graph

@@            Coverage Diff            @@
##            master       #47   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files            4         4           
  Lines          106       106           
=========================================
  Hits           106       106           
Flag Coverage Δ
unittests 100.00% <100.00%> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
geojson_pydantic/features.py 100.00% <100.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 4608687...8c408ab. Read the comment docs.

@vincentsarago
Copy link
Member

thanks @yellowcap 🙏

I'll update the changelog and the documentation and try to cut a new release today 🥳

@vincentsarago vincentsarago merged commit 9415f96 into developmentseed:master Mar 4, 2022
@yellowcap
Copy link
Member Author

Good stuff! Thanks for the help @geospatial-jeff and @vincentsarago 😺

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Geometry field of Feature definition should be optional
4 participants