You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Is your feature request related to a problem? Please describe.
The current python-fastapi generator seems to be geared towards a one-time generation of the python server rather than a continuous spec-first approach. For example:
When I run openapi-generator -i <path_to_spec> -g python-fastapi, a file src/openapi/apis/default_api.py (among other things) is autogenerated containing the following code:
The problem with this code gen pattern is that it doesn't enable a spec-first workflow because it doesn't separate API contract declaration from its implementation. That is, if I implement the generated hello_world_get method, then regenerate the file from the OpenAPI spec, my implementation gets overwritten.
If this was say, Java, the endpoints would be encapsulated under an interface like:
// DefaultAPI.java// This interface is autogenerated interfaceDefaultAPI() {
InlineResponse200helloWorld();
}
If a new method is added to the spec or an existing method is updated, I would run the generator and it would update DefaultAPI.java with any new parameters, return types, API endpoints, etc... And because the implementation (which I create by hand) implements that interface, the build will fail if one of the signatures doesn't correctly match or if an endpoint is not implemented.
Describe the solution you'd like
I'd love to start a conversation about whether the generator intends to evolve in this direction or if I'm just misunderstanding its usage pattern. Ideally, the code generated above enables two development experience invariants:
allow separating the implementation of api endpoints from their declaration
detect if an API method in the spec was not implemented by the developer or implemented with incorrect signatures and raise an exception during CI or tests
I have some outlines of a solution and would love some feedback. Basically, we'd change the structure of the generator to have the following output components:
for each API, there is an ABC declaring the methods a developer needs to implement. Each such method corresponds to one API endpoint.
For each API, the user implements a class which extends the ABC from step 1 in a separate file
The user manually has to write the main.py file which initializes the FastAPI instance which actually launches the server, using the implementation they created from step 2 to initialize any routers.
I've included some pseudocode below that demoes what this would look like on the OpenAPI spec above:
default_api.py (this file is autogenerated):
classAPIInterface(ABC):
# autogenned, contains pythonic signature of api@abstractmethodasyncdefhello_world():
""" hello world """definitialize_router(api: APIInterface) ->APIRouter:
router=APIRouter()
# Directly add the method as a route implementation # instead of adding via decoration (which is the current approach)router.get(
"/hello_world",
responses={
200: {"model": InlineResponse200, "description": "Successful operation"},
},
tags=["default"],
)
# for each endpoint, do the same thing...# ...# at the end just return the routerreturnrouter
api_implementation.py (this file is written and maintained by the user):
fromdefault_apiimportAPIInterface# handwritten implementation of the API methodsclassAPIImplementation(APIInterface):
asyncdefhello_world():
# code code code
main.py (this file is written and maintained by the user, although we can probably automate some parts of it. Not essential that we do that for the sake of this discussion):
# The user must manually write this classfromdefault_apiimportinitialize_routerfromapi_implementationimportAPIImplementationapp=FastAPI(
title="my API",
description=" API ",
version="1.0.0",
)
app.include_router(initialize_router(APIImplementation()))
Would love some feedback on this approach and whether there is any appetite for adopting it.
The text was updated successfully, but these errors were encountered:
Tagging @spacether as a member of the Python technical committee and @krjakbrjak as the package creator. Any feedback on the problem above and the suggested solution?
Is your feature request related to a problem? Please describe.
The current python-fastapi generator seems to be geared towards a one-time generation of the python server rather than a continuous spec-first approach. For example:
Let's say I have the following OpenAPI spec
When I run
openapi-generator -i <path_to_spec> -g python-fastapi
, a filesrc/openapi/apis/default_api.py
(among other things) is autogenerated containing the following code:The problem with this code gen pattern is that it doesn't enable a spec-first workflow because it doesn't separate API contract declaration from its implementation. That is, if I implement the generated
hello_world_get
method, then regenerate the file from the OpenAPI spec, my implementation gets overwritten.If this was say, Java, the endpoints would be encapsulated under an interface like:
Then in a separate file I'd implement the API
If a new method is added to the spec or an existing method is updated, I would run the generator and it would update
DefaultAPI.java
with any new parameters, return types, API endpoints, etc... And because the implementation (which I create by hand) implements that interface, the build will fail if one of the signatures doesn't correctly match or if an endpoint is not implemented.Describe the solution you'd like
I'd love to start a conversation about whether the generator intends to evolve in this direction or if I'm just misunderstanding its usage pattern. Ideally, the code generated above enables two development experience invariants:
I have some outlines of a solution and would love some feedback. Basically, we'd change the structure of the generator to have the following output components:
ABC
declaring the methods a developer needs to implement. Each such method corresponds to one API endpoint.ABC
from step 1 in a separate filemain.py
file which initializes theFastAPI
instance which actually launches the server, using the implementation they created from step 2 to initialize any routers.I've included some pseudocode below that demoes what this would look like on the OpenAPI spec above:
default_api.py
(this file is autogenerated):api_implementation.py
(this file is written and maintained by the user):main.py
(this file is written and maintained by the user, although we can probably automate some parts of it. Not essential that we do that for the sake of this discussion):Would love some feedback on this approach and whether there is any appetite for adopting it.
The text was updated successfully, but these errors were encountered: