openapi-pydantic


Nameopenapi-pydantic JSON
Version 0.5.0 PyPI version JSON
download
home_pagehttps://github.com/mike-oakley/openapi-pydantic
SummaryPydantic OpenAPI schema implementation
upload_time2024-11-04 22:50:45
maintainerNone
docs_urlNone
authorMike Oakley
requires_python<4.0,>=3.8
licenseMIT
keywords openapi schema parser pydantic validation
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # openapi-pydantic

[![PyPI](https://img.shields.io/pypi/v/openapi-pydantic)](https://pypi.org/project/openapi-pydantic/)
[![PyPI - License](https://img.shields.io/pypi/l/openapi-pydantic)](https://github.com/mike-oakley/openapi-pydantic/blob/main/LICENSE)

OpenAPI schema implemented in [Pydantic](https://github.com/samuelcolvin/pydantic). Both Pydantic 1.8+ and 2.x are supported.

The naming of the classes follows the schema in 
[OpenAPI specification](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.1.md#schema).

> This library is forked from [OpenAPI Schema Pydantic](https://github.com/kuimono/openapi-schema-pydantic)  (at version [1.2.4](https://github.com/kuimono/openapi-schema-pydantic/releases/tag/v1.2.4)) which is no longer actively maintained.

## Installation

`pip install openapi-pydantic`

## Try me

```python
from openapi_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"
                    )
                }
            )
        )
    },
)
# Note: for Pydantic 1.x, replace `model_dump_json` with `json`
print(open_api.model_dump_json(by_alias=True, exclude_none=True, indent=2))
```

Result:

```json
{
  "openapi": "3.1.1",
  "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. It allows you to use object / dict / mixed data for input.

The following examples give the same OpenAPI result as above:

```python
from openapi_pydantic import parse_obj, OpenAPI, PathItem, Response

# Construct OpenAPI from dict, inferring the correct schema version
open_api = parse_obj({
    "openapi": "3.1.1",
    "info": {"title": "My own API", "version": "v0.0.1"},
    "paths": {
        "/ping": {
            "get": {"responses": {"200": {"description": "pong"}}}
        }
    },
})


# Construct OpenAPI v3.1 schema from dict
# Note: for Pydantic 1.x, replace `model_validate` with `parse_obj`
open_api = OpenAPI.model_validate({
    "info": {"title": "My own API", "version": "v0.0.1"},
    "paths": {
        "/ping": {
            "get": {"responses": {"200": {"description": "pong"}}}
        }
    },
})

# Construct OpenAPI with mix of dict/object
# Note: for Pydantic 1.x, replace `model_validate` with `parse_obj`
open_api = OpenAPI.model_validate({
    "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](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.4.md#schemaObject)
  in OpenAPI has definitions and tweaks in JSON Schema, which are hard to comprehend and define a good data class
- Pydantic already has a good way to [create JSON schema](https://pydantic-docs.helpmanual.io/usage/schema/).
  Let's not reinvent 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

```python
from pydantic import BaseModel, Field

from openapi_pydantic import OpenAPI
from openapi_pydantic.util import PydanticSchema, construct_open_api_with_schema_class

def construct_base_open_api() -> OpenAPI:
    # Note: for Pydantic 1.x, replace `model_validate` with `parse_obj`
    return OpenAPI.model_validate({
        "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
# Note: for Pydantic 1.x, replace `model_dump_json` with `json`
print(open_api.model_dump_json(by_alias=True, exclude_none=True, indent=2))
```

Result:

```json
{
  "openapi": "3.1.1",
  "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.model_dump() / OpenAPI.model_dump_json() / OpenAPI.json() / OpenAPI.dict()

When using `OpenAPI.model_dump()` / `OpenAPI.model_dump_json()` / `OpenAPI.json()` / `OpenAPI.dict()` functions,
the arguments `by_alias=True, exclude_none=True` have to be in place.
Otherwise the resulting json will not fit the OpenAPI standard.

```python
# OK (Pydantic 2)
open_api.model_dump_json(by_alias=True, exclude_none=True, indent=2)
# OK (Pydantic 1)
open_api.json(by_alias=True, exclude_none=True, indent=2)

# Not good
open_api.model_dump_json(indent=2)
open_api.json(indent=2)
```

More info about field aliases:

| OpenAPI version | Field alias info |
| --------------- | ---------------- |
| 3.1 | [here](https://github.com/mike-oakley/openapi-pydantic/blob/main/openapi_pydantic/v3/v3_1/README.md#alias) |
| 3.0 | [here](https://github.com/mike-oakley/openapi-pydantic/blob/main/openapi_pydantic/v3/v3_0/README.md#alias) |

### 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 | [here](https://github.com/mike-oakley/openapi-pydantic/blob/main/openapi_pydantic/v3/v3_1/README.md#non-pydantic-schema-types) |
| 3.0 | [here](https://github.com/mike-oakley/openapi-pydantic/blob/main/openapi_pydantic/v3/v3_0/README.md#non-pydantic-schema-types) |

### Use OpenAPI 3.0 instead of 3.1

Some UI renderings (e.g. Swagger) still do not support OpenAPI 3.1.x.
The old 3.0.x version is available by importing from different paths:

```python
from openapi_pydantic.v3.v3_0 import OpenAPI, ...
from openapi_pydantic.v3.v3_0.util import PydanticSchema, construct_open_api_with_schema_class
```

### Pydantic version compatibility

Compatibility with both major versions of Pydantic (1.8+ and 2.*) is mostly achieved using a module called `compat.py`. It detects the installed version of Pydantic and exports version-specific symbols for use by the rest of the package. It also provides all symbols necessary for type checking. The `compat.py` module is not intended to be imported by other packages, but other packages may find it helpful as an example of how to span major versions of Pydantic.

## Credits

This library is based from the original implementation by Kuimono of [OpenAPI Schema Pydantic](https://github.com/kuimono/openapi-schema-pydantic) which is no longer actively maintained.

## License

[MIT License](https://github.com/mike-oakley/openapi-pydantic/blob/main/LICENSE)


            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/mike-oakley/openapi-pydantic",
    "name": "openapi-pydantic",
    "maintainer": null,
    "docs_url": null,
    "requires_python": "<4.0,>=3.8",
    "maintainer_email": null,
    "keywords": "openapi, schema, parser, pydantic, validation",
    "author": "Mike Oakley",
    "author_email": "mike-oakley@users.noreply.github.com",
    "download_url": "https://files.pythonhosted.org/packages/24/83/c6dd05cd518e1217b2096d04f959d7868396a3a99faf9669d14007668c38/openapi_pydantic-0.5.0.tar.gz",
    "platform": null,
    "description": "# openapi-pydantic\n\n[![PyPI](https://img.shields.io/pypi/v/openapi-pydantic)](https://pypi.org/project/openapi-pydantic/)\n[![PyPI - License](https://img.shields.io/pypi/l/openapi-pydantic)](https://github.com/mike-oakley/openapi-pydantic/blob/main/LICENSE)\n\nOpenAPI schema implemented in [Pydantic](https://github.com/samuelcolvin/pydantic). Both Pydantic 1.8+ and 2.x are supported.\n\nThe naming of the classes follows the schema in \n[OpenAPI specification](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.1.md#schema).\n\n> This library is forked from [OpenAPI Schema Pydantic](https://github.com/kuimono/openapi-schema-pydantic)  (at version [1.2.4](https://github.com/kuimono/openapi-schema-pydantic/releases/tag/v1.2.4)) which is no longer actively maintained.\n\n## Installation\n\n`pip install openapi-pydantic`\n\n## Try me\n\n```python\nfrom openapi_pydantic import OpenAPI, Info, PathItem, Operation, Response\n\n# Construct OpenAPI by pydantic objects\nopen_api = OpenAPI(\n    info=Info(\n        title=\"My own API\",\n        version=\"v0.0.1\",\n    ),\n    paths={\n        \"/ping\": PathItem(\n            get=Operation(\n                responses={\n                    \"200\": Response(\n                        description=\"pong\"\n                    )\n                }\n            )\n        )\n    },\n)\n# Note: for Pydantic 1.x, replace `model_dump_json` with `json`\nprint(open_api.model_dump_json(by_alias=True, exclude_none=True, indent=2))\n```\n\nResult:\n\n```json\n{\n  \"openapi\": \"3.1.1\",\n  \"info\": {\n    \"title\": \"My own API\",\n    \"version\": \"v0.0.1\"\n  },\n  \"servers\": [\n    {\n      \"url\": \"/\"\n    }\n  ],\n  \"paths\": {\n    \"/ping\": {\n      \"get\": {\n        \"responses\": {\n          \"200\": {\n            \"description\": \"pong\"\n          }\n        },\n        \"deprecated\": false\n      }\n    }\n  }\n}\n```\n\n## Take advantage of Pydantic\n\nPydantic is a great tool. It allows you to use object / dict / mixed data for input.\n\nThe following examples give the same OpenAPI result as above:\n\n```python\nfrom openapi_pydantic import parse_obj, OpenAPI, PathItem, Response\n\n# Construct OpenAPI from dict, inferring the correct schema version\nopen_api = parse_obj({\n    \"openapi\": \"3.1.1\",\n    \"info\": {\"title\": \"My own API\", \"version\": \"v0.0.1\"},\n    \"paths\": {\n        \"/ping\": {\n            \"get\": {\"responses\": {\"200\": {\"description\": \"pong\"}}}\n        }\n    },\n})\n\n\n# Construct OpenAPI v3.1 schema from dict\n# Note: for Pydantic 1.x, replace `model_validate` with `parse_obj`\nopen_api = OpenAPI.model_validate({\n    \"info\": {\"title\": \"My own API\", \"version\": \"v0.0.1\"},\n    \"paths\": {\n        \"/ping\": {\n            \"get\": {\"responses\": {\"200\": {\"description\": \"pong\"}}}\n        }\n    },\n})\n\n# Construct OpenAPI with mix of dict/object\n# Note: for Pydantic 1.x, replace `model_validate` with `parse_obj`\nopen_api = OpenAPI.model_validate({\n    \"info\": {\"title\": \"My own API\", \"version\": \"v0.0.1\"},\n    \"paths\": {\n        \"/ping\": PathItem(\n            get={\"responses\": {\"200\": Response(description=\"pong\")}}\n        )\n    },\n})\n```\n\n## Use Pydantic classes as schema\n\n- The [Schema Object](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.4.md#schemaObject)\n  in OpenAPI has definitions and tweaks in JSON Schema, which are hard to comprehend and define a good data class\n- Pydantic already has a good way to [create JSON schema](https://pydantic-docs.helpmanual.io/usage/schema/).\n  Let's not reinvent the wheel.\n\nThe approach to deal with this:\n\n1. Use `PydanticSchema` objects to represent the `Schema` in `OpenAPI` object\n2. Invoke `construct_open_api_with_schema_class` to resolve the JSON schemas and references\n\n```python\nfrom pydantic import BaseModel, Field\n\nfrom openapi_pydantic import OpenAPI\nfrom openapi_pydantic.util import PydanticSchema, construct_open_api_with_schema_class\n\ndef construct_base_open_api() -> OpenAPI:\n    # Note: for Pydantic 1.x, replace `model_validate` with `parse_obj`\n    return OpenAPI.model_validate({\n        \"info\": {\"title\": \"My own API\", \"version\": \"v0.0.1\"},\n        \"paths\": {\n            \"/ping\": {\n                \"post\": {\n                    \"requestBody\": {\"content\": {\"application/json\": {\n                        \"schema\": PydanticSchema(schema_class=PingRequest)\n                    }}},\n                    \"responses\": {\"200\": {\n                        \"description\": \"pong\",\n                        \"content\": {\"application/json\": {\n                            \"schema\": PydanticSchema(schema_class=PingResponse)\n                        }},\n                    }},\n                }\n            }\n        },\n    })\n\nclass PingRequest(BaseModel):\n    \"\"\"Ping Request\"\"\"\n    req_foo: str = Field(description=\"foo value of the request\")\n    req_bar: str = Field(description=\"bar value of the request\")\n\nclass PingResponse(BaseModel):\n    \"\"\"Ping response\"\"\"\n    resp_foo: str = Field(description=\"foo value of the response\")\n    resp_bar: str = Field(description=\"bar value of the response\")\n\nopen_api = construct_base_open_api()\nopen_api = construct_open_api_with_schema_class(open_api)\n\n# print the result openapi.json\n# Note: for Pydantic 1.x, replace `model_dump_json` with `json`\nprint(open_api.model_dump_json(by_alias=True, exclude_none=True, indent=2))\n```\n\nResult:\n\n```json\n{\n  \"openapi\": \"3.1.1\",\n  \"info\": {\n    \"title\": \"My own API\",\n    \"version\": \"v0.0.1\"\n  },\n  \"servers\": [\n    {\n      \"url\": \"/\"\n    }\n  ],\n  \"paths\": {\n    \"/ping\": {\n      \"post\": {\n        \"requestBody\": {\n          \"content\": {\n            \"application/json\": {\n              \"schema\": {\n                \"$ref\": \"#/components/schemas/PingRequest\"\n              }\n            }\n          },\n          \"required\": false\n        },\n        \"responses\": {\n          \"200\": {\n            \"description\": \"pong\",\n            \"content\": {\n              \"application/json\": {\n                \"schema\": {\n                  \"$ref\": \"#/components/schemas/PingResponse\"\n                }\n              }\n            }\n          }\n        },\n        \"deprecated\": false\n      }\n    }\n  },\n  \"components\": {\n    \"schemas\": {\n      \"PingRequest\": {\n        \"title\": \"PingRequest\",\n        \"required\": [\n          \"req_foo\",\n          \"req_bar\"\n        ],\n        \"type\": \"object\",\n        \"properties\": {\n          \"req_foo\": {\n            \"title\": \"Req Foo\",\n            \"type\": \"string\",\n            \"description\": \"foo value of the request\"\n          },\n          \"req_bar\": {\n            \"title\": \"Req Bar\",\n            \"type\": \"string\",\n            \"description\": \"bar value of the request\"\n          }\n        },\n        \"description\": \"Ping Request\"\n      },\n      \"PingResponse\": {\n        \"title\": \"PingResponse\",\n        \"required\": [\n          \"resp_foo\",\n          \"resp_bar\"\n        ],\n        \"type\": \"object\",\n        \"properties\": {\n          \"resp_foo\": {\n            \"title\": \"Resp Foo\",\n            \"type\": \"string\",\n            \"description\": \"foo value of the response\"\n          },\n          \"resp_bar\": {\n            \"title\": \"Resp Bar\",\n            \"type\": \"string\",\n            \"description\": \"bar value of the response\"\n          }\n        },\n        \"description\": \"Ping response\"\n      }\n    }\n  }\n}\n```\n\n## Notes\n\n### Use of OpenAPI.model_dump() / OpenAPI.model_dump_json() / OpenAPI.json() / OpenAPI.dict()\n\nWhen using `OpenAPI.model_dump()` / `OpenAPI.model_dump_json()` / `OpenAPI.json()` / `OpenAPI.dict()` functions,\nthe arguments `by_alias=True, exclude_none=True` have to be in place.\nOtherwise the resulting json will not fit the OpenAPI standard.\n\n```python\n# OK (Pydantic 2)\nopen_api.model_dump_json(by_alias=True, exclude_none=True, indent=2)\n# OK (Pydantic 1)\nopen_api.json(by_alias=True, exclude_none=True, indent=2)\n\n# Not good\nopen_api.model_dump_json(indent=2)\nopen_api.json(indent=2)\n```\n\nMore info about field aliases:\n\n| OpenAPI version | Field alias info |\n| --------------- | ---------------- |\n| 3.1 | [here](https://github.com/mike-oakley/openapi-pydantic/blob/main/openapi_pydantic/v3/v3_1/README.md#alias) |\n| 3.0 | [here](https://github.com/mike-oakley/openapi-pydantic/blob/main/openapi_pydantic/v3/v3_0/README.md#alias) |\n\n### Non-pydantic schema types\n\nSome schema types are not implemented as pydantic classes.\nPlease refer to the following for more info:\n\n| OpenAPI version | Non-pydantic schema type info |\n| --------------- | ----------------------------- |\n| 3.1 | [here](https://github.com/mike-oakley/openapi-pydantic/blob/main/openapi_pydantic/v3/v3_1/README.md#non-pydantic-schema-types) |\n| 3.0 | [here](https://github.com/mike-oakley/openapi-pydantic/blob/main/openapi_pydantic/v3/v3_0/README.md#non-pydantic-schema-types) |\n\n### Use OpenAPI 3.0 instead of 3.1\n\nSome UI renderings (e.g. Swagger) still do not support OpenAPI 3.1.x.\nThe old 3.0.x version is available by importing from different paths:\n\n```python\nfrom openapi_pydantic.v3.v3_0 import OpenAPI, ...\nfrom openapi_pydantic.v3.v3_0.util import PydanticSchema, construct_open_api_with_schema_class\n```\n\n### Pydantic version compatibility\n\nCompatibility with both major versions of Pydantic (1.8+ and 2.*) is mostly achieved using a module called `compat.py`. It detects the installed version of Pydantic and exports version-specific symbols for use by the rest of the package. It also provides all symbols necessary for type checking. The `compat.py` module is not intended to be imported by other packages, but other packages may find it helpful as an example of how to span major versions of Pydantic.\n\n## Credits\n\nThis library is based from the original implementation by Kuimono of [OpenAPI Schema Pydantic](https://github.com/kuimono/openapi-schema-pydantic) which is no longer actively maintained.\n\n## License\n\n[MIT License](https://github.com/mike-oakley/openapi-pydantic/blob/main/LICENSE)\n\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Pydantic OpenAPI schema implementation",
    "version": "0.5.0",
    "project_urls": {
        "Homepage": "https://github.com/mike-oakley/openapi-pydantic",
        "Repository": "https://github.com/mike-oakley/openapi-pydantic",
        "changelog": "https://github.com/mike-oakley/openapi-pydantic/releases"
    },
    "split_keywords": [
        "openapi",
        " schema",
        " parser",
        " pydantic",
        " validation"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "8b8187f16c4bf2e73ea337b5bb1e074e3ddbdf3e5aabaaf3f8551aad6a9ac9fa",
                "md5": "6e86bedf12a67372be5a693afbc729c6",
                "sha256": "06458efd34969446f42d96d51de39cdef4a9b19daf3cc456a2dfa697458ac542"
            },
            "downloads": -1,
            "filename": "openapi_pydantic-0.5.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "6e86bedf12a67372be5a693afbc729c6",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": "<4.0,>=3.8",
            "size": 95858,
            "upload_time": "2024-11-04T22:50:44",
            "upload_time_iso_8601": "2024-11-04T22:50:44.359781Z",
            "url": "https://files.pythonhosted.org/packages/8b/81/87f16c4bf2e73ea337b5bb1e074e3ddbdf3e5aabaaf3f8551aad6a9ac9fa/openapi_pydantic-0.5.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "2483c6dd05cd518e1217b2096d04f959d7868396a3a99faf9669d14007668c38",
                "md5": "2f404beb6df1d9e22c992ef5d35e1c0e",
                "sha256": "a48f88e2904a056e1ef6d4728cfb2f36aa3213ce194fb09fc04259b9007165f0"
            },
            "downloads": -1,
            "filename": "openapi_pydantic-0.5.0.tar.gz",
            "has_sig": false,
            "md5_digest": "2f404beb6df1d9e22c992ef5d35e1c0e",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": "<4.0,>=3.8",
            "size": 60403,
            "upload_time": "2024-11-04T22:50:45",
            "upload_time_iso_8601": "2024-11-04T22:50:45.981883Z",
            "url": "https://files.pythonhosted.org/packages/24/83/c6dd05cd518e1217b2096d04f959d7868396a3a99faf9669d14007668c38/openapi_pydantic-0.5.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-11-04 22:50:45",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "mike-oakley",
    "github_project": "openapi-pydantic",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "tox": true,
    "lcname": "openapi-pydantic"
}
        
Elapsed time: 0.35538s