Coverage for nexios\openapi\models.py: 99%
256 statements
« prev ^ index » next coverage.py v7.8.0, created at 2025-05-21 20:31 +0100
« prev ^ index » next coverage.py v7.8.0, created at 2025-05-21 20:31 +0100
1# type: ignore[overide]
2from __future__ import annotations
4from typing import Any, Dict, List, Mapping, Optional, Union
6from pydantic import ConfigDict, BaseModel, Field
7from pydantic.networks import AnyUrl
9try:
10 import email_validator # type: ignore # noqa: F401
11 from pydantic import EmailStr
12except ImportError: # pragma: no cover
13 EmailStr = str # type: ignore
16from typing import Annotated, Literal
18ParameterLocations = Literal["header", "path", "query", "cookie"]
19PathParamStyles = Literal["simple", "label", "matrix"]
20QueryParamStyles = Literal["form", "spaceDelimited", "pipeDelimited", "deepObject"]
21HeaderParamStyles = Literal["simple"]
22CookieParamStyles = Literal["form"]
23FormDataStyles = QueryParamStyles
25Extension = Union[Dict[str, Any], List[Any], str, int, float, bool, None]
28class Contact(BaseModel):
29 name: Optional[str] = None
30 url: Optional[AnyUrl] = None
31 email: Optional[EmailStr] = None
34class License(BaseModel):
35 name: str
36 url: Optional[AnyUrl] = None
39class Info(BaseModel):
40 title: str
41 version: str
42 description: Optional[str] = None
43 termsOfService: Optional[str] = None
44 contact: Optional[Contact] = None
45 license: Optional[License] = None
47 model_config = ConfigDict(extra="allow")
50# for extensions
53class ServerVariable(BaseModel):
54 default: str
55 enum: Optional[List[str]] = None
56 description: Optional[str] = None
59class Server(BaseModel):
60 url: Union[AnyUrl, str]
61 description: Optional[str] = None
62 variables: Optional[Dict[str, ServerVariable]] = None
65class Reference(BaseModel):
66 ref: Annotated[str, Field(alias="$ref")]
69class Discriminator(BaseModel):
70 propertyName: str
71 mapping: Optional[Dict[str, str]] = None
74class XML(BaseModel):
75 name: Optional[str] = None
76 namespace: Optional[str] = None
77 prefix: Optional[str] = None
78 attribute: Optional[bool] = None
79 wrapped: Optional[bool] = None
82class ExternalDocumentation(BaseModel):
83 url: Optional[AnyUrl] = None
84 description: Optional[str] = None
87class Schema(BaseModel):
88 ref: Annotated[Optional[str], Field(alias="$ref")] = None
89 title: Optional[str] = None
90 multipleOf: Optional[float] = None
91 maximum: Optional[float] = None
92 exclusiveMaximum: Optional[float] = None
93 minimum: Optional[float] = None
94 exclusiveMinimum: Optional[float] = None
95 maxLength: Annotated[Optional[int], Field(ge=0)] = None
96 minLength: Annotated[Optional[int], Field(ge=0)] = None
97 pattern: Optional[str] = None
98 maxItems: Annotated[Optional[int], Field(ge=0)] = None
99 minItems: Annotated[Optional[int], Field(ge=0)] = None
100 uniqueItems: Optional[bool] = None
101 maxProperties: Annotated[Optional[int], Field(ge=0)] = None
102 minProperties: Annotated[Optional[int], Field(ge=0)] = None
103 required: Optional[List[str]] = None
104 enum: Optional[List[Any]] = None
105 type: Optional[str] = "object"
106 allOf: Optional[List[Schema]] = None
107 oneOf: Optional[List[Schema]] = None
108 anyOf: Optional[List[Schema]] = None
109 not_: Annotated[Optional[Schema], Field(alias="not")] = None
110 items: Optional[Union[Schema, List[Schema]]] = None
111 properties: Optional[Dict[str, Schema]] = None
112 additionalProperties: Optional[Union[Schema, Reference, bool]] = None
113 description: Optional[str] = None
114 format: Optional[str] = None
115 default: Any = None
116 nullable: Optional[bool] = None
117 discriminator: Optional[Discriminator] = None
118 readOnly: Optional[bool] = None
119 writeOnly: Optional[bool] = None
120 xml: Optional[XML] = None
121 externalDocs: Optional[ExternalDocumentation] = None
122 deprecated: Optional[bool] = None
123 example: Optional[Any] = None
124 examples: Optional[Examples] = None
127class Example(BaseModel):
128 summary: Optional[str] = None
129 description: Optional[str] = None
130 value: Any = None
131 external_value: Annotated[Optional[str], Field(alias="externalValue")] = None
134Examples = Mapping[str, Union[Example, Reference]]
137class Encoding(BaseModel):
138 contentType: Optional[str] = None
139 headers: Optional[Dict[str, Union[Header, Reference]]] = None
140 style: Optional[str] = None
141 explode: Optional[bool] = None
144class MediaType(BaseModel):
145 schema_: Annotated[Optional[Union[Schema, Reference]], Field(alias="schema")]
146 examples: Optional[Examples] = None
147 encoding: Optional[Dict[str, Encoding]] = None
150class ParameterBase(BaseModel):
151 description: Optional[str] = None
152 required: Optional[bool] = None
153 deprecated: Optional[bool] = None
154 # Serialization rules for simple scenarios
155 style: Optional[str] = None
156 explode: Optional[bool] = None
157 schema_: Annotated[Optional[Union[Schema, Reference]], Field(alias="schema")]
158 examples: Optional[Examples] = None
159 # Serialization rules for more complex scenarios
160 content: Optional[Dict[str, MediaType]] = None
163class ConcreteParameter(ParameterBase):
164 name: str
165 in_: ParameterLocations = Field(alias="in")
168class Header(ConcreteParameter):
169 in_: Literal["header"] = Field(default="header", alias="in")
170 style: HeaderParamStyles = "simple"
171 explode: bool = False
172 schema_: Annotated[Optional[Union[Schema, Reference]], Field(alias="schema")] = (
173 Schema(type="string")
174 )
177class Query(ConcreteParameter):
178 in_: Literal["query"] = Field(
179 default="query", # Explicit default
180 alias="in", # Explicit alias for OpenAPI compliance
181 )
182 style: QueryParamStyles = "form"
183 explode: bool = True
184 schema_: Annotated[Optional[Union[Schema, Reference]], Field(alias="schema")] = (
185 Schema(type="string")
186 )
189class Path(ConcreteParameter):
190 in_: Literal["path"] = Field(default="path", alias="in") # Explicit default
191 style: PathParamStyles = "simple"
192 explode: bool = False
193 required: Literal[True] = True
196class Cookie(ConcreteParameter):
197 in_: Literal["cookie"] = "cookie"
198 style: CookieParamStyles = "form"
199 explode: bool = True
202Parameter = Union[Query, Header, Cookie, Path]
205class RequestBody(BaseModel):
206 content: Dict[str, MediaType]
207 description: Optional[str] = None
208 required: Optional[bool] = None
211class Link(BaseModel):
212 operationRef: Optional[str] = None
213 operationId: Optional[str] = None
214 parameters: Optional[Dict[str, str]] = None
215 requestBody: Optional[str] = None
216 description: Optional[str] = None
217 server: Optional[Server] = None
220class ResponseHeader(BaseModel):
221 description: Optional[str] = None
222 deprecated: Optional[bool] = None
223 # Serialization rules for simple scenarios
224 style: HeaderParamStyles = "simple"
225 explode: bool = False
226 schema_: Annotated[Optional[Union[Schema, Reference]], Field(alias="schema")] = None
227 examples: Optional[Examples] = None
228 # Serialization rules for more complex scenarios
229 content: Optional[Dict[str, MediaType]] = None
232class Response(BaseModel):
233 description: str
234 headers: Optional[Dict[str, Union[ResponseHeader, Reference]]] = None
235 content: Optional[Dict[str, MediaType]] = None
236 links: Optional[Dict[str, Union[Link, Reference]]] = None
239class Operation(BaseModel):
240 responses: Dict[str, Union[Response, Reference]]
241 tags: Optional[List[str]] = None
242 summary: Optional[str] = None
243 description: Optional[str] = None
244 externalDocs: Optional[ExternalDocumentation] = None
245 operationId: Optional[str] = None
246 parameters: Optional[List[Union[ConcreteParameter, Reference]]] = None
247 requestBody: Optional[Union[RequestBody, Reference]] = None
248 # Using Any for Specification Extensions
249 callbacks: Optional[Dict[str, Union[Dict[str, PathItem], Reference]]] = None
250 deprecated: Optional[bool] = None
251 security: Optional[List[Dict[str, List[str]]]] = None
252 servers: Optional[List[Server]] = None
254 model_config = ConfigDict(extra="allow")
257# for extensions
260class PathItem(BaseModel):
261 ref: Annotated[Optional[str], Field(alias="$ref")] = None
262 summary: Optional[str] = None
263 description: Optional[str] = None
264 get: Optional[Operation] = None
265 put: Optional[Operation] = None
266 post: Optional[Operation] = None
267 delete: Optional[Operation] = None
268 options: Optional[Operation] = None
269 head: Optional[Operation] = None
270 patch: Optional[Operation] = None
271 trace: Optional[Operation] = None
272 servers: Optional[List[Server]] = None
273 parameters: Optional[List[Union[Parameter, Reference]]] = None
275 model_config = ConfigDict(extra="allow")
278# for extensions
281SecuritySchemeName = Literal["apiKey", "http", "oauth2", "openIdConnect"]
284class SecurityBase(BaseModel):
285 type: SecuritySchemeName
286 description: Optional[str] = None
289APIKeyLocation = Literal["query", "header", "cookie"]
292class APIKey(SecurityBase):
293 name: str
294 in_: Annotated[APIKeyLocation, Field(alias="in")]
295 type: Literal["apiKey"] = "apiKey"
298class HTTPBase(SecurityBase):
299 scheme: str
300 type: Literal["http"] = "http"
303class HTTPBearer(HTTPBase):
304 scheme: Literal["bearer"] = "bearer"
305 bearerFormat: Optional[str] = None
306 type: Literal["http"] = "http"
309class OAuthFlow(BaseModel):
310 refreshUrl: Optional[AnyUrl] = None
311 scopes: Annotated[Optional[Mapping[str, str]], Field(default_factory=dict)]
314class OAuthFlowImplicit(OAuthFlow):
315 authorizationUrl: str
318class OAuthFlowPassword(OAuthFlow):
319 tokenUrl: str
322class OAuthFlowClientCredentials(OAuthFlow):
323 tokenUrl: str
326class OAuthFlowAuthorizationCode(OAuthFlow):
327 authorizationUrl: str
328 tokenUrl: str
331class OAuthFlows(BaseModel):
332 implicit: Optional[OAuthFlowImplicit] = None
333 password: Optional[OAuthFlowPassword] = None
334 clientCredentials: Optional[OAuthFlowClientCredentials] = None
335 authorizationCode: Optional[OAuthFlowAuthorizationCode] = None
338class OAuth2(SecurityBase):
339 flows: OAuthFlows
340 type: Literal["oauth2"] = "oauth2"
343class OpenIdConnect(SecurityBase):
344 openIdConnectUrl: str
345 type: Literal["openIdConnect"] = "openIdConnect"
348SecurityScheme = Union[APIKey, HTTPBase, OAuth2, OpenIdConnect, HTTPBearer]
351class Components(BaseModel):
352 schemas: Optional[Dict[str, Union[Schema, Reference]]] = None
353 responses: Optional[Dict[str, Union[Response, Reference]]] = None
354 parameters: Optional[Dict[str, Union[Parameter, Reference]]] = None
355 examples: Optional[Examples] = None
356 requestBodies: Optional[Dict[str, Union[RequestBody, Reference]]] = None
357 headers: Optional[Dict[str, Union[Header, Reference]]] = None
358 securitySchemes: Optional[Dict[str, Union[SecurityScheme, Reference]]] = None
359 links: Optional[Dict[str, Union[Link, Reference]]] = None
360 callbacks: Optional[Dict[str, Union[Dict[str, PathItem], Reference]]] = None
363class Tag(BaseModel):
364 name: str
365 description: Optional[str] = None
366 externalDocs: Optional[ExternalDocumentation] = None
369class OpenAPI(BaseModel):
370 openapi: str
371 info: Info
372 paths: Annotated[Dict[str, Union[PathItem, Extension]], Field(default_factory=dict)]
373 servers: Optional[List[Server]] = None
374 # Using Any for Specification Extensions
375 components: Optional[Components] = None
376 security: Optional[List[Dict[str, List[str]]]] = None
377 tags: Optional[List[Tag]] = None
378 externalDocs: Optional[ExternalDocumentation] = None
381Schema.model_rebuild()
382Operation.model_rebuild()
383Encoding.model_rebuild()