openapi-schema-pydantic
OpenAPI (v3) specification schema as Pydantic classes.
The naming of the classes follows the schema in OpenAPI specification.
Installation
pip install openapi-schema-pydantic
Try me
from openapi_schema_pydantic import OpenAPI, Info, PathItem, Operation, Response
# Construct OpenAPI by pydantic objects
open_api = OpenAPI(
info=Info(
title="My own API",
version="v0.0.1",
),
paths={
"/ping": PathItem(
get=Operation(
responses={
"200": Response(
description="pong"
)
}
)
)
},
)
print(open_api.json(by_alias=True, exclude_none=True, indent=2))
Result:
{
"openapi": "3.1.0",
"info": {
"title": "My own API",
"version": "v0.0.1"
},
"servers": [
{
"url": "/"
}
],
"paths": {
"/ping": {
"get": {
"responses": {
"200": {
"description": "pong"
}
},
"deprecated": false
}
}
}
}
Take advantage of Pydantic
Pydantic is a great tool, allow you to use object / dict / mixed data for for input.
The following examples give the same OpenAPI result as above:
from openapi_schema_pydantic import OpenAPI, PathItem, Response
# Construct OpenAPI from dict
open_api = OpenAPI.parse_obj({
"info": {"title": "My own API", "version": "v0.0.1"},
"paths": {
"/ping": {
"get": {"responses": {"200": {"description": "pong"}}}
}
},
})
# Construct OpenAPI with mix of dict/object
open_api = OpenAPI.parse_obj({
"info": {"title": "My own API", "version": "v0.0.1"},
"paths": {
"/ping": PathItem(
get={"responses": {"200": Response(description="pong")}}
)
},
})
Use Pydantic classes as schema
- The Schema Object in OpenAPI has definitions and tweaks in JSON Schema, which is hard to comprehend and define a good data class
- Pydantic already has a good way to create JSON schema, let's not re-invent the wheel
The approach to deal with this:
- Use
PydanticSchemaobjects to represent theSchemainOpenAPIobject - Invoke
construct_open_api_with_schema_classto resolve the JSON schemas and references
from pydantic import BaseModel, Field
from openapi_schema_pydantic import OpenAPI
from openapi_schema_pydantic.util import PydanticSchema, construct_open_api_with_schema_class
def construct_base_open_api() -> OpenAPI:
return OpenAPI.parse_obj({
"info": {"title": "My own API", "version": "v0.0.1"},
"paths": {
"/ping": {
"post": {
"requestBody": {"content": {"application/json": {
"schema": PydanticSchema(schema_class=PingRequest)
}}},
"responses": {"200": {
"description": "pong",
"content": {"application/json": {
"schema": PydanticSchema(schema_class=PingResponse)
}},
}},
}
}
},
})
class PingRequest(BaseModel):
"""Ping Request"""
req_foo: str = Field(description="foo value of the request")
req_bar: str = Field(description="bar value of the request")
class PingResponse(BaseModel):
"""Ping response"""
resp_foo: str = Field(description="foo value of the response")
resp_bar: str = Field(description="bar value of the response")
open_api = construct_base_open_api()
open_api = construct_open_api_with_schema_class(open_api)
# print the result openapi.json
print(open_api.json(by_alias=True, exclude_none=True, indent=2))
Result:
{
"openapi": "3.1.0",
"info": {
"title": "My own API",
"version": "v0.0.1"
},
"servers": [
{
"url": "/"
}
],
"paths": {
"/ping": {
"post": {
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PingRequest"
}
}
},
"required": false
},
"responses": {
"200": {
"description": "pong",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PingResponse"
}
}
}
}
},
"deprecated": false
}
}
},
"components": {
"schemas": {
"PingRequest": {
"title": "PingRequest",
"required": [
"req_foo",
"req_bar"
],
"type": "object",
"properties": {
"req_foo": {
"title": "Req Foo",
"type": "string",
"description": "foo value of the request"
},
"req_bar": {
"title": "Req Bar",
"type": "string",
"description": "bar value of the request"
}
},
"description": "Ping Request"
},
"PingResponse": {
"title": "PingResponse",
"required": [
"resp_foo",
"resp_bar"
],
"type": "object",
"properties": {
"resp_foo": {
"title": "Resp Foo",
"type": "string",
"description": "foo value of the response"
},
"resp_bar": {
"title": "Resp Bar",
"type": "string",
"description": "bar value of the response"
}
},
"description": "Ping response"
}
}
}
}
Notes
Use of OpenAPI.json() / OpenAPI.dict()
When using OpenAPI.json() / OpenAPI.dict() function,
arguments by_alias=True, exclude_none=True has to be in place.
Otherwise the result json will not fit the OpenAPI standard.
# OK
open_api.json(by_alias=True, exclude_none=True, indent=2)
# Not good
open_api.json(indent=2)
More info about field alias:
| OpenAPI version | Field alias info |
|---|---|
| 3.1.0 | here |
| 3.0.3 | here |
Non-pydantic schema types
Some schema types are not implemented as pydantic classes. Please refer to the following for more info:
| OpenAPI version | Non-pydantic schema type info |
|---|---|
| 3.1.0 | here |
| 3.0.3 | here |
License
Metadata
Release files for openapi-schema-pydantic 1.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| openapi-schema-pydantic-1.2.0.tar.gz | 49.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| openapi_schema_pydantic-1.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 131.5 kB
Release files / openapi-schema-pydantic-1.2.0.tar.gz
| Download URL | openapi-schema-pydantic-1.2.0.tar.gz |
|---|---|
| Size | 49.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
3b88e0a9219ab795e39204253320a797b73e6825124277a77e1a99ced3bd957b
|
|
BLAKE2b-256 checksum How to use checksums |
b9177ed1c229c3148b25ef1c133b5ee0ee57717b5db48cba75b22fb15398b694
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/3.4.1 importlib_metadata/4.6.0 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.61.1 CPython/3.9.5
|
Release files / openapi_schema_pydantic-1.2.0-py3-none-any.whl
| Download URL | openapi_schema_pydantic-1.2.0-py3-none-any.whl |
|---|---|
| Size | 81.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
34774e7e4b121ba1db0bc54c3c04569fda6e02afe2a13708af4ab0cb205fff05
|
|
BLAKE2b-256 checksum How to use checksums |
8fdaf08b548f8c9b682d48dbfe4b6ee78ed53cf921cff847e7ec1cb4b86a82b8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/3.4.1 importlib_metadata/4.6.0 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.61.1 CPython/3.9.5
|