Skip to main content

OpenAPI (v3) specification schema as pydantic class

Project description

openapi-schema-pydantic

PyPI PyPI - License

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.0.3",
  "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:

  1. Use PydanticSchema objects to represent the Schema in OpenAPI object
  2. Invoke construct_open_api_with_schema_class to 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.0.3",
  "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()

When using OpenAPI.json() 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.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.0.3 here

License

MIT License

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

openapi-schema-pydantic-0.2.0.tar.gz (28.0 kB view details)

Uploaded Source

Built Distribution

openapi_schema_pydantic-0.2.0-py3-none-any.whl (41.6 kB view details)

Uploaded Python 3

File details

Details for the file openapi-schema-pydantic-0.2.0.tar.gz.

File metadata

  • Download URL: openapi-schema-pydantic-0.2.0.tar.gz
  • Upload date:
  • Size: 28.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.23.0 setuptools/46.3.0 requests-toolbelt/0.9.1 tqdm/4.46.0 CPython/3.8.1

File hashes

Hashes for openapi-schema-pydantic-0.2.0.tar.gz
Algorithm Hash digest
SHA256 3fc1120e54832de2d917686ea859ac40acbd3c73f5b3e97a697ee727e4f66efe
MD5 cf0ce26dd3c681b21d039dbd8c864857
BLAKE2b-256 9f556f47285039c5752202764c7fb4b8b468c3288746e3064adc86c0e09b1926

See more details on using hashes here.

File details

Details for the file openapi_schema_pydantic-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: openapi_schema_pydantic-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 41.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.23.0 setuptools/46.3.0 requests-toolbelt/0.9.1 tqdm/4.46.0 CPython/3.8.1

File hashes

Hashes for openapi_schema_pydantic-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 81489a50bd268d361dcc537728fe3c6c845ff21c09c8f19b365ba1892c05a4be
MD5 13cc53473b571f7fd677dad8d95a95f1
BLAKE2b-256 f02e3b6b5da9c308683214a37a5a0d5e020274daedf3153b326b0a80ef10e51b

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page