diff options
author | cyfraeviolae <cyfraeviolae> | 2024-04-03 03:10:44 -0400 |
---|---|---|
committer | cyfraeviolae <cyfraeviolae> | 2024-04-03 03:10:44 -0400 |
commit | 6d7ba58f880be618ade07f8ea080fe8c4bf8a896 (patch) | |
tree | b1c931051ffcebd2bd9d61d98d6233ffa289bbce /venv/lib/python3.11/site-packages/litestar/openapi | |
parent | 4f884c9abc32990b4061a1bb6997b4b37e58ea0b (diff) |
venv
Diffstat (limited to 'venv/lib/python3.11/site-packages/litestar/openapi')
74 files changed, 3093 insertions, 0 deletions
diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/__init__.py b/venv/lib/python3.11/site-packages/litestar/openapi/__init__.py new file mode 100644 index 0000000..8cc83d3 --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/__init__.py @@ -0,0 +1,5 @@ +from .config import OpenAPIConfig +from .controller import OpenAPIController +from .datastructures import ResponseSpec + +__all__ = ("OpenAPIController", "OpenAPIConfig", "ResponseSpec") diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/__pycache__/__init__.cpython-311.pyc b/venv/lib/python3.11/site-packages/litestar/openapi/__pycache__/__init__.cpython-311.pyc Binary files differnew file mode 100644 index 0000000..510eb6f --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/__pycache__/__init__.cpython-311.pyc diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/__pycache__/config.cpython-311.pyc b/venv/lib/python3.11/site-packages/litestar/openapi/__pycache__/config.cpython-311.pyc Binary files differnew file mode 100644 index 0000000..16411a1 --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/__pycache__/config.cpython-311.pyc diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/__pycache__/controller.cpython-311.pyc b/venv/lib/python3.11/site-packages/litestar/openapi/__pycache__/controller.cpython-311.pyc Binary files differnew file mode 100644 index 0000000..f153bae --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/__pycache__/controller.cpython-311.pyc diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/__pycache__/datastructures.cpython-311.pyc b/venv/lib/python3.11/site-packages/litestar/openapi/__pycache__/datastructures.cpython-311.pyc Binary files differnew file mode 100644 index 0000000..042a57f --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/__pycache__/datastructures.cpython-311.pyc diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/config.py b/venv/lib/python3.11/site-packages/litestar/openapi/config.py new file mode 100644 index 0000000..c935693 --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/config.py @@ -0,0 +1,153 @@ +from __future__ import annotations + +from copy import deepcopy +from dataclasses import dataclass, field, fields +from typing import TYPE_CHECKING, Literal + +from litestar._openapi.utils import default_operation_id_creator +from litestar.openapi.controller import OpenAPIController +from litestar.openapi.spec import ( + Components, + Contact, + ExternalDocumentation, + Info, + License, + OpenAPI, + PathItem, + Reference, + SecurityRequirement, + Server, + Tag, +) +from litestar.utils.path import normalize_path + +__all__ = ("OpenAPIConfig",) + + +if TYPE_CHECKING: + from litestar.types.callable_types import OperationIDCreator + + +@dataclass +class OpenAPIConfig: + """Configuration for OpenAPI. + + To enable OpenAPI schema generation and serving, pass an instance of this class to the + :class:`Litestar <.app.Litestar>` constructor using the ``openapi_config`` kwargs. + """ + + title: str + """Title of API documentation.""" + version: str + """API version, e.g. '1.0.0'.""" + + create_examples: bool = field(default=False) + """Generate examples using the polyfactory library.""" + random_seed: int = 10 + """The random seed used when creating the examples to ensure deterministic generation of examples.""" + openapi_controller: type[OpenAPIController] = field(default_factory=lambda: OpenAPIController) + """Controller for generating OpenAPI routes. + + Must be subclass of :class:`OpenAPIController <litestar.openapi.controller.OpenAPIController>`. + """ + contact: Contact | None = field(default=None) + """API contact information, should be an :class:`Contact <litestar.openapi.spec.contact.Contact>` instance.""" + description: str | None = field(default=None) + """API description.""" + external_docs: ExternalDocumentation | None = field(default=None) + """Links to external documentation. + + Should be an instance of :class:`ExternalDocumentation <litestar.openapi.spec.external_documentation.ExternalDocumentation>`. + """ + license: License | None = field(default=None) + """API Licensing information. + + Should be an instance of :class:`License <litestar.openapi.spec.license.License>`. + """ + security: list[SecurityRequirement] | None = field(default=None) + """API Security requirements information. + + Should be an instance of + :data:`SecurityRequirement <.openapi.spec.SecurityRequirement>`. + """ + components: Components | list[Components] = field(default_factory=Components) + """API Components information. + + Should be an instance of :class:`Components <litestar.openapi.spec.components.Components>` or a list thereof. + """ + servers: list[Server] = field(default_factory=lambda: [Server(url="/")]) + """A list of :class:`Server <litestar.openapi.spec.server.Server>` instances.""" + summary: str | None = field(default=None) + """A summary text.""" + tags: list[Tag] | None = field(default=None) + """A list of :class:`Tag <litestar.openapi.spec.tag.Tag>` instances.""" + terms_of_service: str | None = field(default=None) + """URL to page that contains terms of service.""" + use_handler_docstrings: bool = field(default=False) + """Draw operation description from route handler docstring if not otherwise provided.""" + webhooks: dict[str, PathItem | Reference] | None = field(default=None) + """A mapping of key to either :class:`PathItem <litestar.openapi.spec.path_item.PathItem>` or. + + :class:`Reference <litestar.openapi.spec.reference.Reference>` objects. + """ + root_schema_site: Literal["redoc", "swagger", "elements", "rapidoc"] = "redoc" + """The static schema generator to use for the "root" path of `/schema/`.""" + enabled_endpoints: set[str] = field( + default_factory=lambda: { + "redoc", + "swagger", + "elements", + "rapidoc", + "openapi.json", + "openapi.yaml", + "openapi.yml", + "oauth2-redirect.html", + } + ) + """A set of the enabled documentation sites and schema download endpoints.""" + operation_id_creator: OperationIDCreator = default_operation_id_creator + """A callable that generates unique operation ids""" + path: str | None = field(default=None) + """Base path for the OpenAPI documentation endpoints.""" + + def __post_init__(self) -> None: + if self.path: + self.path = normalize_path(self.path) + self.openapi_controller = type("OpenAPIController", (self.openapi_controller,), {"path": self.path}) + + def to_openapi_schema(self) -> OpenAPI: + """Return an ``OpenAPI`` instance from the values stored in ``self``. + + Returns: + An instance of :class:`OpenAPI <litestar.openapi.spec.open_api.OpenAPI>`. + """ + + if isinstance(self.components, list): + merged_components = Components() + for components in self.components: + for key in (f.name for f in fields(components)): + if value := getattr(components, key, None): + merged_value_dict = getattr(merged_components, key, {}) or {} + merged_value_dict.update(value) + setattr(merged_components, key, merged_value_dict) + + self.components = merged_components + + return OpenAPI( + external_docs=self.external_docs, + security=self.security, + components=deepcopy(self.components), # deepcopy prevents mutation of the config's components + servers=self.servers, + tags=self.tags, + webhooks=self.webhooks, + info=Info( + title=self.title, + version=self.version, + description=self.description, + contact=self.contact, + license=self.license, + summary=self.summary, + terms_of_service=self.terms_of_service, + ), + paths={}, + ) diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/controller.py b/venv/lib/python3.11/site-packages/litestar/openapi/controller.py new file mode 100644 index 0000000..ac03d4c --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/controller.py @@ -0,0 +1,604 @@ +from __future__ import annotations + +from functools import cached_property +from typing import TYPE_CHECKING, Any, Callable, Final, Literal + +from yaml import dump as dump_yaml + +from litestar.constants import OPENAPI_NOT_INITIALIZED +from litestar.controller import Controller +from litestar.enums import MediaType, OpenAPIMediaType +from litestar.exceptions import ImproperlyConfiguredException +from litestar.handlers import get +from litestar.response.base import ASGIResponse +from litestar.serialization import encode_json +from litestar.serialization.msgspec_hooks import decode_json +from litestar.status_codes import HTTP_404_NOT_FOUND + +__all__ = ("OpenAPIController",) + + +if TYPE_CHECKING: + from litestar.connection.request import Request + from litestar.openapi.spec.open_api import OpenAPI + +_OPENAPI_JSON_ROUTER_NAME: Final = "__litestar_openapi_json" + + +class OpenAPIController(Controller): + """Controller for OpenAPI endpoints.""" + + path: str = "/schema" + """Base path for the OpenAPI documentation endpoints.""" + style: str = "body { margin: 0; padding: 0 }" + """Base styling of the html body.""" + redoc_version: str = "next" + """Redoc version to download from the CDN.""" + swagger_ui_version: str = "5.1.3" + """SwaggerUI version to download from the CDN.""" + stoplight_elements_version: str = "7.7.18" + """StopLight Elements version to download from the CDN.""" + rapidoc_version: str = "9.3.4" + """RapiDoc version to download from the CDN.""" + favicon_url: str = "" + """URL to download a favicon from.""" + redoc_google_fonts: bool = True + """Download google fonts via CDN. + + Should be set to ``False`` when not using a CDN. + """ + redoc_js_url: str = f"https://cdn.jsdelivr.net/npm/redoc@{redoc_version}/bundles/redoc.standalone.js" + """Download url for the Redoc JS bundle.""" + swagger_css_url: str = f"https://cdn.jsdelivr.net/npm/swagger-ui-dist@{swagger_ui_version}/swagger-ui.css" + """Download url for the Swagger UI CSS bundle.""" + swagger_ui_bundle_js_url: str = ( + f"https://cdn.jsdelivr.net/npm/swagger-ui-dist@{swagger_ui_version}/swagger-ui-bundle.js" + ) + """Download url for the Swagger UI JS bundle.""" + swagger_ui_standalone_preset_js_url: str = ( + f"https://cdn.jsdelivr.net/npm/swagger-ui-dist@{swagger_ui_version}/swagger-ui-standalone-preset.js" + ) + """Download url for the Swagger Standalone Preset JS bundle.""" + swagger_ui_init_oauth: dict[Any, Any] | bytes = {} + """ + JSON to initialize Swagger UI OAuth2 by calling the `initOAuth` method. + + Refer to the following URL for details: + `Swagger-UI <https://swagger.io/docs/open-source-tools/swagger-ui/usage/oauth2/>`_. + """ + stoplight_elements_css_url: str = ( + f"https://unpkg.com/@stoplight/elements@{stoplight_elements_version}/styles.min.css" + ) + """Download url for the Stoplight Elements CSS bundle.""" + stoplight_elements_js_url: str = ( + f"https://unpkg.com/@stoplight/elements@{stoplight_elements_version}/web-components.min.js" + ) + """Download url for the Stoplight Elements JS bundle.""" + rapidoc_js_url: str = f"https://unpkg.com/rapidoc@{rapidoc_version}/dist/rapidoc-min.js" + """Download url for the RapiDoc JS bundle.""" + + # internal + _dumped_json_schema: str = "" + _dumped_yaml_schema: bytes = b"" + # until swagger-ui supports v3.1.* of OpenAPI officially, we need to modify the schema for it and keep it + # separate from the redoc version of the schema, which is unmodified. + dto = None + return_dto = None + + @staticmethod + def get_schema_from_request(request: Request[Any, Any, Any]) -> OpenAPI: + """Return the OpenAPI pydantic model from the request instance. + + Args: + request: A :class:`Litestar <.connection.Request>` instance. + + Returns: + An :class:`OpenAPI <litestar.openapi.spec.open_api.OpenAPI>` instance. + """ + return request.app.openapi_schema + + def should_serve_endpoint(self, request: Request[Any, Any, Any]) -> bool: + """Verify that the requested path is within the enabled endpoints in the openapi_config. + + Args: + request: To be tested if endpoint enabled. + + Returns: + A boolean. + + Raises: + ImproperlyConfiguredException: If the application ``openapi_config`` attribute is ``None``. + """ + if not request.app.openapi_config: # pragma: no cover + raise ImproperlyConfiguredException("Litestar has not been instantiated with an OpenAPIConfig") + + asgi_root_path = set(filter(None, request.scope.get("root_path", "").split("/"))) + full_request_path = set(filter(None, request.url.path.split("/"))) + request_path = full_request_path.difference(asgi_root_path) + root_path = set(filter(None, self.path.split("/"))) + + config = request.app.openapi_config + + if request_path == root_path and config.root_schema_site in config.enabled_endpoints: + return True + + return bool(request_path & config.enabled_endpoints) + + @property + def favicon(self) -> str: + """Return favicon ``<link>`` tag, if applicable. + + Returns: + A ``<link>`` tag if ``self.favicon_url`` is not empty, otherwise returns a placeholder meta tag. + """ + return f"<link rel='icon' type='image/x-icon' href='{self.favicon_url}'>" if self.favicon_url else "<meta/>" + + @cached_property + def render_methods_map( + self, + ) -> dict[Literal["redoc", "swagger", "elements", "rapidoc"], Callable[[Request], bytes]]: + """Map render method names to render methods. + + Returns: + A mapping of string keys to render methods. + """ + return { + "redoc": self.render_redoc, + "swagger": self.render_swagger_ui, + "elements": self.render_stoplight_elements, + "rapidoc": self.render_rapidoc, + } + + @get( + path=["/openapi.yaml", "openapi.yml"], + media_type=OpenAPIMediaType.OPENAPI_YAML, + include_in_schema=False, + sync_to_thread=False, + ) + def retrieve_schema_yaml(self, request: Request[Any, Any, Any]) -> ASGIResponse: + """Return the OpenAPI schema as YAML with an ``application/vnd.oai.openapi`` Content-Type header. + + Args: + request: + A :class:`Request <.connection.Request>` instance. + + Returns: + A Response instance with the YAML object rendered into a string. + """ + if self.should_serve_endpoint(request): + if not self._dumped_json_schema: + schema_json = decode_json(self._get_schema_as_json(request)) + schema_yaml = dump_yaml(schema_json, default_flow_style=False) + self._dumped_yaml_schema = schema_yaml.encode("utf-8") + return ASGIResponse(body=self._dumped_yaml_schema, media_type=OpenAPIMediaType.OPENAPI_YAML) + return ASGIResponse(body=b"", status_code=HTTP_404_NOT_FOUND, media_type=MediaType.HTML) + + @get( + path="/openapi.json", + media_type=OpenAPIMediaType.OPENAPI_JSON, + include_in_schema=False, + sync_to_thread=False, + name=_OPENAPI_JSON_ROUTER_NAME, + ) + def retrieve_schema_json(self, request: Request[Any, Any, Any]) -> ASGIResponse: + """Return the OpenAPI schema as JSON with an ``application/vnd.oai.openapi+json`` Content-Type header. + + Args: + request: + A :class:`Request <.connection.Request>` instance. + + Returns: + A Response instance with the JSON object rendered into a string. + """ + if self.should_serve_endpoint(request): + return ASGIResponse( + body=self._get_schema_as_json(request), + media_type=OpenAPIMediaType.OPENAPI_JSON, + ) + return ASGIResponse(body=b"", status_code=HTTP_404_NOT_FOUND, media_type=MediaType.HTML) + + @get(path="/", include_in_schema=False, sync_to_thread=False) + def root(self, request: Request[Any, Any, Any]) -> ASGIResponse: + """Render a static documentation site. + + The site to be rendered is based on the ``root_schema_site`` value set in the application's + :class:`OpenAPIConfig <.openapi.OpenAPIConfig>`. Defaults to ``redoc``. + + Args: + request: + A :class:`Request <.connection.Request>` instance. + + Returns: + A response with the rendered site defined in root_schema_site. + + Raises: + ImproperlyConfiguredException: If the application ``openapi_config`` attribute is ``None``. + """ + config = request.app.openapi_config + if not config: # pragma: no cover + raise ImproperlyConfiguredException(OPENAPI_NOT_INITIALIZED) + + render_method = self.render_methods_map[config.root_schema_site] + + if self.should_serve_endpoint(request): + return ASGIResponse(body=render_method(request), media_type=MediaType.HTML) + return ASGIResponse(body=self.render_404_page(), status_code=HTTP_404_NOT_FOUND, media_type=MediaType.HTML) + + @get(path="/swagger", include_in_schema=False, sync_to_thread=False) + def swagger_ui(self, request: Request[Any, Any, Any]) -> ASGIResponse: + """Route handler responsible for rendering Swagger-UI. + + Args: + request: + A :class:`Request <.connection.Request>` instance. + + Returns: + A response with a rendered swagger documentation site + """ + if self.should_serve_endpoint(request): + return ASGIResponse(body=self.render_swagger_ui(request), media_type=MediaType.HTML) + return ASGIResponse(body=self.render_404_page(), status_code=HTTP_404_NOT_FOUND, media_type=MediaType.HTML) + + @get(path="/elements", media_type=MediaType.HTML, include_in_schema=False, sync_to_thread=False) + def stoplight_elements(self, request: Request[Any, Any, Any]) -> ASGIResponse: + """Route handler responsible for rendering StopLight Elements. + + Args: + request: + A :class:`Request <.connection.Request>` instance. + + Returns: + A response with a rendered stoplight elements documentation site + """ + if self.should_serve_endpoint(request): + return ASGIResponse(body=self.render_stoplight_elements(request), media_type=MediaType.HTML) + return ASGIResponse(body=self.render_404_page(), status_code=HTTP_404_NOT_FOUND, media_type=MediaType.HTML) + + @get(path="/redoc", media_type=MediaType.HTML, include_in_schema=False, sync_to_thread=False) + def redoc(self, request: Request[Any, Any, Any]) -> ASGIResponse: # pragma: no cover + """Route handler responsible for rendering Redoc. + + Args: + request: + A :class:`Request <.connection.Request>` instance. + + Returns: + A response with a rendered redoc documentation site + """ + if self.should_serve_endpoint(request): + return ASGIResponse(body=self.render_redoc(request), media_type=MediaType.HTML) + return ASGIResponse(body=self.render_404_page(), status_code=HTTP_404_NOT_FOUND, media_type=MediaType.HTML) + + @get(path="/rapidoc", media_type=MediaType.HTML, include_in_schema=False, sync_to_thread=False) + def rapidoc(self, request: Request[Any, Any, Any]) -> ASGIResponse: + if self.should_serve_endpoint(request): + return ASGIResponse(body=self.render_rapidoc(request), media_type=MediaType.HTML) + return ASGIResponse(body=self.render_404_page(), status_code=HTTP_404_NOT_FOUND, media_type=MediaType.HTML) + + @get(path="/oauth2-redirect.html", media_type=MediaType.HTML, include_in_schema=False, sync_to_thread=False) + def swagger_ui_oauth2_redirect(self, request: Request[Any, Any, Any]) -> ASGIResponse: # pragma: no cover + """Route handler responsible for rendering oauth2-redirect.html page for Swagger-UI. + + Args: + request: + A :class:`Request <.connection.Request>` instance. + + Returns: + A response with a rendered oauth2-redirect.html page for Swagger-UI. + """ + if self.should_serve_endpoint(request): + return ASGIResponse(body=self.render_swagger_ui_oauth2_redirect(request), media_type=MediaType.HTML) + return ASGIResponse(body=self.render_404_page(), status_code=HTTP_404_NOT_FOUND, media_type=MediaType.HTML) + + def render_swagger_ui_oauth2_redirect(self, request: Request[Any, Any, Any]) -> bytes: + """Render an HTML oauth2-redirect.html page for Swagger-UI. + + Notes: + - override this method to customize the template. + + Args: + request: + A :class:`Request <.connection.Request>` instance. + + Returns: + A rendered html string. + """ + return rb"""<!doctype html> + <html lang="en-US"> + <head> + <title>Swagger UI: OAuth2 Redirect</title> + </head> + <body> + <script> + 'use strict'; + function run () { + var oauth2 = window.opener.swaggerUIRedirectOauth2; + var sentState = oauth2.state; + var redirectUrl = oauth2.redirectUrl; + var isValid, qp, arr; + + if (/code|token|error/.test(window.location.hash)) { + qp = window.location.hash.substring(1).replace('?', '&'); + } else { + qp = location.search.substring(1); + } + + arr = qp.split("&"); + arr.forEach(function (v,i,_arr) { _arr[i] = '"' + v.replace('=', '":"') + '"';}); + qp = qp ? JSON.parse('{' + arr.join() + '}', + function (key, value) { + return key === "" ? value : decodeURIComponent(value); + } + ) : {}; + + isValid = qp.state === sentState; + + if (( + oauth2.auth.schema.get("flow") === "accessCode" || + oauth2.auth.schema.get("flow") === "authorizationCode" || + oauth2.auth.schema.get("flow") === "authorization_code" + ) && !oauth2.auth.code) { + if (!isValid) { + oauth2.errCb({ + authId: oauth2.auth.name, + source: "auth", + level: "warning", + message: "Authorization may be unsafe, passed state was changed in server. The passed state wasn't returned from auth server." + }); + } + + if (qp.code) { + delete oauth2.state; + oauth2.auth.code = qp.code; + oauth2.callback({auth: oauth2.auth, redirectUrl: redirectUrl}); + } else { + let oauthErrorMsg; + if (qp.error) { + oauthErrorMsg = "["+qp.error+"]: " + + (qp.error_description ? qp.error_description+ ". " : "no accessCode received from the server. ") + + (qp.error_uri ? "More info: "+qp.error_uri : ""); + } + + oauth2.errCb({ + authId: oauth2.auth.name, + source: "auth", + level: "error", + message: oauthErrorMsg || "[Authorization failed]: no accessCode received from the server." + }); + } + } else { + oauth2.callback({auth: oauth2.auth, token: qp, isValid: isValid, redirectUrl: redirectUrl}); + } + window.close(); + } + + if (document.readyState !== 'loading') { + run(); + } else { + document.addEventListener('DOMContentLoaded', function () { + run(); + }); + } + </script> + </body> + </html>""" + + def render_swagger_ui(self, request: Request[Any, Any, Any]) -> bytes: + """Render an HTML page for Swagger-UI. + + Notes: + - override this method to customize the template. + + Args: + request: + A :class:`Request <.connection.Request>` instance. + + Returns: + A rendered html string. + """ + schema = self.get_schema_from_request(request) + + head = f""" + <head> + <title>{schema.info.title}</title> + {self.favicon} + <meta charset="utf-8"/> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <link href="{self.swagger_css_url}" rel="stylesheet"> + <script src="{self.swagger_ui_bundle_js_url}" crossorigin></script> + <script src="{self.swagger_ui_standalone_preset_js_url}" crossorigin></script> + <style>{self.style}</style> + </head> + """ + + body = f""" + <body> + <div id='swagger-container'/> + <script type="text/javascript"> + const ui = SwaggerUIBundle({{ + spec: {self._get_schema_as_json(request)}, + dom_id: '#swagger-container', + deepLinking: true, + showExtensions: true, + showCommonExtensions: true, + presets: [ + SwaggerUIBundle.presets.apis, + SwaggerUIBundle.SwaggerUIStandalonePreset + ], + }}) + ui.initOAuth({encode_json(self.swagger_ui_init_oauth).decode('utf-8')}) + </script> + </body> + """ + + return f""" + <!DOCTYPE html> + <html> + {head} + {body} + </html> + """.encode() + + def render_stoplight_elements(self, request: Request[Any, Any, Any]) -> bytes: + """Render an HTML page for StopLight Elements. + + Notes: + - override this method to customize the template. + + Args: + request: + A :class:`Request <.connection.Request>` instance. + + Returns: + A rendered html string. + """ + schema = self.get_schema_from_request(request) + head = f""" + <head> + <title>{schema.info.title}</title> + {self.favicon} + <meta charset="utf-8"/> + <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> + <link rel="stylesheet" href="{self.stoplight_elements_css_url}"> + <script src="{self.stoplight_elements_js_url}" crossorigin></script> + <style>{self.style}</style> + </head> + """ + + body = f""" + <body> + <elements-api + apiDescriptionUrl="{request.app.route_reverse(_OPENAPI_JSON_ROUTER_NAME)}" + router="hash" + layout="sidebar" + /> + </body> + """ + + return f""" + <!DOCTYPE html> + <html> + {head} + {body} + </html> + """.encode() + + def render_rapidoc(self, request: Request[Any, Any, Any]) -> bytes: # pragma: no cover + schema = self.get_schema_from_request(request) + + head = f""" + <head> + <title>{schema.info.title}</title> + {self.favicon} + <meta charset="utf-8"/> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <script src="{self.rapidoc_js_url}" crossorigin></script> + <style>{self.style}</style> + </head> + """ + + body = f""" + <body> + <rapi-doc spec-url="{request.app.route_reverse(_OPENAPI_JSON_ROUTER_NAME)}" /> + </body> + """ + + return f""" + <!DOCTYPE html> + <html> + {head} + {body} + </html> + """.encode() + + def render_redoc(self, request: Request[Any, Any, Any]) -> bytes: # pragma: no cover + """Render an HTML page for Redoc. + + Notes: + - override this method to customize the template. + + Args: + request: + A :class:`Request <.connection.Request>` instance. + + Returns: + A rendered html string. + """ + schema = self.get_schema_from_request(request) + + head = f""" + <head> + <title>{schema.info.title}</title> + {self.favicon} + <meta charset="utf-8"/> + <meta name="viewport" content="width=device-width, initial-scale=1"> + """ + + if self.redoc_google_fonts: + head += """ + <link href="https://fonts.googleapis.com/css?family=Montserrat:300,400,700|Roboto:300,400,700" rel="stylesheet"> + """ + + head += f""" + <script src="{self.redoc_js_url}" crossorigin></script> + <style> + {self.style} + </style> + </head> + """ + + body = f""" + <body> + <div id='redoc-container'/> + <script type="text/javascript"> + Redoc.init( + {self._get_schema_as_json(request)}, + undefined, + document.getElementById('redoc-container') + ) + </script> + </body> + """ + + return f""" + <!DOCTYPE html> + <html> + {head} + {body} + </html> + """.encode() + + def render_404_page(self) -> bytes: + """Render an HTML 404 page. + + Returns: + A rendered html string. + """ + + return f""" + <!DOCTYPE html> + <html> + <head> + <title>404 Not found</title> + {self.favicon} + <meta charset="utf-8"/> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <style> + {self.style} + </style> + </head> + <body> + <h1>Error 404</h1> + </body> + </html> + """.encode() + + def _get_schema_as_json(self, request: Request) -> str: + """Get the schema encoded as a JSON string.""" + + if not self._dumped_json_schema: + schema = self.get_schema_from_request(request).to_schema() + json_encoded_schema = encode_json(schema, request.route_handler.default_serializer) + self._dumped_json_schema = json_encoded_schema.decode("utf-8") + + return self._dumped_json_schema diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/datastructures.py b/venv/lib/python3.11/site-packages/litestar/openapi/datastructures.py new file mode 100644 index 0000000..5796a48 --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/datastructures.py @@ -0,0 +1,29 @@ +from __future__ import annotations + +from dataclasses import dataclass, field +from typing import TYPE_CHECKING + +from litestar.enums import MediaType + +if TYPE_CHECKING: + from litestar.openapi.spec import Example + from litestar.types import DataContainerType + + +__all__ = ("ResponseSpec",) + + +@dataclass +class ResponseSpec: + """Container type of additional responses.""" + + data_container: DataContainerType | None + """A model that describes the content of the response.""" + generate_examples: bool = field(default=True) + """Generate examples for the response content.""" + description: str = field(default="Additional response") + """A description of the response.""" + media_type: MediaType = field(default=MediaType.JSON) + """Response media type.""" + examples: list[Example] | None = field(default=None) + """A list of Example models.""" diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/__init__.py b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__init__.py new file mode 100644 index 0000000..438c351 --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__init__.py @@ -0,0 +1,68 @@ +from .base import BaseSchemaObject +from .callback import Callback +from .components import Components +from .contact import Contact +from .discriminator import Discriminator +from .encoding import Encoding +from .enums import OpenAPIFormat, OpenAPIType +from .example import Example +from .external_documentation import ExternalDocumentation +from .header import OpenAPIHeader +from .info import Info +from .license import License +from .link import Link +from .media_type import OpenAPIMediaType +from .oauth_flow import OAuthFlow +from .oauth_flows import OAuthFlows +from .open_api import OpenAPI +from .operation import Operation +from .parameter import Parameter +from .path_item import PathItem +from .paths import Paths +from .reference import Reference +from .request_body import RequestBody +from .response import OpenAPIResponse +from .responses import Responses +from .schema import Schema +from .security_requirement import SecurityRequirement +from .security_scheme import SecurityScheme +from .server import Server +from .server_variable import ServerVariable +from .tag import Tag +from .xml import XML + +__all__ = ( + "BaseSchemaObject", + "Callback", + "Components", + "Contact", + "Discriminator", + "Encoding", + "Example", + "ExternalDocumentation", + "Info", + "License", + "Link", + "OAuthFlow", + "OAuthFlows", + "OpenAPI", + "OpenAPIFormat", + "OpenAPIHeader", + "OpenAPIMediaType", + "OpenAPIResponse", + "OpenAPIType", + "Operation", + "Parameter", + "PathItem", + "Paths", + "Reference", + "RequestBody", + "Responses", + "Schema", + "SecurityRequirement", + "SecurityScheme", + "Server", + "ServerVariable", + "Tag", + "XML", +) diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/__init__.cpython-311.pyc b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/__init__.cpython-311.pyc Binary files differnew file mode 100644 index 0000000..682acac --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/__init__.cpython-311.pyc diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/base.cpython-311.pyc b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/base.cpython-311.pyc Binary files differnew file mode 100644 index 0000000..7f9658f --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/base.cpython-311.pyc diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/callback.cpython-311.pyc b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/callback.cpython-311.pyc Binary files differnew file mode 100644 index 0000000..8fb170e --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/callback.cpython-311.pyc diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/components.cpython-311.pyc b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/components.cpython-311.pyc Binary files differnew file mode 100644 index 0000000..98c83be --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/components.cpython-311.pyc diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/contact.cpython-311.pyc b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/contact.cpython-311.pyc Binary files differnew file mode 100644 index 0000000..53b94c2 --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/contact.cpython-311.pyc diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/discriminator.cpython-311.pyc b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/discriminator.cpython-311.pyc Binary files differnew file mode 100644 index 0000000..5a4b1bc --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/discriminator.cpython-311.pyc diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/encoding.cpython-311.pyc b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/encoding.cpython-311.pyc Binary files differnew file mode 100644 index 0000000..58ab620 --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/encoding.cpython-311.pyc diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/enums.cpython-311.pyc b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/enums.cpython-311.pyc Binary files differnew file mode 100644 index 0000000..9e328e3 --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/enums.cpython-311.pyc diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/example.cpython-311.pyc b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/example.cpython-311.pyc Binary files differnew file mode 100644 index 0000000..4f031b1 --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/example.cpython-311.pyc diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/external_documentation.cpython-311.pyc b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/external_documentation.cpython-311.pyc Binary files differnew file mode 100644 index 0000000..a0f445b --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/external_documentation.cpython-311.pyc diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/header.cpython-311.pyc b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/header.cpython-311.pyc Binary files differnew file mode 100644 index 0000000..1596fd8 --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/header.cpython-311.pyc diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/info.cpython-311.pyc b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/info.cpython-311.pyc Binary files differnew file mode 100644 index 0000000..45c4fdd --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/info.cpython-311.pyc diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/license.cpython-311.pyc b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/license.cpython-311.pyc Binary files differnew file mode 100644 index 0000000..98c60d4 --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/license.cpython-311.pyc diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/link.cpython-311.pyc b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/link.cpython-311.pyc Binary files differnew file mode 100644 index 0000000..b30775a --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/link.cpython-311.pyc diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/media_type.cpython-311.pyc b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/media_type.cpython-311.pyc Binary files differnew file mode 100644 index 0000000..47c85af --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/media_type.cpython-311.pyc diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/oauth_flow.cpython-311.pyc b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/oauth_flow.cpython-311.pyc Binary files differnew file mode 100644 index 0000000..a6a8564 --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/oauth_flow.cpython-311.pyc diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/oauth_flows.cpython-311.pyc b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/oauth_flows.cpython-311.pyc Binary files differnew file mode 100644 index 0000000..04555f8 --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/oauth_flows.cpython-311.pyc diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/open_api.cpython-311.pyc b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/open_api.cpython-311.pyc Binary files differnew file mode 100644 index 0000000..1926726 --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/open_api.cpython-311.pyc diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/operation.cpython-311.pyc b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/operation.cpython-311.pyc Binary files differnew file mode 100644 index 0000000..1c3ddc2 --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/operation.cpython-311.pyc diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/parameter.cpython-311.pyc b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/parameter.cpython-311.pyc Binary files differnew file mode 100644 index 0000000..e860dc9 --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/parameter.cpython-311.pyc diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/path_item.cpython-311.pyc b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/path_item.cpython-311.pyc Binary files differnew file mode 100644 index 0000000..cf33d1c --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/path_item.cpython-311.pyc diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/paths.cpython-311.pyc b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/paths.cpython-311.pyc Binary files differnew file mode 100644 index 0000000..4dc2e6e --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/paths.cpython-311.pyc diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/reference.cpython-311.pyc b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/reference.cpython-311.pyc Binary files differnew file mode 100644 index 0000000..66b4e2c --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/reference.cpython-311.pyc diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/request_body.cpython-311.pyc b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/request_body.cpython-311.pyc Binary files differnew file mode 100644 index 0000000..5788ebc --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/request_body.cpython-311.pyc diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/response.cpython-311.pyc b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/response.cpython-311.pyc Binary files differnew file mode 100644 index 0000000..364f342 --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/response.cpython-311.pyc diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/responses.cpython-311.pyc b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/responses.cpython-311.pyc Binary files differnew file mode 100644 index 0000000..db08130 --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/responses.cpython-311.pyc diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/schema.cpython-311.pyc b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/schema.cpython-311.pyc Binary files differnew file mode 100644 index 0000000..6af9ca3 --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/schema.cpython-311.pyc diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/security_requirement.cpython-311.pyc b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/security_requirement.cpython-311.pyc Binary files differnew file mode 100644 index 0000000..5aa7c2f --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/security_requirement.cpython-311.pyc diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/security_scheme.cpython-311.pyc b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/security_scheme.cpython-311.pyc Binary files differnew file mode 100644 index 0000000..a2b1045 --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/security_scheme.cpython-311.pyc diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/server.cpython-311.pyc b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/server.cpython-311.pyc Binary files differnew file mode 100644 index 0000000..26b70b3 --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/server.cpython-311.pyc diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/server_variable.cpython-311.pyc b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/server_variable.cpython-311.pyc Binary files differnew file mode 100644 index 0000000..46ab0cd --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/server_variable.cpython-311.pyc diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/tag.cpython-311.pyc b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/tag.cpython-311.pyc Binary files differnew file mode 100644 index 0000000..7597e16 --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/tag.cpython-311.pyc diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/xml.cpython-311.pyc b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/xml.cpython-311.pyc Binary files differnew file mode 100644 index 0000000..97cacd9 --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/__pycache__/xml.cpython-311.pyc diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/base.py b/venv/lib/python3.11/site-packages/litestar/openapi/spec/base.py new file mode 100644 index 0000000..69cd3f3 --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/base.py @@ -0,0 +1,56 @@ +from __future__ import annotations + +from dataclasses import asdict, dataclass, fields, is_dataclass +from enum import Enum +from typing import Any + +__all__ = ("BaseSchemaObject",) + + +def _normalize_key(key: str) -> str: + if key.endswith("_in"): + return "in" + if key.startswith("schema_"): + return key.split("_")[1] + if "_" in key: + components = key.split("_") + return components[0] + "".join(component.title() for component in components[1:]) + return "$ref" if key == "ref" else key + + +def _normalize_value(value: Any) -> Any: + if isinstance(value, BaseSchemaObject): + return value.to_schema() + if is_dataclass(value): + return {_normalize_value(k): _normalize_value(v) for k, v in asdict(value).items() if v is not None} + if isinstance(value, dict): + return {_normalize_value(k): _normalize_value(v) for k, v in value.items() if v is not None} + if isinstance(value, list): + return [_normalize_value(v) for v in value] + return value.value if isinstance(value, Enum) else value + + +@dataclass +class BaseSchemaObject: + """Base class for schema spec objects""" + + def to_schema(self) -> dict[str, Any]: + """Transform the spec dataclass object into a string keyed dictionary. This method traverses all nested values + recursively. + """ + result: dict[str, Any] = {} + + for field in fields(self): + value = _normalize_value(getattr(self, field.name, None)) + + if value is not None: + if "alias" in field.metadata: + if not isinstance(field.metadata["alias"], str): + raise TypeError('metadata["alias"] must be a str') + key = field.metadata["alias"] + else: + key = _normalize_key(field.name) + + result[key] = value + + return result diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/callback.py b/venv/lib/python3.11/site-packages/litestar/openapi/spec/callback.py new file mode 100644 index 0000000..c4bb129 --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/callback.py @@ -0,0 +1,24 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING, Dict, Union + +if TYPE_CHECKING: + from litestar.openapi.spec.path_item import PathItem + from litestar.openapi.spec.reference import Reference + + +Callback = Dict[str, Union["PathItem", "Reference"]] +"""A map of possible out-of band callbacks related to the parent operation. Each value in the map is a +`Path Item Object <https://spec.openapis.org/oas/v3.1.0#pathItemObject>`_ that describes a set of requests that may be +initiated by the API provider and the expected responses. The key value used to identify the path item object is an +expression, evaluated at runtime, that identifies a URL to use for the callback operation. + +Patterned Fields + +{expression}: 'PathItem' = ... + +A Path Item Object used to define a callback request and expected responses. + +A `complete example <https://github.com/OAI/OpenAPI-Specification/blob/main/examples/v3.1/webhook-example.yaml>`_ is +available. +""" diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/components.py b/venv/lib/python3.11/site-packages/litestar/openapi/spec/components.py new file mode 100644 index 0000000..b11da78 --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/components.py @@ -0,0 +1,72 @@ +from __future__ import annotations + +from dataclasses import dataclass, field +from typing import TYPE_CHECKING + +from litestar.openapi.spec.base import BaseSchemaObject + +__all__ = ("Components",) + + +if TYPE_CHECKING: + from litestar.openapi.spec.callback import Callback + from litestar.openapi.spec.example import Example + from litestar.openapi.spec.header import OpenAPIHeader + from litestar.openapi.spec.link import Link + from litestar.openapi.spec.parameter import Parameter + from litestar.openapi.spec.path_item import PathItem + from litestar.openapi.spec.reference import Reference + from litestar.openapi.spec.request_body import RequestBody + from litestar.openapi.spec.response import OpenAPIResponse + from litestar.openapi.spec.schema import Schema + from litestar.openapi.spec.security_scheme import SecurityScheme + + +@dataclass +class Components(BaseSchemaObject): + """Holds a set of reusable objects for different aspects of the OAS. + + All objects defined within the components object will have no effect + on the API unless they are explicitly referenced from properties + outside the components object. + """ + + schemas: dict[str, Schema] = field(default_factory=dict) + """An object to hold reusable + `Schema Objects <https://spec.openapis.org/oas/v3.1.0#schemaObject>`_""" + + responses: dict[str, OpenAPIResponse | Reference] | None = None + """An object to hold reusable + `Response Objects <https://spec.openapis.org/oas/v3.1.0#responseObject>`_""" + + parameters: dict[str, Parameter | Reference] | None = None + """An object to hold reusable + `Parameter Objects <https://spec.openapis.org/oas/v3.1.0#parameterObject>`_""" + + examples: dict[str, Example | Reference] | None = None + """An object to hold reusable + `Example Objects <https://spec.openapis.org/oas/v3.1.0#exampleObject>`_""" + + request_bodies: dict[str, RequestBody | Reference] | None = None + """An object to hold reusable + `Request Body Objects <https://spec.openapis.org/oas/v3.1.0#requestBodyObject>`_""" + + headers: dict[str, OpenAPIHeader | Reference] | None = None + """An object to hold reusable + `Header Objects <https://spec.openapis.org/oas/v3.1.0#headerObject>`_""" + + security_schemes: dict[str, SecurityScheme | Reference] | None = None + """An object to hold reusable + `Security Scheme Objects <https://spec.openapis.org/oas/v3.1.0#securitySchemeObject>`_""" + + links: dict[str, Link | Reference] | None = None + """An object to hold reusable + `Link Objects <https://spec.openapis.org/oas/v3.1.0#linkObject>`_""" + + callbacks: dict[str, Callback | Reference] | None = None + """An object to hold reusable + `Callback Objects <https://spec.openapis.org/oas/v3.1.0#callbackObject>`_""" + + path_items: dict[str, PathItem | Reference] | None = None + """An object to hold reusable + `Path Item Object <https://spec.openapis.org/oas/v3.1.0#pathItemObject>`_""" diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/contact.py b/venv/lib/python3.11/site-packages/litestar/openapi/spec/contact.py new file mode 100644 index 0000000..b816288 --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/contact.py @@ -0,0 +1,21 @@ +from __future__ import annotations + +from dataclasses import dataclass + +from litestar.openapi.spec.base import BaseSchemaObject + +__all__ = ("Contact",) + + +@dataclass +class Contact(BaseSchemaObject): + """Contact information for the exposed API.""" + + name: str | None = None + """The identifying name of the contact person/organization.""" + + url: str | None = None + """The URL pointing to the contact information. MUST be in the form of a URL.""" + + email: str | None = None + """The email address of the contact person/organization. MUST be in the form of an email address.""" diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/discriminator.py b/venv/lib/python3.11/site-packages/litestar/openapi/spec/discriminator.py new file mode 100644 index 0000000..3c292ce --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/discriminator.py @@ -0,0 +1,25 @@ +from __future__ import annotations + +from dataclasses import dataclass + +from litestar.openapi.spec.base import BaseSchemaObject + +__all__ = ("Discriminator",) + + +@dataclass(unsafe_hash=True) +class Discriminator(BaseSchemaObject): + """When request bodies or response payloads may be one of a number of different schemas, a ``discriminator`` + object can be used to aid in serialization, deserialization, and validation. + + The discriminator is a specific object in a schema which is used to inform the consumer of the specification of an + alternative schema based on the value associated with it. + + When using the discriminator, _inline_ schemas will not be considered. + """ + + property_name: str + """**REQUIRED**. The name of the property in the payload that will hold the discriminator value.""" + + mapping: dict[str, str] | None = None + """An object to hold mappings between payload values and schema names or references.""" diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/encoding.py b/venv/lib/python3.11/site-packages/litestar/openapi/spec/encoding.py new file mode 100644 index 0000000..2a469c8 --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/encoding.py @@ -0,0 +1,67 @@ +from __future__ import annotations + +from dataclasses import dataclass +from typing import TYPE_CHECKING + +from litestar.openapi.spec.base import BaseSchemaObject + +if TYPE_CHECKING: + from litestar.openapi.spec.header import OpenAPIHeader + from litestar.openapi.spec.reference import Reference + +__all__ = ("Encoding",) + + +@dataclass +class Encoding(BaseSchemaObject): + """A single encoding definition applied to a single schema property.""" + + content_type: str | None = None + """The Content-Type for encoding a specific property. Default value depends n the property type: + + - for ``object``: ``application/json`` + - for ``array``: the default is defined based on the inner type + - for all other cases the default is ``application/octet-stream``. + + The value can be a specific media type (e.g. ``application/json``), a wildcard media type (e.g. ``image/*``), or a + comma-separated list of the two types. + """ + + headers: dict[str, OpenAPIHeader | Reference] | None = None + """A map allowing additional information to be provided as headers, for example ``Content-Disposition``. + + ``Content-Type`` is described separately and SHALL be ignored in this section. This property SHALL be ignored if the + request body media type is not a ``multipart``. + """ + + style: str | None = None + """Describes how a specific property value will be serialized depending on its type. + + See `Parameter Object <https://spec.openapis.org/oas/v3.1.0#parameterObject>`_ for details on the + `style <https://spec.openapis.org/oas/v3.1.0#parameterStyle>`__ property. The behavior follows the same values as + ``query`` parameters, including default values. This property SHALL be ignored if the request body media type is not + ``application/x-www-form-urlencoded`` or ``multipart/form-data``. If a value is explicitly defined, then the value + of `contentType <https://spec.openapis.org/oas/v3.1.0#encodingContentType>`_ (implicit or explicit) SHALL be + ignored. + """ + + explode: bool = False + """When this is true, property values of type ``array`` or ``object`` generate separate parameters for each value of + the array, or key-value-pair of the map. + + For other types of properties this property has no effect. When + `style <https://spec.openapis.org/oas/v3.1.0#encodingStyle>`_ is ``form``, the default value is ``True``. For all + other styles, the default value is ``False``. This property SHALL be ignored if the request body media type is not + ``application/x-www-form-urlencoded`` or ``multipart/form-data``. If a value is explicitly defined, then the value + of `contentType <https://spec.openapis.org/oas/v3.1.0#encodingContentType>`_ (implicit or explicit) SHALL be + ignored. + """ + + allow_reserved: bool = False + """Determines whether the parameter value SHOULD allow reserved characters, as defined by :rfc:`3986` + (``:/?#[]@!$&'()*+,;=``) to be included without percent-encoding. + + This property SHALL be ignored if the request body media type s not ``application/x-www-form-urlencoded`` or + ``multipart/form-data``. If a value is explicitly defined, then the value of + `contentType <https://spec.openapis.org/oas/v3.1.0#encodingContentType>`_ (implicit or explicit) SHALL be ignored. + """ diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/enums.py b/venv/lib/python3.11/site-packages/litestar/openapi/spec/enums.py new file mode 100644 index 0000000..da9adea --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/enums.py @@ -0,0 +1,41 @@ +from enum import Enum + +__all__ = ("OpenAPIFormat", "OpenAPIType") + + +class OpenAPIFormat(str, Enum): + """Formats extracted from: https://datatracker.ietf.org/doc/html/draft-bhutton-json-schema-validation-00#page-13""" + + DATE = "date" + DATE_TIME = "date-time" + TIME = "time" + DURATION = "duration" + URL = "url" + EMAIL = "email" + IDN_EMAIL = "idn-email" + HOST_NAME = "hostname" + IDN_HOST_NAME = "idn-hostname" + IPV4 = "ipv4" + IPV6 = "ipv6" + URI = "uri" + URI_REFERENCE = "uri-reference" + URI_TEMPLATE = "uri-template" + JSON_POINTER = "json-pointer" + RELATIVE_JSON_POINTER = "relative-json-pointer" + IRI = "iri-reference" + IRI_REFERENCE = "iri-reference" # noqa: PIE796 + UUID = "uuid" + REGEX = "regex" + BINARY = "binary" + + +class OpenAPIType(str, Enum): + """An OopenAPI type.""" + + ARRAY = "array" + BOOLEAN = "boolean" + INTEGER = "integer" + NULL = "null" + NUMBER = "number" + OBJECT = "object" + STRING = "string" diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/example.py b/venv/lib/python3.11/site-packages/litestar/openapi/spec/example.py new file mode 100644 index 0000000..414452e --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/example.py @@ -0,0 +1,33 @@ +from __future__ import annotations + +from dataclasses import dataclass +from typing import Any + +from litestar.openapi.spec.base import BaseSchemaObject + + +@dataclass +class Example(BaseSchemaObject): + summary: str | None = None + """Short description for the example.""" + + description: str | None = None + """Long description for the example. + + `CommonMark syntax <https://spec.commonmark.org/>`_ MAY be used for rich text representation. + """ + + value: Any | None = None + """Embedded literal example. + + The ``value`` field and ``externalValue`` field are mutually exclusive. To represent examples of media types that + cannot naturally represented in JSON or YAML, use a string value to contain the example, escaping where necessary. + """ + + external_value: str | None = None + """A URL that points to the literal example. This provides the capability to reference examples that cannot easily + be included in JSON or YAML documents. + + The ``value`` field and ``externalValue`` field are mutually exclusive. See the rules for resolving + `Relative References <https://spec.openapis.org/oas/v3.1.0#relativeReferencesURI>`_. + """ diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/external_documentation.py b/venv/lib/python3.11/site-packages/litestar/openapi/spec/external_documentation.py new file mode 100644 index 0000000..f11b90d --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/external_documentation.py @@ -0,0 +1,21 @@ +from __future__ import annotations + +from dataclasses import dataclass + +from litestar.openapi.spec.base import BaseSchemaObject + +__all__ = ("ExternalDocumentation",) + + +@dataclass +class ExternalDocumentation(BaseSchemaObject): + """Allows referencing an external resource for extended documentation.""" + + url: str + """**REQUIRED**. The URL for the target documentation. Value MUST be in the form of a URL.""" + + description: str | None = None + """A short description of the target documentation. + + `CommonMark syntax <https://spec.commonmark.org/>`_ MAY be used for rich text representation. + """ diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/header.py b/venv/lib/python3.11/site-packages/litestar/openapi/spec/header.py new file mode 100644 index 0000000..006ff22 --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/header.py @@ -0,0 +1,121 @@ +from __future__ import annotations + +from dataclasses import dataclass +from typing import TYPE_CHECKING, Any, Literal + +from litestar.openapi.spec.base import BaseSchemaObject + +if TYPE_CHECKING: + from litestar.openapi.spec.example import Example + from litestar.openapi.spec.media_type import OpenAPIMediaType + from litestar.openapi.spec.reference import Reference + from litestar.openapi.spec.schema import Schema + +__all__ = ("OpenAPIHeader",) + + +@dataclass +class OpenAPIHeader(BaseSchemaObject): + """The Header Object follows the structure of the [Parameter + Object](https://spec.openapis.org/oas/v3.1.0#parameterObject) with the + following changes: + + 1. ``name`` MUST NOT be specified, it is given in the corresponding ``headers`` map. + 2. ``in`` MUST NOT be specified, it is implicitly in ``header``. + 3. All traits that are affected by the location MUST be applicable to a location of ``header`` + (for example, `style <https://spec.openapis.org/oas/v3.1.0#parameterStyle>`__). + """ + + schema: Schema | Reference | None = None + """The schema defining the type used for the parameter.""" + + name: Literal[""] = "" + """MUST NOT be specified, it is given in the corresponding ``headers`` map.""" + + param_in: Literal["header"] = "header" + """MUST NOT be specified, it is implicitly in ``header``.""" + + description: str | None = None + """A brief description of the parameter. This could contain examples of + use. + + `CommonMark syntax <https://spec.commonmark.org/>`_ MAY be used for rich text representation. + """ + + required: bool = False + """Determines whether this parameter is mandatory. + + If the `parameter location <https://spec.openapis.org/oas/v3.1.0#parameterIn>`_ is ``"path"``, this property is + **REQUIRED** and its value MUST be ``True``. Otherwise, the property MAY be included and its default value is + ``False``. + """ + + deprecated: bool = False + """Specifies that a parameter is deprecated and SHOULD be transitioned out of usage. Default value is ``False``.""" + + allow_empty_value: bool = False + """Sets the ability to pass empty-valued parameters. This is valid only for ``query`` parameters and allows sending + a parameter with an empty value. Default value is ``False``. If + `style <https://spec.openapis.org/oas/v3.1.0#parameterStyle>`__ is used, and if behavior is ``n/a`` (cannot be + serialized), the value of ``allowEmptyValue`` SHALL be ignored. Use of this property is NOT RECOMMENDED, as it is + likely to be removed in a later revision. + + The rules for serialization of the parameter are specified in one of two ways.For simpler scenarios, a + `schema <https://spec.openapis.org/oas/v3.1.0#parameterSchema>`_ and + `style <https://spec.openapis.org/oas/v3.1.0#parameterStyle>`__ can describe the structure and syntax of the + parameter. + """ + + style: str | None = None + """Describes how the parameter value will be serialized depending on the + type of the parameter value. Default values (based on value of ``in``): + + - for ``query`` - ``form``; + - for ``path`` - ``simple``; + - for ``header`` - ``simple``; + - for ``cookie`` - ``form``. + """ + + explode: bool | None = None + """When this is true, parameter values of type ``array`` or ``object`` generate separate parameters for each value + of the array or key-value pair of the map. + + For other types of parameters this property has no effect.When + `style <https://spec.openapis.org/oas/v3.1.0#parameterStyle>`__ is ``form``, the default value is ``True``. For all + other styles, the default value is ``False``. + """ + + allow_reserved: bool = False + """Determines whether the parameter value SHOULD allow reserved characters, as defined by. :rfc:`3986` + (``:/?#[]@!$&'()*+,;=``) to be included without percent-encoding. + + This property only applies to parameters with an ``in`` value of ``query``. The default value is ``False``. + """ + + example: Any | None = None + """Example of the parameter's potential value. + + The example SHOULD match the specified schema and encoding properties if present. The ``example`` field is mutually + exclusive of the ``examples`` field. Furthermore, if referencing a ``schema`` that contains an example, the + ``example`` value SHALL _override_ the example provided by the schema. To represent examples of media types that + cannot naturally be represented in JSON or YAML, a string value can contain the example with escaping where + necessary. + """ + + examples: dict[str, Example | Reference] | None = None + """Examples of the parameter's potential value. Each example SHOULD contain a value in the correct format as + specified in the parameter encoding. The ``examples`` field is mutually exclusive of the ``example`` field. + Furthermore, if referencing a ``schema`` that contains an example, the ``examples`` value SHALL _override_ the + example provided by the schema. + + For more complex scenarios, the `content <https://spec.openapis.org/oas/v3.1.0#parameterContent>`_ property can + define the media type and schema of the parameter. A parameter MUST contain either a ``schema`` property, or a + ``content`` property, but not both. When ``example`` or ``examples`` are provided in conjunction with the ``schema`` + object, the example MUST follow the prescribed serialization strategy for the parameter. + """ + + content: dict[str, OpenAPIMediaType] | None = None + """A map containing the representations for the parameter. + + The key is the media type and the value describes it. The map MUST only contain one entry. + """ diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/info.py b/venv/lib/python3.11/site-packages/litestar/openapi/spec/info.py new file mode 100644 index 0000000..1d858db --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/info.py @@ -0,0 +1,50 @@ +from __future__ import annotations + +from dataclasses import dataclass +from typing import TYPE_CHECKING + +from litestar.openapi.spec.base import BaseSchemaObject + +if TYPE_CHECKING: + from litestar.openapi.spec.contact import Contact + from litestar.openapi.spec.license import License + +__all__ = ("Info",) + + +@dataclass +class Info(BaseSchemaObject): + """The object provides metadata about the API. + + The metadata MAY be used by the clients if needed, and MAY be presented in editing or documentation generation tools + for convenience. + """ + + title: str + """ + **REQUIRED**. The title of the API. + """ + + version: str + """ + **REQUIRED**. The version of the OpenAPI document which is distinct from the + `OpenAPI Specification version <https://spec.openapis.org/oas/v3.1.0#oasVersion>`_ or the API implementation version + """ + + summary: str | None = None + """A short summary of the API.""" + + description: str | None = None + """A description of the API. + + `CommonMark syntax <https://spec.commonmark.org/>`_ MAY be used for rich text representation. + """ + + terms_of_service: str | None = None + """A URL to the Terms of Service for the API. MUST be in the form of a URL.""" + + contact: Contact | None = None + """The contact information for the exposed API.""" + + license: License | None = None + """The license information for the exposed API.""" diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/license.py b/venv/lib/python3.11/site-packages/litestar/openapi/spec/license.py new file mode 100644 index 0000000..b779bb4 --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/license.py @@ -0,0 +1,28 @@ +from __future__ import annotations + +from dataclasses import dataclass + +from litestar.openapi.spec.base import BaseSchemaObject + +__all__ = ("License",) + + +@dataclass +class License(BaseSchemaObject): + """License information for the exposed API.""" + + name: str + """**REQUIRED**. The license name used for the API.""" + + identifier: str | None = None + """An + `SPDX <https://spdx.github.io/spdx-spec/v2.3/SPDX-license-list/#a1-licenses-with-short-identifiers>`_ license expression for the API. + + The ``identifier`` field is mutually exclusive of the ``url`` field. + """ + + url: str | None = None + """A URL to the license used for the API. + + This MUST be in the form of a URL. The ``url`` field is mutually exclusive of the ``identifier`` field. + """ diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/link.py b/venv/lib/python3.11/site-packages/litestar/openapi/spec/link.py new file mode 100644 index 0000000..78c4f85 --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/link.py @@ -0,0 +1,66 @@ +from __future__ import annotations + +from dataclasses import dataclass +from typing import TYPE_CHECKING, Any + +from litestar.openapi.spec.base import BaseSchemaObject + +if TYPE_CHECKING: + from litestar.openapi.spec.server import Server + +__all__ = ("Link",) + + +@dataclass +class Link(BaseSchemaObject): + """The ``Link object`` represents a possible design-time link for a response. The presence of a link does not + guarantee the caller's ability to successfully invoke it, rather it provides a known relationship and traversal + mechanism between responses and other operations. + + Unlike _dynamic_ links (i.e. links provided **in** the response payload), the OAS linking mechanism does not require + link information in the runtime response. + + For computing links, and providing instructions to execute them, a + `runtime expression <https://spec.openapis.org/oas/v3.1.0#runtimeExpression>`_ is used for accessing values in an + operation and using them as parameters while invoking the linked operation. + """ + + operation_ref: str | None = None + """A relative or absolute URI reference to an OAS operation. + + This field is mutually exclusive of the ``operationId`` field, and MUST point to an + `Operation Object <https://spec.openapis.org/oas/v3.1.0#operationObject>`_. Relative ``operationRef`` values MAY be + used to locate an existing `Operation Object <https://spec.openapis.org/oas/v3.1.0#operationObject>`_ in the OpenAPI + definition. See the rules for resolving + `Relative References <https://spec.openapis.org/oas/v3.1.0#relativeReferencesURI>`_ + """ + + operation_id: str | None = None + """The name of an _existing_, resolvable OAS operation, as defined with a unique ``operationId``. + + This field is mutually exclusive of the ``operationRef`` field. + """ + + parameters: dict[str, Any] | None = None + """A map representing parameters to pass to an operation as specified with ``operationId`` or identified via + ``operationRef``. The key is the parameter name to be used, whereas the value can be a constant or an expression to + be evaluated and passed to the linked operation. + + The parameter name can be qualified using the + `parameter location <https://spec.openapis.org/oas/v3.1.0#parameterIn>`_ ``[{in}.]{name}`` for operations that use + the same parameter name in different locations (e.g. path.id). + """ + + request_body: Any | None = None + """A literal value or + `{expression} <https://spec.openapis.org/oas/v3.1.0#runtimeExpression>`_ to use as a request body when calling the + target operation.""" + + description: str | None = None + """A description of the link. + + `CommonMark syntax <https://spec.commonmark.org/>`_ MAY be used for rich text representation. + """ + + server: Server | None = None + """A server object to be used by the target operation.""" diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/media_type.py b/venv/lib/python3.11/site-packages/litestar/openapi/spec/media_type.py new file mode 100644 index 0000000..3e83fb5 --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/media_type.py @@ -0,0 +1,51 @@ +from __future__ import annotations + +from dataclasses import dataclass +from typing import TYPE_CHECKING, Any + +from litestar.openapi.spec.base import BaseSchemaObject + +if TYPE_CHECKING: + from litestar.openapi.spec.encoding import Encoding + from litestar.openapi.spec.example import Example + from litestar.openapi.spec.reference import Reference + from litestar.openapi.spec.schema import Schema + +__all__ = ("OpenAPIMediaType",) + + +@dataclass +class OpenAPIMediaType(BaseSchemaObject): + """Each Media Type Object provides schema and examples for the media type identified by its key.""" + + schema: Reference | Schema | None = None + """The schema defining the content of the request, response, or parameter.""" + + example: Any | None = None + """Example of the media type. + + The example object SHOULD be in the correct format as specified by the media type. + + The ``example`` field is mutually exclusive of the ``examples`` field. + + Furthermore, if referencing a ``schema`` which contains an example, the ``example`` value SHALL _override_ the + example provided by the schema. + """ + + examples: dict[str, Example | Reference] | None = None + """Examples of the media type. + + Each example object SHOULD match the media type and specified schema if present. + + The ``examples`` field is mutually exclusive of the ``example`` field. + + Furthermore, if referencing a ``schema`` which contains an example, the ``examples`` value SHALL _override_ the + example provided by the schema. + """ + + encoding: dict[str, Encoding] | None = None + """A map between a property name and its encoding information. + + The key, being the property name, MUST exist in the schema as a property. The encoding object SHALL only apply to + ``requestBody`` objects when the media type is ``multipart`` or ``application/x-www-form-urlencoded``. + """ diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/oauth_flow.py b/venv/lib/python3.11/site-packages/litestar/openapi/spec/oauth_flow.py new file mode 100644 index 0000000..c322efc --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/oauth_flow.py @@ -0,0 +1,36 @@ +from __future__ import annotations + +from dataclasses import dataclass + +from litestar.openapi.spec.base import BaseSchemaObject + +__all__ = ("OAuthFlow",) + + +@dataclass +class OAuthFlow(BaseSchemaObject): + """Configuration details for a supported OAuth Flow.""" + + authorization_url: str | None = None + """ + **REQUIRED** for ``oauth2`` ("implicit", "authorizationCode"). The authorization URL to be used for this flow. This + MUST be in the form of a URL. The OAuth2 standard requires the use of TLS. + """ + + token_url: str | None = None + """ + **REQUIRED** for ``oauth2`` ("password", "clientCredentials", "authorizationCode"). The token URL to be used for + this flow. This MUST be in the form of a URL. The OAuth2 standard requires the use of TLS. + """ + + refresh_url: str | None = None + """The URL to be used for obtaining refresh tokens. + + This MUST be in the form of a URL. The OAuth2 standard requires the use of TLS. + """ + + scopes: dict[str, str] | None = None + """ + **REQUIRED** for ``oauth2``. The available scopes for the OAuth2 security scheme. A map between the scope name and a + short description for it the map MAY be empty. + """ diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/oauth_flows.py b/venv/lib/python3.11/site-packages/litestar/openapi/spec/oauth_flows.py new file mode 100644 index 0000000..920d095 --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/oauth_flows.py @@ -0,0 +1,28 @@ +from __future__ import annotations + +from dataclasses import dataclass +from typing import TYPE_CHECKING + +from litestar.openapi.spec.base import BaseSchemaObject + +if TYPE_CHECKING: + from litestar.openapi.spec.oauth_flow import OAuthFlow + +__all__ = ("OAuthFlows",) + + +@dataclass +class OAuthFlows(BaseSchemaObject): + """Allows configuration of the supported OAuth Flows.""" + + implicit: OAuthFlow | None = None + """Configuration for the OAuth Implicit flow.""" + + password: OAuthFlow | None = None + """Configuration for the OAuth Resource Owner Password flow.""" + + client_credentials: OAuthFlow | None = None + """Configuration for the OAuth Client Credentials flow. Previously called ``application`` in OpenAPI 2.0.""" + + authorization_code: OAuthFlow | None = None + """Configuration for the OAuth Authorization Code flow. Previously called ``accessCode`` in OpenAPI 2.0.""" diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/open_api.py b/venv/lib/python3.11/site-packages/litestar/openapi/spec/open_api.py new file mode 100644 index 0000000..55465fa --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/open_api.py @@ -0,0 +1,87 @@ +from __future__ import annotations + +from dataclasses import dataclass, field +from typing import TYPE_CHECKING + +from litestar.openapi.spec.base import BaseSchemaObject +from litestar.openapi.spec.components import Components +from litestar.openapi.spec.server import Server + +if TYPE_CHECKING: + from litestar.openapi.spec.external_documentation import ExternalDocumentation + from litestar.openapi.spec.info import Info + from litestar.openapi.spec.path_item import PathItem + from litestar.openapi.spec.paths import Paths + from litestar.openapi.spec.reference import Reference + from litestar.openapi.spec.security_requirement import SecurityRequirement + from litestar.openapi.spec.tag import Tag + +__all__ = ("OpenAPI",) + + +@dataclass +class OpenAPI(BaseSchemaObject): + """Root OpenAPI document.""" + + info: Info + """ + **REQUIRED**. Provides metadata about the API. The metadata MAY be used by tooling as required. + """ + + openapi: str = "3.1.0" + """ + **REQUIRED**. This string MUST be the + `version number <https://spec.openapis.org/oas/v3.1.0#versions>`_ of the OpenAPI Specification that the OpenAPI + document uses. The ``openapi`` field SHOULD be used by tooling to interpret the OpenAPI document. This is *not* + related to the API `info.version <https://spec.openapis.org/oas/v3.1.0#infoVersion>`_ string. + """ + + json_schema_dialect: str | None = None + """The default value for the ``$schema`` keyword within + `Schema Objects <https://spec.openapis.org/oas/v3.1.0#schemaObject>`_ contained within this OAS document. + + This MUST be in the form of a URI. + """ + + servers: list[Server] = field(default_factory=lambda x: [Server(url="/")]) # type: ignore[misc, arg-type] + """An array of Server Objects, which provide connectivity information to a target server. + + If the ``servers`` property is not provided, or is an empty array, the default value would be a + `Server Object <https://spec.openapis.org/oas/v3.1.0#serverObject>`_ with a + `url <https://spec.openapis.org/oas/v3.1.0#serverUrl>`_ value of ``/``. + """ + + paths: Paths | None = None + """The available paths and operations for the API.""" + + webhooks: dict[str, PathItem | Reference] | None = None + """The incoming webhooks that MAY be received as part of this API and that the API consumer MAY choose to implement. + + Closely related to the ``callbacks`` feature, this section describes requests initiated other than by an API call, + for example by an out of band registration. The key name is a unique string to refer to each webhook, while the + (optionally referenced) Path Item Object describes a request that may be initiated by the API provider and the + expected responses. An + `example <https://github.com/OAI/OpenAPI-Specification/blob/main/examples/v3.1/webhook-example.yaml>`_ is available. + """ + + components: Components = field(default_factory=Components) + """An element to hold various schemas for the document.""" + + security: list[SecurityRequirement] | None = None + """A declaration of which security mechanisms can be used across the API. + + The list of values includes alternative security requirement objects that can be used. Only one of the security + requirement objects need to be satisfied to authorize a request. Individual operations can override this definition. + To make security optional, an empty security requirement ( ``{}`` ) can be included in the array. + """ + + tags: list[Tag] | None = None + """A list of tags used by the document with additional metadata. + + The order of the tags can be used to reflect on their order by the parsing tools. Not all tags that are used by the + `Operation Object <https://spec.openapis.org/oas/v3.1.0#operationObject>`_ must be declared. The tags that are not + declared MAY be organized randomly or based on the tools' logic. Each tag name in the list MUST be unique. + """ + + external_docs: ExternalDocumentation | None = None + """Additional external documentation.""" diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/operation.py b/venv/lib/python3.11/site-packages/litestar/openapi/spec/operation.py new file mode 100644 index 0000000..ab80181 --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/operation.py @@ -0,0 +1,105 @@ +from __future__ import annotations + +from dataclasses import dataclass +from typing import TYPE_CHECKING + +from litestar.openapi.spec.base import BaseSchemaObject + +if TYPE_CHECKING: + from litestar.openapi.spec.callback import Callback + from litestar.openapi.spec.external_documentation import ExternalDocumentation + from litestar.openapi.spec.parameter import Parameter + from litestar.openapi.spec.reference import Reference + from litestar.openapi.spec.request_body import RequestBody + from litestar.openapi.spec.responses import Responses + from litestar.openapi.spec.security_requirement import SecurityRequirement + from litestar.openapi.spec.server import Server + +__all__ = ("Operation",) + + +@dataclass +class Operation(BaseSchemaObject): + """Describes a single API operation on a path.""" + + tags: list[str] | None = None + """A list of tags for API documentation control. + + Tags can be used for logical grouping of operations by resources or any other qualifier. + """ + + summary: str | None = None + """A short summary of what the operation does.""" + + description: str | None = None + """A verbose explanation of the operation behavior. + + `CommonMark syntax <https://spec.commonmark.org/>`_ MAY be used for rich text representation. + """ + + external_docs: ExternalDocumentation | None = None + """Additional external documentation for this operation.""" + + operation_id: str | None = None + """Unique string used to identify the operation. + + The id MUST be unique among all operations described in the API. The operationId value is **case-sensitive**. Tools + and libraries MAY use the operationId to uniquely identify an operation, therefore, it is RECOMMENDED to follow + common programming naming conventions. + """ + + parameters: list[Parameter | Reference] | None = None + """A list of parameters that are applicable for this operation. + + If a parameter is already defined at the `Path Item <https://spec.openapis.org/oas/v3.1.0#pathItemParameters>`_, + the new definition will override it but can never remove it. The list MUST NOT include duplicated parameters. A + unique parameter is defined by a combination of a `name <https://spec.openapis.org/oas/v3.1.0#parameterName>`_ and + `location <https://spec.openapis.org/oas/v3.1.0#parameterIn>`_. The list can use the + `Reference Object <https://spec.openapis.org/oas/v3.1.0#referenceObject>`_ to link to parameters that are defined at + the `OpenAPI Object's components/parameters <https://spec.openapis.org/oas/v3.1.0#componentsParameters>`_. + """ + + request_body: RequestBody | Reference | None = None + """The request body applicable for this operation. + + The ``requestBody`` is fully supported in HTTP methods where the HTTP 1.1 specification + :rfc:`7231` has explicitly defined semantics for request bodies. In other cases where the HTTP spec is vague (such + as `GET <https://tools.ietf.org/html/rfc7231#section-4.3.1>`_, + `HEAD <https://tools.ietf.org/html/rfc7231#section-4.3.2>`_ and + `DELETE <https://tools.ietf.org/html/rfc7231#section-4.3.5>`_, ``requestBody`` is permitted but does not have + well-defined semantics and SHOULD be avoided if possible. + """ + + responses: Responses | None = None + """The list of possible responses as they are returned from executing this operation.""" + + callbacks: dict[str, Callback | Reference] | None = None + """A map of possible out-of band callbacks related to the parent operation. + + The key is a unique identifier for the Callback Object. Each value in the map is a + `Callback Object <https://spec.openapis.org/oas/v3.1.0#callbackObject>`_ that describes a request that may be + initiated by the API provider and the expected responses. + """ + + deprecated: bool = False + """Declares this operation to be deprecated. + + Consumers SHOULD refrain from usage of the declared operation. Default value is ``False``. + """ + + security: list[SecurityRequirement] | None = None + """A declaration of which security mechanisms can be used for this operation. + + The list of values includes alternative security requirement objects that can be used. Only one of the security + requirement objects need to be satisfied to authorize a request. To make security optional, an empty security + requirement (``{}``) can be included in the array. This definition overrides any declared top-level + `security <https://spec.openapis.org/oas/v3.1.0#oasSecurity>`_. To remove a top-level security declaration, an empty + array can be used. + """ + + servers: list[Server] | None = None + """An alternative ``server`` array to service this operation. + + If an alternative ``server`` object is specified at the Path Item Object or Root level, it will be overridden by + this value. + """ diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/parameter.py b/venv/lib/python3.11/site-packages/litestar/openapi/spec/parameter.py new file mode 100644 index 0000000..74a100f --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/parameter.py @@ -0,0 +1,136 @@ +from __future__ import annotations + +from dataclasses import dataclass +from typing import TYPE_CHECKING, Any, Mapping + +from litestar.openapi.spec.base import BaseSchemaObject + +if TYPE_CHECKING: + from litestar.openapi.spec.example import Example + from litestar.openapi.spec.media_type import OpenAPIMediaType + from litestar.openapi.spec.reference import Reference + from litestar.openapi.spec.schema import Schema + +__all__ = ("Parameter",) + + +@dataclass +class Parameter(BaseSchemaObject): + """Describes a single operation parameter. + + A unique parameter is defined by a combination of a `name <https://spec.openapis.org/oas/v3.1.0#parameterName>`_ and + `location <https://spec.openapis.org/oas/v3.1.0#parameterIn>`_. + """ + + name: str + """ + **REQUIRED**. The name of the parameter. + Parameter names are *case sensitive*. + + - If `in <https://spec.openapis.org/oas/v3.1.0#parameterIn>`_ is ``"path"``, the ``name`` field MUST correspond to a + template expression occurring within the `path <https://spec.openapis.org/oas/v3.1.0#pathsPath>`_ field in the + `Paths Object <https://spec.openapis.org/oas/v3.1.0#pathsObject>`_. See + `Path Templating <https://spec.openapis.org/oas/v3.1.0#pathTemplating>`_ for further information. + - If `in <https://spec.openapis.org/oas/v3.1.0#parameterIn>`_ is ``"header"`` and the ``name`` field is + ``"Accept"``, ``"Content-Type"`` or ``"Authorization"``, the parameter definition SHALL be ignored. + - For all other cases, the ``name`` corresponds to the parameter name used by the + `in <https://spec.openapis.org/oas/v3.1.0#parameterIn>`_ property. + """ + + param_in: str + """ + **REQUIRED**. The location of the parameter. Possible values are + ``"query"``, ``"header"``, ``"path"`` or ``"cookie"``. + """ + + schema: Schema | Reference | None = None + """The schema defining the type used for the parameter.""" + + description: str | None = None + """A brief description of the parameter. This could contain examples of + use. + + `CommonMark syntax <https://spec.commonmark.org/>`_ MAY be used for rich text representation. + """ + + required: bool = False + """Determines whether this parameter is mandatory. + + If the `parameter location <https://spec.openapis.org/oas/v3.1.0#parameterIn>`_ is ``"path"``, this property is + **REQUIRED** and its value MUST be ``True``. Otherwise, the property MAY be included and its default value is + ``False``. + """ + + deprecated: bool = False + """Specifies that a parameter is deprecated and SHOULD be transitioned out of usage. + + Default value is ``False``. + """ + + allow_empty_value: bool = False + """Sets the ability to pass empty-valued parameters. This is valid only for ``query`` parameters and allows sending + a parameter with an empty value. Default value is ``False``. If + `style <https://spec.openapis.org/oas/v3.1.0#parameterStyle>`__ is used, and if behavior is ``n/a`` (cannot be + serialized), the value of ``allowEmptyValue`` SHALL be ignored. Use of this property is NOT RECOMMENDED, as it is + likely to be removed in a later revision. + + The rules for serialization of the parameter are specified in one of two ways. For simpler scenarios, a + `schema <https://spec.openapis.org/oas/v3.1.0#parameterSchema>`_ and + `style <https://spec.openapis.org/oas/v3.1.0#parameterStyle>`__ can describe the structure and syntax of the + parameter. + """ + + style: str | None = None + """Describes how the parameter value will be serialized depending on the ype of the parameter value. Default values + (based on value of ``in``): + + - for ``query`` - ``form`` + - for ``path`` - ``simple`` + - for ``header`` - ``simple`` + - for ``cookie`` - ``form`` + """ + + explode: bool | None = None + """When this is true, parameter values of type ``array`` or ``object`` generate separate parameters for each value + of the array or key-value pair of the map. + + For other types of parameters this property has no effect. When + `style <https://spec.openapis.org/oas/v3.1.0#parameterStyle>`__ is ``form``, the default value is ``True``. For all + other styles, the default value is ``False``. + """ + + allow_reserved: bool = False + """Determines whether the parameter value SHOULD allow reserved characters, as defined by. + + :rfc:`3986` ``:/?#[]@!$&'()*+,;=`` to be included without percent-encoding. + + This property only applies to parameters with an ``in`` value of ``query``. The default value is ``False``. + """ + + example: Any | None = None + """Example of the parameter's potential value. + + The example SHOULD match the specified schema and encoding properties if present. The ``example`` field is mutually + exclusive of the ``examples`` field. Furthermore, if referencing a ``schema`` that contains an example, the + ``example`` value SHALL _override_ the example provided by the schema. To represent examples of media types that + cannot naturally be represented in JSON or YAML, a string value can contain the example with escaping where + necessary. + """ + + examples: Mapping[str, Example | Reference] | None = None + """Examples of the parameter's potential value. Each example SHOULD contain a value in the correct format as + specified in the parameter encoding. The ``examples`` field is mutually exclusive of the ``example`` field. + Furthermore, if referencing a ``schema`` that contains an example, the ``examples`` value SHALL _override_ the + example provided by the schema. + + For more complex scenarios, the `content <https://spec.openapis.org/oas/v3.1.0#parameterContent>`_ property can + define the media type and schema of the parameter. A parameter MUST contain either a ``schema`` property, or a + ``content`` property, but not both. When ``example`` or ``examples`` are provided in conjunction with the + ``schema`` object, the example MUST follow the prescribed serialization strategy for the parameter. + """ + + content: dict[str, OpenAPIMediaType] | None = None + """A map containing the representations for the parameter. + + The key is the media type and the value describes it. The map MUST only contain one entry. + """ diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/path_item.py b/venv/lib/python3.11/site-packages/litestar/openapi/spec/path_item.py new file mode 100644 index 0000000..17005c5 --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/path_item.py @@ -0,0 +1,78 @@ +from __future__ import annotations + +from dataclasses import dataclass +from typing import TYPE_CHECKING + +from litestar.openapi.spec.base import BaseSchemaObject + +if TYPE_CHECKING: + from litestar.openapi.spec.operation import Operation + from litestar.openapi.spec.parameter import Parameter + from litestar.openapi.spec.reference import Reference + from litestar.openapi.spec.server import Server + +__all__ = ("PathItem",) + + +@dataclass +class PathItem(BaseSchemaObject): + """Describes the operations available on a single path. + + A Path Item MAY be empty, due to `ACL constraints <https://spec.openapis.org/oas/v3.1.0#securityFiltering>`_. The + path itself is still exposed to the documentation viewer, but they will not know which operations and parameters are + available. + """ + + ref: str | None = None + """Allows for an external definition of this path item. The referenced structure MUST be in the format of a + `Path Item Object <https://spec.openapis.org/oas/v3.1.0#pathItemObject>`. + + In case a Path Item Object field appears both in the defined object and the referenced object, the behavior is + undefined. See the rules for resolving + `Relative References <https://spec.openapis.org/oas/v3.1.0#relativeReferencesURI>`_. + """ + + summary: str | None = None + """An optional, string summary, intended to apply to all operations in this path.""" + + description: str | None = None + """An optional, string description, intended to apply to all operations in this path. + + `CommonMark syntax <https://spec.commonmark.org/>`_ MAY be used for rich text representation. + """ + + get: Operation | None = None + """A definition of a GET operation on this path.""" + + put: Operation | None = None + """A definition of a PUT operation on this path.""" + + post: Operation | None = None + """A definition of a POST operation on this path.""" + + delete: Operation | None = None + """A definition of a DELETE operation on this path.""" + + options: Operation | None = None + """A definition of a OPTIONS operation on this path.""" + + head: Operation | None = None + """A definition of a HEAD operation on this path.""" + + patch: Operation | None = None + """A definition of a PATCH operation on this path.""" + + trace: Operation | None = None + """A definition of a TRACE operation on this path.""" + + servers: list[Server] | None = None + """An alternative ``server`` array to service all operations in this path.""" + + parameters: list[Parameter | Reference] | None = None + """A list of parameters that are applicable for all the operations described under this path. These parameters can + be overridden at the operation level, but cannot be removed there. The list MUST NOT include duplicated parameters. + A unique parameter is defined by a combination of a `name <https://spec.openapis.org/oas/v3.1.0#parameterName>`_ and + `location <https://spec.openapis.org/oas/v3.1.0#parameterIn>`_. The list can use the + `Reference Object <https://spec.openapis.org/oas/v3.1.0#referenceObject>`_ to link to parameters that are defined at + the `OpenAPI Object's components/parameters <https://spec.openapis.org/oas/v3.1.0#componentsParameters>`_. + """ diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/paths.py b/venv/lib/python3.11/site-packages/litestar/openapi/spec/paths.py new file mode 100644 index 0000000..682664e --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/paths.py @@ -0,0 +1,27 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING, Dict + +if TYPE_CHECKING: + from litestar.openapi.spec import PathItem + +Paths = Dict[str, "PathItem"] +"""Holds the relative paths to the individual endpoints and their operations. The path is appended to the URL from the. + +`Server Object <https://spec.openapis.org/oas/v3.1.0#serverObject>`_ in order to construct the full URL. + +The Paths MAY be empty, due to +`Access Control List (ACL) constraints <https://spec.openapis.org/oas/v3.1.0#securityFiltering>`_. + +Patterned Fields + +/{path}: PathItem + +A relative path to an individual endpoint. The field name MUST begin with a forward slash (``/``). The path is +**appended** (no relative URL resolution) to the expanded URL from the +`Server Object <https://spec.openapis.org/oas/v3.1.0#serverObject>`_ 's ``url`` field in order to construct the full +URL. `Path templating <https://spec.openapis.org/oas/v3.1.0#pathTemplating>`_ is allowed. When matching URLs, concrete +(non-templated) paths would be matched before their templated counterparts. Templated paths with the same hierarchy but +different templated names MUST NOT exist as they are identical. In case of ambiguous matching, it's up to the tooling to +decide which one to use. +""" diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/reference.py b/venv/lib/python3.11/site-packages/litestar/openapi/spec/reference.py new file mode 100644 index 0000000..5ee2a95 --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/reference.py @@ -0,0 +1,38 @@ +from __future__ import annotations + +from dataclasses import dataclass + +from litestar.openapi.spec.base import BaseSchemaObject + +__all__ = ("Reference",) + + +@dataclass +class Reference(BaseSchemaObject): + """A simple object to allow referencing other components in the OpenAPI document, internally and externally. + + The ``$ref`` string value contains a URI `RFC3986 <https://tools.ietf.org/html/rfc3986>`_ , which identifies the + location of the value being referenced. + + See the rules for resolving `Relative References <https://spec.openapis.org/oas/v3.1.0#relativeReferencesURI>`_. + """ + + ref: str + """**REQUIRED**. The reference identifier. This MUST be in the form of a URI.""" + + summary: str | None = None + """A short summary which by default SHOULD override that of the referenced component. + + If the referenced object-type does not allow a ``summary`` field, then this field has no effect. + """ + + description: str | None = None + """A description which by default SHOULD override that of the referenced component. + + `CommonMark syntax <https://spec.commonmark.org/>`_ MAY be used for rich text representation. If the referenced + object-type does not allow a ``description`` field, then this field has no effect. + """ + + @property + def value(self) -> str: + return self.ref.split("/")[-1] diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/request_body.py b/venv/lib/python3.11/site-packages/litestar/openapi/spec/request_body.py new file mode 100644 index 0000000..5e4e195 --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/request_body.py @@ -0,0 +1,38 @@ +from __future__ import annotations + +from dataclasses import dataclass +from typing import TYPE_CHECKING + +from litestar.openapi.spec.base import BaseSchemaObject + +if TYPE_CHECKING: + from litestar.openapi.spec.media_type import OpenAPIMediaType + +__all__ = ("RequestBody",) + + +@dataclass +class RequestBody(BaseSchemaObject): + """Describes a single request body.""" + + content: dict[str, OpenAPIMediaType] + """ + **REQUIRED**. The content of the request body. + The key is a media type or `media type range <https://tools.ietf.org/html/rfc7231#appendix-D>`_ and the value + describes it. + + For requests that match multiple keys, only the most specific key is applicable. e.g. ``text/plain`` overrides + ``text/*`` + """ + + description: str | None = None + """A brief description of the request body. This could contain examples of use. + + `CommonMark syntax <https://spec.commonmark.org/>`_ MAY be used for rich text representation. + """ + + required: bool = False + """Determines if the request body is required in the request. + + Defaults to ``False``. + """ diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/response.py b/venv/lib/python3.11/site-packages/litestar/openapi/spec/response.py new file mode 100644 index 0000000..236bc40 --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/response.py @@ -0,0 +1,48 @@ +from __future__ import annotations + +from dataclasses import dataclass +from typing import TYPE_CHECKING + +from litestar.openapi.spec.base import BaseSchemaObject + +if TYPE_CHECKING: + from litestar.openapi.spec.header import OpenAPIHeader + from litestar.openapi.spec.link import Link + from litestar.openapi.spec.media_type import OpenAPIMediaType + from litestar.openapi.spec.reference import Reference + + +__all__ = ("OpenAPIResponse",) + + +@dataclass +class OpenAPIResponse(BaseSchemaObject): + """Describes a single response from an API Operation, including design-time, static ``links`` to operations based on + the response. + """ + + description: str + """**REQUIRED**. A short description of the response. + `CommonMark syntax <https://spec.commonmark.org/>`_ MAY be used for rich text representation. + """ + + headers: dict[str, OpenAPIHeader | Reference] | None = None + """Maps a header name to its definition. + `RFC7230 <https://tools.ietf.org/html/rfc7230#page-22>`_ states header names are case insensitive. + If a response header is defined with the name ``Content-Type``, it SHALL be ignored. + """ + + content: dict[str, OpenAPIMediaType] | None = None + """A map containing descriptions of potential response payloads. The key is a media type or + `media type range <https://tools.ietf.org/html/rfc7231#appendix-D>`_ and the value describes it. + + For responses that match multiple keys, only the most specific key is applicable. e.g. ``text/plain`` overrides + ``text/*`` + """ + + links: dict[str, Link | Reference] | None = None + """A map of operations links that can be followed from the response. + + The key of the map is a short name for the link, following the naming constraints of the names for + `Component Objects <https://spec.openapis.org/oas/v3.1.0#componentsObject>`_. + """ diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/responses.py b/venv/lib/python3.11/site-packages/litestar/openapi/spec/responses.py new file mode 100644 index 0000000..0cff680 --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/responses.py @@ -0,0 +1,44 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING, Dict, Union + +if TYPE_CHECKING: + from litestar.openapi.spec.reference import Reference + from litestar.openapi.spec.response import OpenAPIResponse + +Responses = Dict[str, Union["OpenAPIResponse", "Reference"]] +"""A container for the expected responses of an operation. The container maps a +HTTP response code to the expected response. + +The documentation is not necessarily expected to cover all possible HTTP response codes because they may not be known in +advance. However, documentation is expected to cover a successful operation response and any known errors. + +The ``default`` MAY be used as a default response object for all HTTP codes hat are not covered individually by the +specification. + +The ``Responses Object`` MUST contain at least one response code, and it SHOULD be the response for a successful +operation call. + +Fixed Fields + +default: ``Optional[Union[Response, Reference]]`` + +The documentation of responses other than the ones declared for specific HTTP response codes. Use this field to cover +undeclared responses. A `Reference Object <https://spec.openapis.org/oas/v3.1.0#referenceObject>`_ can link to a +response that the `OpenAPI Object's components/responses <https://spec.openapis.org/oas/v3.1.0#componentsResponses>`_ +section defines. + +Patterned Fields +{httpStatusCode}: ``Optional[Union[Response, Reference]]`` + +Any `HTTP status code <https://spec.openapis.org/oas/v3.1.0#httpCodes>`_ can be used as the property name, but only one +property per code, to describe the expected response for that HTTP status code. + +A `Reference Object <https://spec.openapis.org/oas/v3.1.0#referenceObject>`_ can link to a response that is defined in +the `OpenAPI Object's components/responses <https://spec.openapis.org/oas/v3.1.0#componentsResponses>`_ section. This +field MUST be enclosed in quotation marks (for example, ``200``) for compatibility between JSON and YAML. To define a +range of response codes, this field MAY contain the uppercase wildcard character ``X``. For example, ``2XX`` represents +all response codes between ``[200-299]``. Only the following range definitions are allowed: ``1XX``, ``2XX``, ``3XX``, +``4XX``, and ``5XX``. If a response is defined using an explicit code, the explicit code definition takes precedence +over the range definition for that code. +""" diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/schema.py b/venv/lib/python3.11/site-packages/litestar/openapi/spec/schema.py new file mode 100644 index 0000000..4be2b7c --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/schema.py @@ -0,0 +1,652 @@ +from __future__ import annotations + +from dataclasses import dataclass, fields, is_dataclass +from typing import TYPE_CHECKING, Any, Hashable, Mapping, Sequence + +from litestar.openapi.spec.base import BaseSchemaObject +from litestar.utils.predicates import is_non_string_sequence + +if TYPE_CHECKING: + from litestar.openapi.spec.discriminator import Discriminator + from litestar.openapi.spec.enums import OpenAPIFormat, OpenAPIType + from litestar.openapi.spec.external_documentation import ExternalDocumentation + from litestar.openapi.spec.reference import Reference + from litestar.openapi.spec.xml import XML + from litestar.types import DataclassProtocol + +__all__ = ("Schema", "SchemaDataContainer") + + +def _recursive_hash(value: Hashable | Sequence | Mapping | DataclassProtocol | type[DataclassProtocol]) -> int: + if isinstance(value, Mapping): + hash_value = 0 + for k, v in value.items(): + if k != "examples": + hash_value += hash(k) + hash_value += _recursive_hash(v) + return hash_value + if is_dataclass(value): + hash_value = hash(type(value).__name__) + for field in fields(value): + if field.name != "examples": + hash_value += hash(field.name) + hash_value += _recursive_hash(getattr(value, field.name, None)) + return hash_value + if is_non_string_sequence(value): + return sum(_recursive_hash(v) for v in value) + return hash(value) if isinstance(value, Hashable) else 0 + + +@dataclass +class Schema(BaseSchemaObject): + """The Schema Object allows the definition of input and output data types. These types can be objects, but also + primitives and arrays. This object is a superset of the + `JSON Schema Specification Draft 2020-12 <https://tools.ietf.org/html/draft-bhutton-json-schema-00>`_. + + For more information about the properties, see + `JSON Schema Core <https://tools.ietf.org/html/draft-wright-json-schema-00>`_ and + `JSON Schema Validation <https://tools.ietf.org/html/draft-wright-json-schema-validation-00>`_. + + Unless stated otherwise, the property definitions follow those of JSON Schema and do not add any additional + semantics. Where JSON Schema indicates that behavior is defined by the application (e.g. for annotations), OAS also + defers the definition of semantics to the application consuming the OpenAPI document. + + The following properties are taken directly from the + `JSON Schema Core <https://tools.ietf.org/html/draft-wright-json-schema-00>`_ and follow the same specifications. + """ + + all_of: Sequence[Reference | Schema] | None = None + """This keyword's value MUST be a non-empty array. Each item of the array MUST be a valid JSON Schema. + + An instance validates successfully against this keyword if it validates successfully against all schemas defined by + this keyword's value. + """ + + any_of: Sequence[Reference | Schema] | None = None + """This keyword's value MUST be a non-empty array. Each item of the array MUST be a valid JSON Schema. + + An instance validates successfully against this keyword if it validates successfully against at least one schema + defined by this keyword's value. Note that when annotations are being collected, all subschemas MUST be examined so + that annotations are collected from each subschema that validates successfully. + """ + + one_of: Sequence[Reference | Schema] | None = None + """This keyword's value MUST be a non-empty array. Each item of the array MUST be a valid JSON Schema. + + An instance validates successfully against this keyword if it validates successfully against exactly one schema + defined by this keyword's value. + """ + + schema_not: Reference | Schema | None = None + """This keyword's value MUST be a valid JSON Schema. + + An instance is valid against this keyword if it fails to validate successfully against the schema defined by this + keyword. + """ + + schema_if: Reference | Schema | None = None + """This keyword's value MUST be a valid JSON Schema. + + This validation outcome of this keyword's subschema has no direct effect on the overall validation result. Rather, + it controls which of the "then" or "else" keywords are evaluated. + + Instances that successfully validate against this keyword's subschema MUST also be valid against the subschema + value of the "then" keyword, if present. + + Instances that fail to validate against this keyword's subschema MUST also be valid against the subschema value of + the "else" keyword, if present. + + If annotations (Section 7.7) are being collected, they are collected rom this keyword's subschema in the usual way, + including when the keyword is present without either "then" or "else". + """ + + then: Reference | Schema | None = None + """This keyword's value MUST be a valid JSON Schema. + + When "if" is present, and the instance successfully validates against its subschema, then validation succeeds + against this keyword if the instance also successfully validates against this keyword's subschema. + + This keyword has no effect when "if" is absent, or when the instance fails to validate against its subschema. + Implementations MUST NOT evaluate the instance against this keyword, for either validation or annotation collection + purposes, in such cases. + """ + + schema_else: Reference | Schema | None = None + """This keyword's value MUST be a valid JSON Schema. + + When "if" is present, and the instance fails to validate against its subschema, then validation succeeds against + this keyword if the instance successfully validates against this keyword's subschema. + + This keyword has no effect when "if" is absent, or when the instance successfully validates against its subschema. + Implementations MUST NOT evaluate the instance against this keyword, for either validation or annotation collection + purposes, in such cases. + """ + + dependent_schemas: dict[str, Reference | Schema] | None = None + """This keyword specifies subschemas that are evaluated if the instance is + an object and contains a certain property. + + This keyword's value MUST be an object. Each value in the object MUST be a valid JSON Schema. + + If the object key is a property in the instance, the entire instance must validate against the subschema. Its use is + dependent on the presence of the property. + + Omitting this keyword has the same behavior as an empty object. + """ + + prefix_items: Sequence[Reference | Schema] | None = None + """The value of "prefixItems" MUST be a non-empty array of valid JSON Schemas. + + Validation succeeds if each element of the instance validates against the schema at the same position, if any. + This keyword does not constrain the length of the array. If the array is longer than this keyword's value, this + keyword validates only the prefix of matching length. + + This keyword produces an annotation value which is the largest index to which this keyword applied a subschema. + he value MAY be a boolean true if a subschema was applied to every index of the instance, such as is produced by the + "items" keyword. This annotation affects the behavior of "items" and "unevaluatedItems". + + Omitting this keyword has the same assertion behavior as an empty array. + """ + + items: Reference | Schema | None = None + """The value of "items" MUST be a valid JSON Schema. + + This keyword applies its subschema to all instance elements at indexes greater than the length of the "prefixItems" + array in the same schema object, as reported by the annotation result of that "prefixItems" keyword. If no such + annotation result exists, "items" applies its subschema to all instance array elements. [[CREF11: Note that the + behavior of "items" without "prefixItems" is identical to that of the schema form of "items" in prior drafts. When + "prefixItems" is present, the behavior of "items" is identical to the former "additionalItems" keyword. ]] + + If the "items" subschema is applied to any positions within the instance array, it produces an annotation result of + boolean true, indicating that all remaining array elements have been evaluated against this keyword's subschema. + + Omitting this keyword has the same assertion behavior as an empty schema. + + Implementations MAY choose to implement or optimize this keyword in another way that produces the same effect, such + as by directly checking for the presence and size of a "prefixItems" array. Implementations that do not support + annotation collection MUST do so. + """ + + contains: Reference | Schema | None = None + """The value of this keyword MUST be a valid JSON Schema. + + An array instance is valid against "contains" if at least one of its elements is valid against the given schema. + The subschema MUST be applied to every array element even after the first match has been found, in order to collect + annotations for use by other keywords. This is to ensure that all possible annotations are collected. + + Logically, the validation result of applying the value subschema to each item in the array MUST be ORed with + "false", resulting in an overall validation result. + + This keyword produces an annotation value which is an array of the indexes to which this keyword validates + successfully when applying its subschema, in ascending order. The value MAY be a boolean "true" if the subschema + validates successfully when applied to every index of the instance. The annotation MUST be present if the instance + array to which this keyword's schema applies is empty. + """ + + properties: dict[str, Reference | Schema] | None = None + """The value of "properties" MUST be an object. Each value of this object MUST be a valid JSON Schema. + + Validation succeeds if, for each name that appears in both the instance and as a name within this keyword's value, + the child instance for that name successfully validates against the corresponding schema. + + The annotation result of this keyword is the set of instance property names matched by this keyword. + + Omitting this keyword has the same assertion behavior as an empty object. + """ + + pattern_properties: dict[str, Reference | Schema] | None = None + """The value of "patternProperties" MUST be an object. Each property name of this object SHOULD be a valid + regular expression, according to the ECMA-262 regular expression dialect. Each property value of this object + MUST be a valid JSON Schema. + + Validation succeeds if, for each instance name that matches any regular expressions that appear as a property name + in this keyword's value, the child instance for that name successfully validates against each schema that + corresponds to a matching regular expression. + + The annotation result of this keyword is the set of instance property names matched by this keyword. + + Omitting this keyword has the same assertion behavior as an empty object. + """ + + additional_properties: Reference | Schema | bool | None = None + """The value of "additionalProperties" MUST be a valid JSON Schema. + + The behavior of this keyword depends on the presence and annotation results of "properties" and "patternProperties" + within the same schema object. Validation with "additionalProperties" applies only to the child values of instance + names that do not appear in the annotation results of either "properties" or "patternProperties". + + For all such properties, validation succeeds if the child instance validates against the "additionalProperties" + schema. + + The annotation result of this keyword is the set of instance property names validated by this keyword's subschema. + + Omitting this keyword has the same assertion behavior as an empty schema. + + Implementations MAY choose to implement or optimize this keyword in another way that produces the same effect, such + as by directly checking the names in "properties" and the patterns in "patternProperties" against the instance + property set. Implementations that do not support annotation collection MUST do so. + """ + + property_names: Reference | Schema | None = None + """The value of "propertyNames" MUST be a valid JSON Schema. + + If the instance is an object, this keyword validates if every property name in the instance validates against the + provided schema. Note the property name that the schema is testing will always be a string. + + Omitting this keyword has the same behavior as an empty schema. + """ + + unevaluated_items: Reference | Schema | None = None + """The value of "unevaluatedItems" MUST be a valid JSON Schema. + + The behavior of this keyword depends on the annotation results of adjacent keywords that apply to the instance + location being validated. Specifically, the annotations from "prefixItems" items", and "contains", which can come + from those keywords when they are adjacent to the "unevaluatedItems" keyword. Those three annotations, as well as + "unevaluatedItems", can also result from any and all adjacent in-place applicator (Section 10.2) keywords. This + includes but is not limited to the in-place applicators defined in this document. + + If no relevant annotations are present, the "unevaluatedItems" subschema MUST be applied to all locations in the + array. If a boolean true value is present from any of the relevant annotations, unevaluatedItems" MUST be ignored. + Otherwise, the subschema MUST be applied to any index greater than the largest annotation value for "prefixItems", + which does not appear in any annotation value for + "contains". + + This means that "prefixItems", "items", "contains", and all in-place applicators MUST be evaluated before this + keyword can be evaluated. Authors of extension keywords MUST NOT define an in-place applicator that would need to be + evaluated after this keyword. + + If the "unevaluatedItems" subschema is applied to any positions within the instance array, it produces an annotation + result of boolean true, analogous to the behavior of "items". + + Omitting this keyword has the same assertion behavior as an empty schema. + """ + + unevaluated_properties: Reference | Schema | None = None + """The value of "unevaluatedProperties" MUST be a valid JSON Schema. + + The behavior of this keyword depends on the annotation results of adjacent keywords that apply to the instance + location being validated. Specifically, the annotations from "properties", "patternProperties", and + "additionalProperties", which can come from those keywords when they are adjacent to the "unevaluatedProperties" + keyword. Those three annotations, as well as "unevaluatedProperties", can also result from any and all adjacent + in-place applicator (Section 10.2) keywords. This includes but is not limited to the in-place applicators defined + in this document. + + Validation with "unevaluatedProperties" applies only to the child values of instance names that do not appear in + the "properties", "patternProperties", "additionalProperties", or "unevaluatedProperties" annotation results that + apply to the instance location being validated. + + For all such properties, validation succeeds if the child instance validates against the "unevaluatedProperties" + schema. + + This means that "properties", "patternProperties", "additionalProperties", and all in-place applicators MUST be + evaluated before this keyword can be evaluated. Authors of extension keywords MUST NOT define an in-place + applicator that would need to be evaluated after this keyword. + + The annotation result of this keyword is the set of instance property names validated by this keyword's subschema. + + Omitting this keyword has the same assertion behavior as an empty schema. + + The following properties are taken directly from the + `JSON Schema Validation <https://tools.ietf.org/html/draft-wright-json-schema-validation-00>`_ and follow the same + specifications: + """ + + type: OpenAPIType | Sequence[OpenAPIType] | None = None + """The value of this keyword MUST be either a string or an array. If it is an array, elements of the array MUST be + strings and MUST be unique. + + String values MUST be one of the six primitive types (``"null"``, ``"boolean"``, ``"object"``, ``"array"``, + ``"number"``, and ``"string"``), or ``"integer"`` which matches any number with a zero fractional part. + + An instance validates if and only if the instance is in any of the sets listed for this keyword. + """ + + enum: Sequence[Any] | None = None + """The value of this keyword MUST be an array. This array SHOULD have at least one element. Elements in the array + SHOULD be unique. + + An instance validates successfully against this keyword if its value is equal to one of the elements in this + keyword's array value. + + Elements in the array might be of any type, including null. + """ + + const: Any | None = None + """The value of this keyword MAY be of any type, including null. + + Use of this keyword is functionally equivalent to an "enum" (Section 6.1.2) with a single value. + + An instance validates successfully against this keyword if its value is equal to the value of the keyword. + """ + + multiple_of: float | None = None + """The value of "multipleOf" MUST be a number, strictly greater than 0. + + A numeric instance is only valid if division by this keyword's value results in an integer. + """ + + maximum: float | None = None + """The value of "maximum" MUST be a number, representing an inclusive upper limit for a numeric instance. + + If the instance is a number, then this keyword validates only if the instance is less than or exactly equal to + "maximum". + """ + + exclusive_maximum: float | None = None + """The value of "exclusiveMaximum" MUST be a number, representing an exclusive upper limit for a numeric instance. + + If the instance is a number, then the instance is valid only if it has a value strictly less than (not equal to) + "exclusiveMaximum". + """ + + minimum: float | None = None + """The value of "minimum" MUST be a number, representing an inclusive lower limit for a numeric instance. + + If the instance is a number, then this keyword validates only if the instance is greater than or exactly equal to + "minimum". + """ + + exclusive_minimum: float | None = None + """The value of "exclusiveMinimum" MUST be a number, representing an exclusive lower limit for a numeric instance. + + If the instance is a number, then the instance is valid only if it has a value strictly greater than (not equal to) + "exclusiveMinimum". + """ + + max_length: int | None = None + """The value of this keyword MUST be a non-negative integer. + + A string instance is valid against this keyword if its length is less than, or equal to, the value of this keyword. + + The length of a string instance is defined as the number of its characters as defined by :rfc:`8259`. + """ + + min_length: int | None = None + """The value of this keyword MUST be a non-negative integer. + + A string instance is valid against this keyword if its length is greater than, or equal to, the value of this + keyword. + + The length of a string instance is defined as the number of its characters as defined by :rfc:`8259`. + + Omitting this keyword has the same behavior as a value of 0. + """ + + pattern: str | None = None + """The value of this keyword MUST be a string. This string SHOULD be a valid regular expression, according to the + ECMA-262 regular expression dialect. + + A string instance is considered valid if the regular expression matches the instance successfully. Recall: regular + expressions are not implicitly anchored. + """ + + max_items: int | None = None + """The value of this keyword MUST be a non-negative integer. + + An array instance is valid against "maxItems" if its size is less than, or equal to, the value of this keyword. + """ + + min_items: int | None = None + """The value of this keyword MUST be a non-negative integer. + + An array instance is valid against "minItems" if its size is greater than, or equal to, the value of this keyword. + + Omitting this keyword has the same behavior as a value of 0. + """ + + unique_items: bool | None = None + """The value of this keyword MUST be a boolean. + + If this keyword has boolean value false, the instance validates successfully. If it has boolean value true, the + instance validates successfully if all of its elements are unique. + + Omitting this keyword has the same behavior as a value of false. + """ + + max_contains: int | None = None + """The value of this keyword MUST be a non-negative integer. + + If "contains" is not present within the same schema object, then this keyword has no effect. + + An instance array is valid against "maxContains" in two ways, depending on the form of the annotation result of an + adjacent "contains" [json-schema] keyword. The first way is if the annotation result is an array and the length of + that array is less than or equal to the "maxContains" value. The second way is if the annotation result is a + boolean "true" and the instance array length is less than r equal to the "maxContains" value. + """ + + min_contains: int | None = None + """The value of this keyword MUST be a non-negative integer. + + If "contains" is not present within the same schema object, then this keyword has no effect. + + An instance array is valid against "minContains" in two ways, depending on the form of the annotation result of an + adjacent "contains" [json-schema] keyword. The first way is if the annotation result is an array and the length of + that array is greater than or equal to the "minContains" value. The second way is if the annotation result is a + boolean "true" and the instance array length is greater than or equal to the "minContains" value. + + A value of 0 is allowed, but is only useful for setting a range of occurrences from 0 to the value of "maxContains". + A value of 0 with no "maxContains" causes "contains" to always pass validation. + + Omitting this keyword has the same behavior as a value of 1. + """ + + max_properties: int | None = None + """The value of this keyword MUST be a non-negative integer. + + An object instance is valid against "maxProperties" if its number of properties is less than, or equal to, the value + of this keyword. + """ + + min_properties: int | None = None + """The value of this keyword MUST be a non-negative integer. + + An object instance is valid against "minProperties" if its number of properties is greater than, or equal to, the + value of this keyword. + + Omitting this keyword has the same behavior as a value of 0. + """ + + required: Sequence[str] | None = None + """The value of this keyword MUST be an array. Elements of this array, if any, MUST be strings, and MUST be unique. + + An object instance is valid against this keyword if every item in the rray is the name of a property in the instance. + + Omitting this keyword has the same behavior as an empty array. + """ + + dependent_required: dict[str, Sequence[str]] | None = None + """The value of this keyword MUST be an object. Properties in this object, f any, MUST be arrays. Elements in each + array, if any, MUST be strings, and MUST be unique. + + This keyword specifies properties that are required if a specific other property is present. Their requirement is + dependent on the presence of the other property. + + Validation succeeds if, for each name that appears in both the instance and as a name within this keyword's value, + every item in the corresponding array is also the name of a property in the instance. + + Omitting this keyword has the same behavior as an empty object. + """ + + format: OpenAPIFormat | None = None + """From OpenAPI: + + See `Data Type Formats <https://spec.openapis.org/oas/v3.1.0#dataTypeFormat>`_ for further details. While relying on + JSON Schema's defined formats, the OAS offers a few additional predefined formats. + + From JSON Schema: + + Structural validation alone may be insufficient to allow an application to correctly utilize certain values. + The "format" annotation keyword is defined to allow schema authors to convey semantic information for a fixed subset + of values which are accurately described by authoritative resources, be they RFCs or other external specifications. + + The value of this keyword is called a format attribute. It MUST be a string. A format attribute can generally only + validate a given set of instance types. If the type of the instance to validate is not in this set, validation for + this format attribute and instance SHOULD succeed. All format attributes defined in this section apply to strings, + but a format attribute can be specified to apply to any instance types defined in the data model defined in the core + JSON Schema. [json-schema] [[CREF1: Note that the "type" keyword in this specification defines an "integer" type + which is not part of the data model. Therefore a format attribute can be limited to numbers, but not specifically to + integers. However, a numeric format can be used alongside the "type" keyword with a value of "integer", or could be + explicitly defined to always pass if the number is not an integer, which produces essentially the same behavior as + only applying to integers. ]] + """ + + content_encoding: str | None = None + """If the instance value is a string, this property defines that the string SHOULD be interpreted as binary data and + decoded using the encoding named by this property. + + Possible values indicating base 16, 32, and 64 encodings with several variations are listed in :rfc:`4648`. + Additionally, sections 6.7 and 6.8 of :rfc:`2045` provide encodings used in MIME. As "base64" is defined in both + RFCs, the definition from :rfc:`4648` SHOULD be assumed unless the string is specifically intended for use in a + MIME context. Note that all of these encodings result in strings consisting only of 7-bit ASCII characters. + therefore, this keyword has no meaning for strings containing characters outside of that range. + + If this keyword is absent, but "contentMediaType" is present, this indicates that the encoding is the identity + encoding, meaning that no transformation was needed in order to represent the content in a UTF-8 string. + """ + + content_media_type: str | None = None + """If the instance is a string, this property indicates the media type of the contents of the string. If + "contentEncoding" is present, this property describes the decoded string. + + The value of this property MUST be a string, which MUST be a media type, as defined by :rfc:`2046` + """ + + content_schema: Reference | Schema | None = None + """If the instance is a string, and if "contentMediaType" is present, this property contains a schema which + describes the structure of the string. + + This keyword MAY be used with any media type that can be mapped into JSON Schema's data model. + + The value of this property MUST be a valid JSON schema. It SHOULD be ignored if "contentMediaType" is not present. + """ + + title: str | None = None + """The value of "title" MUST be a string. + + The title can be used to decorate a user interface with information about the data produced by this user interface. + A title will preferably be short. + """ + + description: str | None = None + """From OpenAPI: + + `CommonMark syntax <https://spec.commonmark.org/>`_ MAY be used for rich text representation. + + From JSON Schema: + The value "description" MUST be a string. + + The description can be used to decorate a user interface with information about the data produced by this user + interface. A description will provide explanation about the purpose of the instance described by this schema. + """ + + default: Any | None = None + """There are no restrictions placed on the value of this keyword. When multiple occurrences of this keyword are + applicable to a single sub-instance, implementations SHOULD remove duplicates. + + This keyword can be used to supply a default JSON value associated with a particular schema. It is RECOMMENDED that + a default value be valid against the associated schema. + """ + + deprecated: bool | None = None + """The value of this keyword MUST be a boolean. When multiple occurrences of this keyword are applicable to a + single sub-instance, applications SHOULD consider the instance location to be deprecated if any occurrence specifies + a true value. + + If "deprecated" has a value of boolean true, it indicates that applications SHOULD refrain from usage of the + declared property. It MAY mean the property is going to be removed in the future. + + A root schema containing "deprecated" with a value of true indicates that the entire resource being described MAY be + removed in the future. + + The "deprecated" keyword applies to each instance location to which the schema object containing the keyword + successfully applies. This can result in scenarios where every array item or object property is deprecated even + though the containing array or object is not. + + Omitting this keyword has the same behavior as a value of false. + """ + + read_only: bool | None = None + """The value of "readOnly" MUST be a boolean. When multiple occurrences of this keyword are applicable to a single + sub-instance, the resulting behavior SHOULD be as for a true value if any occurrence specifies a true value, and + SHOULD be as for a false value otherwise. + + If "readOnly" has a value of boolean true, it indicates that the value of the instance is managed exclusively by + the owning authority, and attempts by an application to modify the value of this property are expected to be ignored + or rejected by that owning authority. + + An instance document that is marked as "readOnly" for the entire document MAY be ignored if sent to the owning + authority, or MAY result in an error, at the authority's discretion. + + For example, "readOnly" would be used to mark a database-generated serial number as read-only, while "writeOnly" + would be used to mark a password input field. + + This keyword can be used to assist in user interface instance generation. In particular, an application MAY choose + to use a widget that hides input values as they are typed for write-only fields. + + Omitting these keywords has the same behavior as values of false. + """ + + write_only: bool | None = None + """The value of "writeOnly" MUST be a boolean. When multiple occurrences of this keyword are applicable to a + single sub-instance, the resulting behavior SHOULD be as for a true value if any occurrence specifies a true value, + and SHOULD be as for a false value otherwise. + + If "writeOnly" has a value of boolean true, it indicates that the value is never present when the instance is + retrieved from the owning authority. It can be present when sent to the owning authority to update or create the + document (or the resource it represents), but it will not be included in any updated or newly created version of the + instance. + + An instance document that is marked as "writeOnly" for the entire document MAY be returned as a blank document of + some sort, or MAY produce an error upon retrieval, or have the retrieval request ignored, at the authority's + discretion. + + For example, "readOnly" would be used to mark a database-generated serial number as read-only, while "writeOnly" + would be used to mark a password input field. + + This keyword can be used to assist in user interface instance generation. In particular, an application MAY choose + to use a widget that hides input values as they are typed for write-only fields. + + Omitting these keywords has the same behavior as values of false. + """ + + examples: list[Any] | None = None + """The value of this must be an array containing the example values.""" + + discriminator: Discriminator | None = None + """Adds support for polymorphism. + + The discriminator is an object name that is used to differentiate between other schemas which may satisfy the + payload description. See `Composition and Inheritance <https://spec.openapis.org/oas/v3.1.0#schemaComposition>`_ + for more details. + """ + + xml: XML | None = None + """This MAY be used only on properties schemas. + + It has no effect on root schemas. Adds additional metadata to describe the XML representation of this property. + """ + + external_docs: ExternalDocumentation | None = None + """Additional external documentation for this schema.""" + + example: Any | None = None + """A free-form property to include an example of an instance for this schema. To represent examples that cannot be + naturally represented in JSON or YAML, a string value can be used to contain the example with escaping where + necessary. + + Deprecated: The example property has been deprecated in favor of the JSON Schema examples keyword. Use of example is + discouraged, and later versions of this specification may remove it. + """ + + def __hash__(self) -> int: + return _recursive_hash(self) + + +@dataclass +class SchemaDataContainer(Schema): + """Special class that allows using python data containers, e.g. dataclasses or pydantic models, to represent a + schema + """ + + data_container: Any = None + """A data container instance that will be used to generate the schema.""" diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/security_requirement.py b/venv/lib/python3.11/site-packages/litestar/openapi/spec/security_requirement.py new file mode 100644 index 0000000..e3d1394 --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/security_requirement.py @@ -0,0 +1,30 @@ +from __future__ import annotations + +from typing import Dict, List + +SecurityRequirement = Dict[str, List[str]] +"""Lists the required security schemes to execute this operation. The name used for each property MUST correspond to a +security scheme declared in the. + +`Security Schemes <https://spec.openapis.org/oas/v3.1.0#componentsSecuritySchemes>`_ under the +`Components Object <https://spec.openapis.org/oas/v3.1.0#componentsObject>`_. + +Security Requirement Objects that contain multiple schemes require that all schemes MUST be satisfied for a request to +be authorized. This enables support for scenarios where multiple query parameters or HTTP headers are required to convey +security information. + +When a list of Security Requirement Objects is defined on the +`OpenAPI Object <https://spec.openapis.org/oas/v3.1.0#oasObject>`_ or +`Operation Object <https://spec.openapis.org/oas/v3.1.0#operationObject>`_, only one of the Security Requirement +Objects in the list needs to be satisfied to authorize the request. + +Patterned Fields + +{name}: ``List[str]`` +Each name MUST correspond to a security scheme which is declared +in the `Security Schemes <https://spec.openapis.org/oas/v3.1.0#componentsSecuritySchemes>`_ under the +`Components Object <https://spec.openapis.org/oas/v3.1.0#componentsObject>`_. if the security scheme is of type +``"oauth2"`` or ``"openIdConnect"``, then the value is a list of scope names required for the execution, and the list +MAY be empty if authorization does not require a specified scope. For other security scheme types, the array MAY contain +a list of role names which are required for the execution,but are not otherwise defined or exchanged in-band. +""" diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/security_scheme.py b/venv/lib/python3.11/site-packages/litestar/openapi/spec/security_scheme.py new file mode 100644 index 0000000..badc77e --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/security_scheme.py @@ -0,0 +1,69 @@ +from __future__ import annotations + +from dataclasses import dataclass +from typing import TYPE_CHECKING, Literal + +from litestar.openapi.spec.base import BaseSchemaObject + +if TYPE_CHECKING: + from litestar.openapi.spec.oauth_flows import OAuthFlows + +__all__ = ("SecurityScheme",) + + +@dataclass +class SecurityScheme(BaseSchemaObject): + """Defines a security scheme that can be used by the operations. + + Supported schemes are HTTP authentication, an API key (either as a header, a cookie parameter or as a query + parameter), mutual TLS (use of a client certificate), OAuth2's common flows (implicit, password, client credentials + and authorization code) as defined in :rfc`6749`, and + `OpenID Connect Discovery <https://tools.ietf.org/html/draft-ietf-oauth-discovery-06>`_. + + Please note that as of 2020, the implicit flow is about to be deprecated by + `OAuth 2.0 Security Best Current Practice <https://tools.ietf.org/html/draft-ietf-oauth-security-topics>`_. + Recommended for most use case is Authorization Code Grant flow with PKCE. + """ + + type: Literal["apiKey", "http", "mutualTLS", "oauth2", "openIdConnect"] + """**REQUIRED**. The type of the security scheme.""" + + description: str | None = None + """A description for security scheme. + + `CommonMark syntax <https://spec.commonmark.org/>`_ MAY be used for rich text representation. + """ + + name: str | None = None + """ + **REQUIRED** for ``apiKey``. The name of the header, query or cookie parameter to be used. + """ + + security_scheme_in: Literal["query", "header", "cookie"] | None = None + """ + **REQUIRED** for ``apiKey``. The location of the API key. + """ + + scheme: str | None = None + """ + **REQUIRED** for ``http``. The name of the HTTP Authorization scheme to be used in the + authorization header as defined in :rfc:`7235`. + + The values used SHOULD be registered in the + `IANA Authentication Scheme registry <https://www.iana.org/assignments/http-authschemes/http-authschemes.xhtml>`_ + """ + + bearer_format: str | None = None + """A hint to the client to identify how the bearer token is formatted. + + Bearer tokens are usually generated by an authorization server, so this information is primarily for documentation + purposes. + """ + + flows: OAuthFlows | None = None + """**REQUIRED** for ``oauth2``. An object containing configuration information for the flow types supported.""" + + open_id_connect_url: str | None = None + """**REQUIRED** for ``openIdConnect``. OpenId Connect URL to discover OAuth2 configuration values. This MUST be in + the form of a URL. The OpenID Connect standard requires the use of TLS. + """ diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/server.py b/venv/lib/python3.11/site-packages/litestar/openapi/spec/server.py new file mode 100644 index 0000000..2c12fcf --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/server.py @@ -0,0 +1,34 @@ +from __future__ import annotations + +from dataclasses import dataclass +from typing import TYPE_CHECKING + +from litestar.openapi.spec.base import BaseSchemaObject + +if TYPE_CHECKING: + from litestar.openapi.spec.server_variable import ServerVariable + +__all__ = ("Server",) + + +@dataclass +class Server(BaseSchemaObject): + """An object representing a Server.""" + + url: str + """ + **REQUIRED**. A URL to the target host. + + This URL supports Server Variables and MAY be relative, to indicate that the host location is relative to the + location where the OpenAPI document is being served. Variable substitutions will be made when a variable is named in + ``{brackets}``. + """ + + description: str | None = None + """An optional string describing the host designated by the URL. + + `CommonMark syntax <https://spec.commonmark.org/>`_ MAY be used for rich text representation. + """ + + variables: dict[str, ServerVariable] | None = None + """A map between a variable name and its value. The value is used for substitution in the server's URL template.""" diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/server_variable.py b/venv/lib/python3.11/site-packages/litestar/openapi/spec/server_variable.py new file mode 100644 index 0000000..c59c542 --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/server_variable.py @@ -0,0 +1,32 @@ +from __future__ import annotations + +from dataclasses import dataclass + +from litestar.openapi.spec.base import BaseSchemaObject + +__all__ = ("ServerVariable",) + + +@dataclass +class ServerVariable(BaseSchemaObject): + """An object representing a Server Variable for server URL template substitution.""" + + default: str + """**REQUIRED**. The default value to use for substitution, which SHALL be sent if an alternate value is _not_ + supplied. Note this behavior is different than the + `Schema Object's <https://spec.openapis.org/oas/v3.1.0#schemaObject>`_ treatment of default values, because in those + cases parameter values are optional. If the `enum <https://spec.openapis.org/oas/v3.1.0#serverVariableEnum>`_ is + defined, the value MUST exist in the enum's values. + """ + + enum: list[str] | None = None + """An enumeration of string values to be used if the substitution options are from a limited set. + + The array SHOULD NOT be empty. + """ + + description: str | None = None + """An optional description for the server variable. + + `CommonMark syntax <https://spec.commonmark.org/>`_ MAY be used for rich text representation. + """ diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/tag.py b/venv/lib/python3.11/site-packages/litestar/openapi/spec/tag.py new file mode 100644 index 0000000..c3e6374 --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/tag.py @@ -0,0 +1,32 @@ +from __future__ import annotations + +from dataclasses import dataclass +from typing import TYPE_CHECKING + +from litestar.openapi.spec.base import BaseSchemaObject + +if TYPE_CHECKING: + from litestar.openapi.spec.external_documentation import ExternalDocumentation + +__all__ = ("Tag",) + + +@dataclass +class Tag(BaseSchemaObject): + """Adds metadata to a single tag that is used by the + `Operation Object <https://spec.openapis.org/oas/v3.1.0#operationObject>`_. + + It is not mandatory to have a Tag Object per tag defined in the Operation Object instances. + """ + + name: str + """**REQUIRED**. The name of the tag.""" + + description: str | None = None + """A short description for the tag. + + `CommonMark syntax <https://spec.commonmark.org/>`_ MAY be used for rich text representation. + """ + + external_docs: ExternalDocumentation | None = None + """Additional external documentation for this tag.""" diff --git a/venv/lib/python3.11/site-packages/litestar/openapi/spec/xml.py b/venv/lib/python3.11/site-packages/litestar/openapi/spec/xml.py new file mode 100644 index 0000000..6030998 --- /dev/null +++ b/venv/lib/python3.11/site-packages/litestar/openapi/spec/xml.py @@ -0,0 +1,44 @@ +from __future__ import annotations + +from dataclasses import dataclass + +from litestar.openapi.spec.base import BaseSchemaObject + +__all__ = ("XML",) + + +@dataclass() +class XML(BaseSchemaObject): + """A metadata object that allows for more fine-tuned XML model definitions. + + When using arrays, XML element names are *not* inferred (for singular/plural forms) and the ``name`` property SHOULD + be used to add that information. See examples for expected behavior. + """ + + name: str | None = None + """ + Replaces the name of the element/attribute used for the described schema property. When defined within ``items``, it + will affect the name of the individual XML elements within the list. When defined alongside ``type`` being ``array`` + (outside the ``items``), it will affect the wrapping element and only if ``wrapped`` is ``True``. If ``wrapped`` is + ``False``, it will be ignored. + """ + + namespace: str | None = None + """The URI of the namespace definition. Value MUST be in the form of an absolute URI.""" + + prefix: str | None = None + """The prefix to be used for the + `xmlName <https://spec.openapis.org/oas/v3.1.0#xmlName>`_ + """ + + attribute: bool = False + """Declares whether the property definition translates to an attribute instead of an element. Default value is + ``False``. + """ + + wrapped: bool = False + """ + MAY be used only for an array definition. Signifies whether the array is wrapped (for example, + ``<books><book/><book/></books>``) or unwrapped (``<book/><book/>``). Default value is ``False``. The definition + takes effect only when defined alongside ``type`` being ``array`` (outside the ``items``). + """ |