apigenie-generatorOpenAPI serversserver fastapi
server fastapi
Generate a Python FastAPI server from an OpenAPI document.
Usage
apigenie-generator server fastapi [...OPTIONS] INPUT_FILE
Description
The generated project has the layout of the python-fastapi generator of
openapi-generator and accepts its options, so a project generated
by openapi-generator can be generated again by API Genie. The code itself is written for FastAPI
0.115+, pydantic 2.7+ and Python 3.10+:
pyproject.toml, requirements.txt, README.md, Dockerfile, docker-compose.yaml, openapi.yaml
src/openapi_server/
main.py the application: includes the routers, loads the implementation
apis/pets_api.py the routes of the "pets" API (one module per tag)
apis/pets_api_base.py BasePetsApi: the methods to implement
impl/__init__.py the implementation package, yours
models/ pydantic models, one module per schema
security_api.py the dependencies checking credentials
tests/ pytest tests with FastAPI's TestClient
Routes validate requests, then call the methods of the base class of their API, which answer 501 Not Implemented. Implement them in a subclass, in a module of the implementation package:
from openapi_server.apis.pets_api_base import BasePetsApi
from openapi_server.models import Pet
class PetsApi(BasePetsApi):
async def show_pet_by_id(self, *, pet_id: str) -> Pet:
return Pet(id=1, name="Rex")
The application imports the modules of the implementation package when it starts, and the first
subclass of a base class serves its requests. Tests can replace it with
app.dependency_overrides[get_pets_api]. Credentials are validated the same way, by a subclass of
BaseSecurity of security_api.py.
The generated code covers:
- routes with the status code, response class, documented responses (including
default, ranges like4XXand headers), tags, summary, description, operation ID and deprecation of operations; routes of concrete paths come before the routes of templates matching them - path, query, header and cookie parameters with their aliases, defaults and constraints, JSON,
text and binary request bodies, forms and file uploads (
UploadFile) - models: classes with aliases for names that aren’t valid Python names, constraints, defaults
and descriptions; enums;
allOfmerged into one class;oneOf/anyOfas unions, with discriminators where the document has them; nullable types of OpenAPI 3.0 and 3.1; recursive and mutually referencing models - security: API keys (header, query, cookie), HTTP basic, bearer and other HTTP schemes, OAuth2
(all flows, with scopes) and OpenID Connect, with global security, alternatives (a request needs
to meet one of the security requirements) and anonymous access (
{})
Files are generated again on every run, except the implementation package, the tests of the APIs,
tests/conftest.py and .openapi-generator-ignore, which are generated only when they don’t
exist. Files listed in .openapi-generator-ignore (which uses the syntax of .gitignore) aren’t
written. .openapi-generator/FILES lists the generated files.
Differences from openapi-generator:
- routes declare their status code and response class, e.g. 201 or 204 without a body, instead of documenting every response as 200
- the implementation is one instance of the subclass, resolved by a FastAPI dependency, instead of an instance per request; the tokens of security schemes are passed to it
- models are idiomatic pydantic 2 models:
oneOf/anyOfare unions (discriminated where possible) instead of wrapper classes, constraints usepattern=instead of the deprecatedregex=, and there are noto_dict()/from_dict()helpers - OAuth2 schemes of the same flow don’t collide, and OpenID Connect schemes are supported
- mutual TLS security schemes are reported and left out, since FastAPI can’t check them
- unknown options are errors, not ignored
- the input must be an OpenAPI 3.0, 3.1 or 3.2 document; convert Swagger 2.0 documents with
apigenie convert, and bundle documents referencing other files withapigenie bundle
Constructs that FastAPI can’t express are reported as warnings and simplified: object query
parameters (e.g. deepObject) are left out and the route receives the request instead; arrays in
headers, cookies and non-exploded query parameters are received as strings; nested objects in
forms are received as strings.
Not supported: callbacks, webhooks and response links, which the served OpenAPI document leaves
out, and x-internal, whose operations stay in it.
Extensions
| Extension | Effect |
|---|---|
x-apigenie.codegen.controller-name |
on an operation or its path item: the API module of the operation, instead of its first tag |
x-apigenie.codegen.action-name |
name of the function of an operation, instead of its operationId |
x-apigenie.codegen.disabled |
true on an operation or its path item leaves the operation out, with skipDisabled |
x-codegen-request-body-name |
on an operation or its request body: the name of the body parameter |
x-defaultMapping |
defaultMapping of a discriminator in OpenAPI 3.0 and 3.1 documents: the schema of the values whose discriminator value isn’t mapped |
The extensions can live in an overlay for this target instead of in the document, e.g.
fastapi.overlay.yaml:
overlay: 1.0.0
info:
title: FastAPI names
version: 1.0.0
actions:
- target: $.paths['/pets'].post
update:
x-codegen-request-body-name: pet
x-apigenie:
codegen:
action-name: add_pet
apigenie-generator server fastapi openapi.yaml --overlay fastapi.overlay.yaml -o out
Options
-c, –config
Path to the configuration file to use. See the “Configuration” section for more information.
–overlay OVERLAY
Path to an OpenAPI Overlay (1.0 to 1.2) applied to the input before generating, e.g. one setting the
extensions of the “Extensions” section. Can be repeated: the overlays apply in order, after those
listed under commands.generate.server_fastapi.overlay in the configuration file (with paths
relative to it). Warnings and errors about a value an overlay set point to the overlay.
–strict
Makes an overlay action whose target selects nothing an error (exit status 2, nothing is generated)
instead of a warning (OVERLAY:LINE:COL: action #N (TARGET) selects no nodes.).
-o, –output
Directory where the project is generated.
–package-name
Python package of the generated code (packageName), e.g. pet_store or acme.pet_store.
Defaults to openapi_server.
–package-version
Version of the generated project (packageVersion). Defaults to the version of the API when pip
accepts it, otherwise to 1.0.0.
-p, –property NAME=VALUE
Sets a generator option (see below), e.g. -p serverPort=8000. Options given on the command line
take precedence over the configuration file. Mapping options take comma-separated lists, e.g.
-p 'nameMappings=_links=links,$type=kind'.
Configuration
Options can also be set in the configuration file, either directly or in an
additionalProperties section, like in configuration files of openapi-generator:
version: '1.0'
commands:
generate:
server_fastapi:
packageName: pet_store
serverPort: 8000
nameMappings:
_links: links
| Option | Description |
|---|---|
packageName |
Python package of the generated code (default openapi_server) |
packageVersion |
Version of the project (defaults to the version of the API when pip accepts it, otherwise 1.0.0) |
serverPort |
Port the server listens to (defaults to the port of the first server, or 8080) |
sourceFolder |
Directory of the package, relative to the output directory (default src) |
fastapiImplementationPackage |
Package of the implementation of the APIs (default impl), inside the generated package unless useExternalImplementationPackage is set |
useExternalImplementationPackage |
The implementation package is outside the generated package and isn’t generated (default false) |
generateTests |
Generate tests (tests/) (default true) |
generateDocker |
Generate a Dockerfile and docker-compose.yaml (default true) |
generatorVersion |
Version of the generator written into generated files |
sortParamsByRequiredFlag |
Put required parameters before optional ones (default true) |
skipDeprecated |
Don’t generate code for deprecated operations (default false) |
skipDisabled |
Don’t generate code for operations disabled with x-apigenie (default false) |
modelsLayout |
Where models are written: modules (a module per model, the default) or single (one module) |
disallowAdditionalPropertiesIfNotPresent |
Models of schemas without additionalProperties reject unknown properties (extra=“forbid”) (default false) |
hideGenerationTimestamp |
Accepted for compatibility with openapi-generator; generated files have no timestamps |
modelNamePrefix |
Prefix of model names |
modelNameSuffix |
Suffix of model names |
modelNameMappings |
Mappings of schema names to model names (Schema=Model,…) |
nameMappings |
Mappings of property names to field names (name=field_name,…) |
parameterNameMappings |
Mappings of parameter names to Python names (name=python_name,…) |
enumNameMappings |
Mappings of enum values to member names (value=NAME,…) |