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() / 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.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-1.1.0.tar.gz (27.9 kB view details)

Uploaded Source

Built Distribution

openapi_schema_pydantic-1.1.0-py3-none-any.whl (41.7 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: openapi-schema-pydantic-1.1.0.tar.gz
  • Upload date:
  • Size: 27.9 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-1.1.0.tar.gz
Algorithm Hash digest
SHA256 c036bf6d2f02854372b2b7b3ba7cbeec3ccca115822b148916a616b2d9541447
MD5 28ed10abf7bcbc17f92b654615f3dabc
BLAKE2b-256 3f73dcd975dfad51c3dfb134638fca9ede31bdf27a8bbb9b9f7e7ac320f16fba

See more details on using hashes here.

File details

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

File metadata

  • Download URL: openapi_schema_pydantic-1.1.0-py3-none-any.whl
  • Upload date:
  • Size: 41.7 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-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 42c857c5138ff4c04a15f59e4e40bef280afb5994002be023df07707e8465098
MD5 f9c507430226b962bb77b58e1fbb51b2
BLAKE2b-256 b002a91dd72050048ebc5ef8b28a3269b3b7d66ddce3702183af260455b602ca

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