Created
October 18, 2021 04:06
-
-
Save adriangb/d3ea3416906af9cd11287770b1d88bdf to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from __future__ import annotations | |
from dataclasses import dataclass as dataclass | |
from dataclasses import field | |
from typing import Any, Dict, List, Literal, Mapping, Optional, Union | |
ParameterLocations = Literal["header", "path", "query", "cookie"] | |
PathParamStyles = Literal["simple", "label", "matrix"] | |
QueryParamStyles = Literal["form", "spaceDelimited", "pipeDelimited", "deepObject"] | |
HeaderParamStyles = Literal["simple"] | |
CookieParamStyles = Literal["form"] | |
FormDataStyles = QueryParamStyles | |
@dataclass | |
class Contact: | |
name: Optional[str] = None | |
url: Optional[str] = None | |
email: Optional[str] = None | |
@dataclass | |
class License: | |
name: str | |
url: Optional[str] = None | |
@dataclass | |
class Info: | |
title: str | |
version: str | |
description: Optional[str] = None | |
termsOfService: Optional[str] = None | |
contact: Optional[Contact] = None | |
license: Optional[License] = None | |
@dataclass | |
class ServerVariable: | |
default: str | |
enum: Optional[List[str]] = None | |
description: Optional[str] = None | |
@dataclass | |
class Server: | |
url: Union[str, str] | |
description: Optional[str] = None | |
variables: Optional[Dict[str, ServerVariable]] = None | |
@dataclass | |
class Reference: | |
ref: str | |
@dataclass | |
class Discriminator: | |
propertyName: str | |
mapping: Optional[Dict[str, str]] = None | |
@dataclass | |
class XML: | |
name: Optional[str] = None | |
namespace: Optional[str] = None | |
prefix: Optional[str] = None | |
attribute: Optional[bool] = None | |
wrapped: Optional[bool] = None | |
@dataclass | |
class ExternalDocumentation: | |
url: str | |
description: Optional[str] = None | |
@dataclass | |
class Schema: | |
ref: Optional[str] = field(default=None) | |
title: Optional[str] = None | |
multipleOf: Optional[float] = None | |
maximum: Optional[float] = None | |
exclusiveMaximum: Optional[float] = None | |
minimum: Optional[float] = None | |
exclusiveMinimum: Optional[float] = None | |
maxLength: Optional[int] = field(default=None) | |
minLength: Optional[int] = field(default=None) | |
pattern: Optional[str] = None | |
maxItems: Optional[int] = field(default=None) | |
minItems: Optional[int] = field(default=None) | |
uniqueItems: Optional[bool] = None | |
maxProperties: Optional[int] = field(default=None) | |
minProperties: Optional[int] = field(default=None) | |
required: Optional[List[str]] = None | |
enum: Optional[List[Any]] = None | |
type: Optional[str] = None | |
allOf: Optional[List[Schema]] = None | |
oneOf: Optional[List[Schema]] = None | |
anyOf: Optional[List[Schema]] = None | |
not_: Optional[Schema] = field(default=None) | |
items: Optional[Schema] = None | |
properties: Optional[Dict[str, Schema]] = None | |
additionalProperties: Optional[Union[Schema, Reference, bool]] = None | |
description: Optional[str] = None | |
format: Optional[str] = None | |
default: Any = None | |
nullable: Optional[bool] = None | |
discriminator: Optional[Discriminator] = None | |
readOnly: Optional[bool] = None | |
writeOnly: Optional[bool] = None | |
xml: Optional[XML] = None | |
externalDocs: Optional[ExternalDocumentation] = None | |
deprecated: Optional[bool] = None | |
@dataclass | |
class Example: | |
summary: Optional[str] = None | |
description: Optional[str] = None | |
value: Any = None | |
external_value: Optional[str] = field(default=None) | |
@dataclass | |
class Encoding: | |
contentType: Optional[str] = None | |
headers: Optional[Dict[str, Union[Header, Reference]]] = None | |
style: Optional[str] = None | |
explode: Optional[bool] = None | |
allowReserved: Optional[bool] = None | |
@dataclass | |
class MediaType: | |
schema_: Optional[Union[Schema, Reference]] = None | |
examples: Optional[Dict[str, Union[Example, Reference]]] = None | |
encoding: Optional[Dict[str, Encoding]] = None | |
@dataclass | |
class ParameterBase: | |
description: Optional[str] = None | |
required: Optional[bool] = None | |
deprecated: Optional[bool] = None | |
# Serialization rules for simple scenarios | |
style: Optional[str] = None | |
explode: Optional[bool] = None | |
allowReserved: Optional[bool] = None | |
schema_: Optional[Union[Schema, Reference]] = None | |
examples: Optional[Dict[str, Union[Example, Reference]]] = None | |
# Serialization rules for more complex scenarios | |
content: Optional[Dict[str, MediaType]] = None | |
@dataclass | |
class ConcreteParameter: | |
name: str | |
in_: ParameterLocations | |
@dataclass | |
class Header(ParameterBase, ConcreteParameter): | |
in_: Literal["header"] = "header" | |
style: HeaderParamStyles = "simple" | |
explode: bool = False | |
@dataclass | |
class Query(ParameterBase, ConcreteParameter): | |
in_: Literal["header"] = "header" | |
style: QueryParamStyles = "form" | |
explode: bool = True | |
@dataclass | |
class Path(ParameterBase, ConcreteParameter): | |
in_: Literal["path"] = "path" | |
style: PathParamStyles = "simple" | |
explode: bool = False | |
required: Literal[True] = True | |
@dataclass | |
class Cookie(ParameterBase, ConcreteParameter): | |
in_: Literal["cookie"] = "cookie" | |
style: CookieParamStyles = "form" | |
explode: bool = True | |
Parameter = Union[Query, Header, Cookie, Path] | |
@dataclass | |
class RequestBody: | |
content: Dict[str, MediaType] | |
description: Optional[str] = None | |
required: Optional[bool] = None | |
@dataclass | |
class Link: | |
operationRef: Optional[str] = None | |
operationId: Optional[str] = None | |
parameters: Optional[Dict[str, Union[str]]] = None | |
requestBody: Optional[Union[str]] = None | |
description: Optional[str] = None | |
server: Optional[Server] = None | |
@dataclass | |
class Response: | |
description: str | |
headers: Optional[Dict[str, Union[Header, Reference]]] = None | |
content: Optional[Dict[str, MediaType]] = None | |
links: Optional[Dict[str, Union[Link, Reference]]] = None | |
@dataclass | |
class Operation: | |
responses: Dict[str, Response] | |
tags: Optional[List[str]] = None | |
summary: Optional[str] = None | |
description: Optional[str] = None | |
externalDocs: Optional[ExternalDocumentation] = None | |
operationId: Optional[str] = None | |
parameters: Optional[List[Union[Parameter, Reference]]] = None | |
requestBody: Optional[Union[RequestBody, Reference]] = None | |
# Using Any for Specification Extensions | |
callbacks: Optional[Dict[str, Union[Dict[str, PathItem], Reference]]] = None | |
deprecated: Optional[bool] = None | |
security: Optional[List[Dict[str, List[str]]]] = None | |
servers: Optional[List[Server]] = None | |
@dataclass | |
class PathItem: | |
ref: Optional[str] = None | |
summary: Optional[str] = None | |
description: Optional[str] = None | |
get: Optional[Operation] = None | |
put: Optional[Operation] = None | |
post: Optional[Operation] = None | |
delete: Optional[Operation] = None | |
options: Optional[Operation] = None | |
head: Optional[Operation] = None | |
patch: Optional[Operation] = None | |
trace: Optional[Operation] = None | |
servers: Optional[List[Server]] = None | |
parameters: Optional[List[Union[Parameter, Reference]]] = None | |
SecuritySchemeName = Literal["apiKey", "http", "oauth2", "openIdConnect"] | |
class SecurityBase: | |
type: SecuritySchemeName | |
description: Optional[str] = None | |
APIKeyLocation = Literal["query", "header", "cookie"] | |
@dataclass | |
class APIKey(SecurityBase): | |
name: str | |
in_: APIKeyLocation | |
type: Literal["apiKey"] = "apiKey" | |
@dataclass | |
class HTTPBase(SecurityBase): | |
scheme: str | |
type: Literal["http"] = "http" | |
@dataclass | |
class HTTPBearer(HTTPBase): | |
scheme = "bearer" | |
bearerFormat: Optional[str] = None | |
@dataclass | |
class OAuthFlow: | |
refreshUrl: Optional[str] = None | |
scopes: Optional[Mapping[str, str]] = field(default_factory=dict) # type: ignore | |
@dataclass | |
class OAuthFlowImplicitBase: | |
authorizationUrl: str | |
@dataclass | |
class OAuthFlowImplicit(OAuthFlow, OAuthFlowImplicitBase): | |
... | |
@dataclass | |
class OAuthFlowPasswordBase: | |
tokenUrl: str | |
@dataclass | |
class OAuthFlowPassword(OAuthFlow, OAuthFlowPasswordBase): | |
... | |
@dataclass | |
class OAuthFlowClientCredentialsBase: | |
tokenUrl: str | |
@dataclass | |
class OAuthFlowClientCredentials(OAuthFlow, OAuthFlowClientCredentialsBase): | |
... | |
@dataclass | |
class OAuthFlowAuthorizationCodeBase: | |
authorizationUrl: str | |
tokenUrl: str | |
@dataclass | |
class OAuthFlowAuthorizationCode(OAuthFlow, OAuthFlowAuthorizationCodeBase): | |
... | |
@dataclass | |
class OAuthFlows: | |
implicit: Optional[OAuthFlowImplicit] = None | |
password: Optional[OAuthFlowPassword] = None | |
clientCredentials: Optional[OAuthFlowClientCredentials] = None | |
authorizationCode: Optional[OAuthFlowAuthorizationCode] = None | |
@dataclass | |
class OAuth2(SecurityBase): | |
flows: OAuthFlows | |
type: Literal["oauth2"] = "oauth2" | |
@dataclass | |
class OpenIdConnect(SecurityBase): | |
openIdConnectUrl: str | |
type: Literal["openIdConnect"] = "openIdConnect" | |
SecurityScheme = Union[APIKey, HTTPBase, OAuth2, OpenIdConnect, HTTPBearer] | |
@dataclass | |
class Components: | |
schemas: Optional[Dict[str, Union[Schema, Reference]]] = None | |
responses: Optional[Dict[str, Union[Response, Reference]]] = None | |
parameters: Optional[Dict[str, Union[Parameter, Reference]]] = None | |
examples: Optional[Dict[str, Union[Example, Reference]]] = None | |
requestBodies: Optional[Dict[str, Union[RequestBody, Reference]]] = None | |
headers: Optional[Dict[str, Union[Header, Reference]]] = None | |
securitySchemes: Optional[Dict[str, Union[SecurityScheme, Reference]]] = None | |
links: Optional[Dict[str, Union[Link, Reference]]] = None | |
# Using Any for Specification Extensions | |
callbacks: Optional[Dict[str, Union[Dict[str, PathItem], Reference]]] = None | |
@dataclass | |
class Tag: | |
name: str | |
description: Optional[str] = None | |
externalDocs: Optional[ExternalDocumentation] = None | |
@dataclass | |
class OpenAPI: | |
openapi: str | |
info: Info | |
paths: Dict[str, Union[PathItem]] = field(default_factory=dict) | |
servers: Optional[List[Server]] = None | |
# Using Any for Specification Extensions | |
components: Optional[Components] = None | |
security: Optional[List[Dict[str, List[str]]]] = None | |
tags: Optional[List[Tag]] = None | |
externalDocs: Optional[ExternalDocumentation] = None | |
if __name__ == "__main__": | |
from time import time | |
from apischema import serialize | |
data = OpenAPI(info=Info(title="A", version="1"), openapi="1", paths={}) | |
start = time() | |
serialize(OpenAPI, data) | |
print(f"apischema took {time()-start:e} sec on first go") | |
start = time() | |
serialize(OpenAPI, data) | |
print(f"apischema took {time()-start:e} sec on second go") | |
from fastapi.openapi import models as pydantic_models | |
data2 = pydantic_models.OpenAPI(info=pydantic_models.Info(title="A", version="1"), openapi="1", paths={}) | |
start = time() | |
data2.dict() | |
print(f"pydantic took {time()-start:e} sec on first go") | |
start = time() | |
data2.dict() | |
print(f"pydantic took {time()-start:e} sec on second go") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment