openapi specification parser based on pydantic
Project description
Openapydantic
openapi specification validator based on pydantic.
Python version support
3.8+
Openapi versions support
- ❌ 2.0
- 🟠 3.0.0
- 🟠 3.0.1
- ✅ 3.0.2
- ❌ 3.0.3
- ❌ 3.1.0
Openapi versions are retrocompatibles (except for major version).
So 3.0.2 specification should be able to handle 3.0.0 and 3.0.1 data.
Unit tests handle this case (3.0.2 object automatically try to load previous version fixtures).
Installation
Depending on your preference...
pip install openapydantic
...or...
poetry add openapydantic
Basic usage
Api loader
Openapydantic provide an openapi specification (a.k.a "swagger file") loader.
This loader returns a pydantic model so you can work with your specification like a common pydantic python object.
For each openapi specification version, there's a dedicated python class.
The loader can either automatically determine the class to provide...
import asyncio
import openapydantic
api = asyncio.run(
openapydantic.load_api(
file_path="openapi-spec.yaml",
),
)
print(api.info)
# if my openapi version is "3.0.2", 'api' is an instance of OpenApi302
# if the version is not implemented, it will crash
... or you can also specify a specific version.
It may be useful for backward compatibility (for eg: create an OpenApi302 object using data from an 3.0.1 openapi specfication ).
import asyncio
import openapydantic
OpenApiVersion = openapydantic.OpenApiVersion
api = asyncio.run(
openapydantic.load_api(
file_path="openapi-spec-3-0-1.yaml",
version=OpenApiVersion.v3_0_2
),
)
# Here ,'api' is an OpenApi302 object, event if you send an 3.0.1 spec.
print(api.openapi)
>> 3.0.1 # version in the spec file
print(api.__version__)
>> 3.0.2 # openapi version supported for the object class
Reference interpolation
Openapydantic will interpolate openapi references.
If your api looks like this:
# my-api.yaml
openapi: 3.0.2
info:
version: "1.0.0"
title: Example
paths:
/user:
get:
summary: Get user
responses:
"200":
description: successful operation
content:
application/json:
schema:
$ref: "#/components/schemas/User"
components:
schemas:
User:
type: object
properties:
id:
type: integer
format: int64
name:
type: string
example: "John Doe"
Once loaded, it will be usable like if it was ...
openapi: 3.0.2
info:
version: "1.0.0"
title: Example
paths:
/user:
get:
summary: Get user
responses:
"200":
description: successful operation
content:
application/json:
schema:
type: object
properties:
id:
type: integer
format: int64
name:
type: string
example: "John Doe"
And so you will be able to do things like...
import asyncio
import openapydantic
api = asyncio.run(
openapydantic.load_api(
file_path="my-api.yaml",
),
)
print(api.info)
print(
api.paths["/user"]
.get.responses["200"]
.content["application/json"]
.schema_.properties["name"]
.example
)
>> John Doe
As describe in the openapi specification some attributes are fix ('paths', 'content' etc...) and some can be mapping with a free key.
Mapping must be accessed like common dict, either by direct key loading, either using .get('key')
Note that file reference (e.g: "#/file.yaml" are currently not supported)
Reference that reference themself will not be interpolated so ...
# my-api.yaml
openapi: 3.0.2
info:
version: "1.0.0"
title: Example
paths:
/user:
get:
summary: Get user
responses:
"200":
description: successful operation
content:
application/json:
schema:
$ref: "#/components/schemas/User"
components:
schemas:
User:
type: object
properties:
id:
type: integer
format: int64
name:
type: string
example: "John Doe"
brother:
$ref: "#/components/schemas/User"
.. will stay the same ...
import asyncio
import openapydantic
api = asyncio.run(
openapydantic.load_api(
file_path="my-api.yaml",
),
)
print(api.components.schemas["User"].properties["brother"].ref)
>> '#/components/schemas/User'
Attributes name collision
Openapi specify some attribute which name are already reserved either by pydantic,either by the python language itself.
To access these attributes, you must use the Openapydantic specific name
Attribute name | Openapydantic specific name |
---|---|
schema | schema_ |
in | in_ |
not | not_ |
e.g:
print(
api.paths["/user"]
.get.responses["200"]
.content["application/json"]
.schema_
)
Model export
You can access the original api you provided as a dict using the raw_api attribute.
import asyncio
import openapydantic
api = asyncio.run(
openapydantic.load_api(
file_path="my-api.yaml",
),
)
print(api.raw_api)
>> {'openapi': '3.0.2', 'info': {'version': '1.0.0', 'title': 'Example'}, 'paths': {'/user': {'get': {'summary': 'Get user', 'responses': {'200': {'description': 'successful operation', 'content': {'application/json': {'schema': {'$ref': '#/components/schemas/User'}}}}}}}}, 'components': {'schemas': {'User': {'type': 'object', 'properties': {'id': {'type': 'integer', 'format': 'int64'}, 'name': {'type': 'string', 'example': 'John Doe'}}}}}}
You can export your data as json string or as python dict using specific methods:
import asyncio
import openapydantic
api = asyncio.run(
openapydantic.load_api(
file_path="my-api.yaml",
),
)
print(api.as_clean_json())
>> {"openapi": "3.0.2", "info": {"title": "Example", "version": "1.0.0"}, "paths": {"/user": {"get": {"summary": "Get user", "responses": {"200": {"description": "successful operation", "content": {"application/json": {"schema": {"type": "object", "properties": {"id": {"type": "integer", "format": "int64"}, "name": {"type": "string", "example": "John Doe"}}}}}}}}}}}
print(api.as_clean_dict())
> {'openapi': <OpenApiVersion.v3_0_2: '3.0.2'>, 'info': {'title': 'Example', 'version': '1.0.0'}, 'paths': {'/user': {'get': {'summary': 'Get user', 'responses': {'200': {'description': 'successful operation', 'content': {'application/json': {'schema': {'type': <JsonType.object_: 'object'>, 'properties': {'id': {'type': <JsonType.integer: 'integer'>, 'format': 'int64'}, 'name': {'type': <JsonType.string: 'string'>, 'example': 'John Doe'}}}}}}}}}}}
Note that these functions are just wrapper to .dict() and .json() pydantic model with specific parameters.
By default, since the references are interpolated, the components root key is exclude.
If you want to have it in the output, you can set the exclude_components parameter to False.
import asyncio
import openapydantic
api = asyncio.run(
openapydantic.load_api(
file_path="my-api.yaml",
),
)
print(
api.as_clean_json(
exclude_components=False,
),
)
>> {"components": {"schemas": {"User": {"type": "object", "properties": {"id": {"type": "integer", "format": "int64"}, "name": {"type": "string", "example": "John Doe"}}}}}, "openapi": "3.0.2", "info": {"title": "Example", "version": "1.0.0"}, "paths": {"/user": {"get": {"summary": "Get user", "responses": {"200": {"description": "successful operation", "content": {"application/json": {"schema": {"type": "object", "properties": {"id": {"type": "integer", "format": "int64"}, "name": {"type": "string", "example": "John Doe"}}}}}}}}}}, "raw_api": {"openapi": "3.0.2", "info": {"version": "1.0.0", "title": "Example"}, "paths": {"/user": {"get": {"summary": "Get user", "responses": {"200": {"description": "successful operation", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/User"}}}}}}}}, "components": {"schemas": {"User": {"type": "object", "properties": {"id": {"type": "integer", "format": "int64"}, "name": {"type": "string", "example": "John Doe"}}}}}}}
In the same way,the raw_api attribute is exclude by default.
If you want to have it in the output, you can set the exclude_raw_api parameter to False.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file openapydantic-0.2.3.tar.gz
.
File metadata
- Download URL: openapydantic-0.2.3.tar.gz
- Upload date:
- Size: 12.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.1.13 CPython/3.8.10 Linux/5.10.76-linuxkit
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 89f8b3a79f413e8314573631af2ba761fa69eff5101a1e004491983a09e3006c |
|
MD5 | 7aec4e8f313ff485c023f23d575d1a5b |
|
BLAKE2b-256 | 6d45d4bdb125158ec5a9ac26d56bded1e785ba21a5070c3268e5f861757b65a9 |
File details
Details for the file openapydantic-0.2.3-py3-none-any.whl
.
File metadata
- Download URL: openapydantic-0.2.3-py3-none-any.whl
- Upload date:
- Size: 11.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.1.13 CPython/3.8.10 Linux/5.10.76-linuxkit
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 0f9d622b658125af142328d65b99ecc4fddbc7f13faf4b2a6493b4f54c4b3e2b |
|
MD5 | 12ba3e5eea54dc1fbe92e8e17d722e1b |
|
BLAKE2b-256 | 7651f691965eaae71269c9e9352d4a9dd01b81b75cca4afdf98d8ba936941fb3 |