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
Enums as separate models #1432
Enums as separate models #1432
Conversation
Codecov Report
@@ Coverage Diff @@
## master #1432 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 21 21
Lines 3747 3793 +46
Branches 742 752 +10
=========================================
+ Hits 3747 3793 +46
Continue to review full report at Codecov.
|
@samuelcolvin One of the fastapi tests is currently failing since it's expecting an OpenAPI schema for the old enum behavior: What's the best way to handle this? Should I open another PR updating the fastapi test now, or should I do it once this PR gets merged in? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
generally looks good, but I wonder whether this needs to wait until v2.
@tiangolo do you have an opinion on whether this would be considered a breaking change?
pydantic/schema.py
Outdated
@@ -516,6 +516,27 @@ def model_type_schema( | |||
return out_schema, definitions, nested_models | |||
|
|||
|
|||
def enum_process_schema(enum: EnumMeta) -> Dict[str, Any]: | |||
""" | |||
Take a single ``enum`` and generate its schema. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Take a single ``enum`` and generate its schema. | |
Take a single `enum` and generate its schema. |
docstrings currently aren't rendered as rst or md, but if they ever are, it'll be as markdown, see #1339.
And below.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That sounds awesome. Would it be helpful if I replaced all of the double-tick characters with ` in this file? Or would you prefer that I only update the double-ticks characters that were added by this PR to keep it cleaner?
Should be fixed if you rebase. |
@samuelcolvin Got it. Also thanks for the comments — I just pushed the suggested fixes. I'll defer to you and @tiangolo with regard to the release schedule. In theory this shouldn't be a breaking change so long as the end user is following the Open API spec. But I also understand these things don't always work out so cleanly. |
@calvinwyoung can you rebase to master. @tiangolo would love your feedback on the V2 decision. |
Sorry for the delay on this... I think I finally found a way to filter and label GitHub notifications with mentions 😅 I like this! 🚀 🎉 I've been trying to think of a way that this could break something badly enough as to be considered a "breaking change", but I haven't found anything. I don't expect FastAPI users to test their OpenAPI schemas as FastAPI already tests the generation of valid OpenAPI. The only concern I have is, @calvinwyoung , have you tested how this looks like in the But apart from that I think this should be safe to release in a MINOR bump. I can update the tests in FastAPI to accept the schemas generated by this and release a minor version, that should make tests pass here. ✔️ |
Oh so the failing FastAPI tests are real - catching an actual change with a test! 😆 I guess you'll have to get the test to pass with both the old and new schema for a while. Let us know when you've updated FastAPI and we'll get tests passing here. |
So, I rushed to add the extra check in the tests and release a new version. But now I realized that it breaks Swagger UI 🤦 . I'm now checking what needs to be changed in this PR and in FastAPI, I'm getting deeper and deeper into this... 😅 I'll keep reporting here what I find. Would it be fine if I commit on top of this same branch? Or would it be better if I submit a new PR with extra changes on top of this? |
@tiangolo Thanks so much for taking a look at this. I had thought I tested the Swagger UI previously, and it seemed to work okay. Before this PR, the After this PR, the schemas render like this: And we also have a new Where else are you seeing breaking changes? And yes, feel free to commit directly on top of the same branch! Thanks again — really appreciate the work you and @samuelcolvin have put into maintaining these two incredible projects 🥇 |
as they now have independent schemas, they kinda behave like top-level models, and should be taken into account for top level definitions
Fine by me if you commit directly to the branch for this PR, it might be simpler than a PR into this PR. I hope @calvinwyoung doesn't mind. |
I think that should work 🚀 I updated FastAPI, it ended up touching a bunch of places 😅 The main issue was that enums are supported for parameters in path, cookie, query, etc. And those didn't have a way to collect additional schema definitions. But this is supported now in 0.55.1 (just released). I updated it here to include enums when collecting flat models and treat them as sort of top-level models for schema generation, as they get their own independent definitions. In short, this works correctly with the current FastAPI (and any other libraries that use this). I added a couple of alias types to reduce duplication, but that can be changed if you prefer @samuelcolvin . If you think this is fine, it's also ready from my side 🙂 🚀 |
Awesome, thank you both. |
@tiangolo Ah yes that makes complete sense. Thank you! |
Change Summary
This PR updates the OpenAPI schema generation behavior so that all enums are outputted as separate models, following the recipe for reusable enums. The primary benefit is to improve support for OpenAPI code generation tools — more on this below.
To illustrate the changes, suppose we have the following models:
Prior to this PR, the generated schema would look like the following:
Notice how the enum values are duplicated in both the
Foo
andBar
definitions. As a result, an OpenAPI code generation tool will create 2 definitions of the enum — one forModelAFoo
and one forModelBFoo
. This is obviously not ideal as it makes it harder to reuse the enum definition in the client code.With this PR, the generated schema will instead look like this:
As a result, an OpenAPI code generation tool will output a single
Foo
enum definition that's referenced by bothModelA
andModelB
.This PR works seamlessly with fastapi v0.54.1 and with openapi-generator-cli via the
openapitools/openapi-generator-cli
docker image v4.3.0.Related issue number
#1173
Checklist
changes/<pull request or issue id>-<github username>.md
file added describing change(see changes/README.md for details)