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

1# type: ignore[overide] 

2from __future__ import annotations 

3 

4from typing import Any, Dict, List, Mapping, Optional, Union 

5 

6from pydantic import ConfigDict, BaseModel, Field 

7from pydantic.networks import AnyUrl 

8 

9try: 

10 import email_validator # type: ignore # noqa: F401 

11 from pydantic import EmailStr 

12except ImportError: # pragma: no cover 

13 EmailStr = str # type: ignore 

14 

15 

16from typing import Annotated, Literal 

17 

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 

24 

25Extension = Union[Dict[str, Any], List[Any], str, int, float, bool, None] 

26 

27 

28class Contact(BaseModel): 

29 name: Optional[str] = None 

30 url: Optional[AnyUrl] = None 

31 email: Optional[EmailStr] = None 

32 

33 

34class License(BaseModel): 

35 name: str 

36 url: Optional[AnyUrl] = None 

37 

38 

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 

46 

47 model_config = ConfigDict(extra="allow") 

48 

49 

50# for extensions 

51 

52 

53class ServerVariable(BaseModel): 

54 default: str 

55 enum: Optional[List[str]] = None 

56 description: Optional[str] = None 

57 

58 

59class Server(BaseModel): 

60 url: Union[AnyUrl, str] 

61 description: Optional[str] = None 

62 variables: Optional[Dict[str, ServerVariable]] = None 

63 

64 

65class Reference(BaseModel): 

66 ref: Annotated[str, Field(alias="$ref")] 

67 

68 

69class Discriminator(BaseModel): 

70 propertyName: str 

71 mapping: Optional[Dict[str, str]] = None 

72 

73 

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 

80 

81 

82class ExternalDocumentation(BaseModel): 

83 url: Optional[AnyUrl] = None 

84 description: Optional[str] = None 

85 

86 

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 

125 

126 

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 

132 

133 

134Examples = Mapping[str, Union[Example, Reference]] 

135 

136 

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 

142 

143 

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 

148 

149 

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 

161 

162 

163class ConcreteParameter(ParameterBase): 

164 name: str 

165 in_: ParameterLocations = Field(alias="in") 

166 

167 

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 ) 

175 

176 

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 ) 

187 

188 

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 

194 

195 

196class Cookie(ConcreteParameter): 

197 in_: Literal["cookie"] = "cookie" 

198 style: CookieParamStyles = "form" 

199 explode: bool = True 

200 

201 

202Parameter = Union[Query, Header, Cookie, Path] 

203 

204 

205class RequestBody(BaseModel): 

206 content: Dict[str, MediaType] 

207 description: Optional[str] = None 

208 required: Optional[bool] = None 

209 

210 

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 

218 

219 

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 

230 

231 

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 

237 

238 

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 

253 

254 model_config = ConfigDict(extra="allow") 

255 

256 

257# for extensions 

258 

259 

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 

274 

275 model_config = ConfigDict(extra="allow") 

276 

277 

278# for extensions 

279 

280 

281SecuritySchemeName = Literal["apiKey", "http", "oauth2", "openIdConnect"] 

282 

283 

284class SecurityBase(BaseModel): 

285 type: SecuritySchemeName 

286 description: Optional[str] = None 

287 

288 

289APIKeyLocation = Literal["query", "header", "cookie"] 

290 

291 

292class APIKey(SecurityBase): 

293 name: str 

294 in_: Annotated[APIKeyLocation, Field(alias="in")] 

295 type: Literal["apiKey"] = "apiKey" 

296 

297 

298class HTTPBase(SecurityBase): 

299 scheme: str 

300 type: Literal["http"] = "http" 

301 

302 

303class HTTPBearer(HTTPBase): 

304 scheme: Literal["bearer"] = "bearer" 

305 bearerFormat: Optional[str] = None 

306 type: Literal["http"] = "http" 

307 

308 

309class OAuthFlow(BaseModel): 

310 refreshUrl: Optional[AnyUrl] = None 

311 scopes: Annotated[Optional[Mapping[str, str]], Field(default_factory=dict)] 

312 

313 

314class OAuthFlowImplicit(OAuthFlow): 

315 authorizationUrl: str 

316 

317 

318class OAuthFlowPassword(OAuthFlow): 

319 tokenUrl: str 

320 

321 

322class OAuthFlowClientCredentials(OAuthFlow): 

323 tokenUrl: str 

324 

325 

326class OAuthFlowAuthorizationCode(OAuthFlow): 

327 authorizationUrl: str 

328 tokenUrl: str 

329 

330 

331class OAuthFlows(BaseModel): 

332 implicit: Optional[OAuthFlowImplicit] = None 

333 password: Optional[OAuthFlowPassword] = None 

334 clientCredentials: Optional[OAuthFlowClientCredentials] = None 

335 authorizationCode: Optional[OAuthFlowAuthorizationCode] = None 

336 

337 

338class OAuth2(SecurityBase): 

339 flows: OAuthFlows 

340 type: Literal["oauth2"] = "oauth2" 

341 

342 

343class OpenIdConnect(SecurityBase): 

344 openIdConnectUrl: str 

345 type: Literal["openIdConnect"] = "openIdConnect" 

346 

347 

348SecurityScheme = Union[APIKey, HTTPBase, OAuth2, OpenIdConnect, HTTPBearer] 

349 

350 

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 

361 

362 

363class Tag(BaseModel): 

364 name: str 

365 description: Optional[str] = None 

366 externalDocs: Optional[ExternalDocumentation] = None 

367 

368 

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 

379 

380 

381Schema.model_rebuild() 

382Operation.model_rebuild() 

383Encoding.model_rebuild()