flask-openapi 4.3.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. flask_openapi/__init__.py +44 -0
  2. flask_openapi/__version__.py +5 -0
  3. flask_openapi/blueprint.py +201 -0
  4. flask_openapi/commands.py +38 -0
  5. flask_openapi/models/__init__.py +91 -0
  6. flask_openapi/models/callback.py +18 -0
  7. flask_openapi/models/components.py +37 -0
  8. flask_openapi/models/contact.py +17 -0
  9. flask_openapi/models/data_type.py +18 -0
  10. flask_openapi/models/discriminator.py +16 -0
  11. flask_openapi/models/encoding.py +27 -0
  12. flask_openapi/models/example.py +19 -0
  13. flask_openapi/models/external_documentation.py +16 -0
  14. flask_openapi/models/file.py +27 -0
  15. flask_openapi/models/header.py +17 -0
  16. flask_openapi/models/info.py +24 -0
  17. flask_openapi/models/license.py +17 -0
  18. flask_openapi/models/link.py +23 -0
  19. flask_openapi/models/media_type.py +24 -0
  20. flask_openapi/models/oauth_flow.py +18 -0
  21. flask_openapi/models/oauth_flows.py +20 -0
  22. flask_openapi/models/operation.py +36 -0
  23. flask_openapi/models/parameter.py +34 -0
  24. flask_openapi/models/parameter_in_type.py +13 -0
  25. flask_openapi/models/path_item.py +36 -0
  26. flask_openapi/models/paths.py +9 -0
  27. flask_openapi/models/reference.py +14 -0
  28. flask_openapi/models/request_body.py +19 -0
  29. flask_openapi/models/response.py +23 -0
  30. flask_openapi/models/responses.py +11 -0
  31. flask_openapi/models/schema.py +59 -0
  32. flask_openapi/models/security_requirement.py +8 -0
  33. flask_openapi/models/security_scheme.py +25 -0
  34. flask_openapi/models/security_scheme_in_type.py +12 -0
  35. flask_openapi/models/server.py +19 -0
  36. flask_openapi/models/server_variable.py +17 -0
  37. flask_openapi/models/style_values.py +14 -0
  38. flask_openapi/models/tag.py +15 -0
  39. flask_openapi/models/validation_error.py +24 -0
  40. flask_openapi/models/xml.py +19 -0
  41. flask_openapi/openapi.py +449 -0
  42. flask_openapi/plugins.py +17 -0
  43. flask_openapi/py.typed +0 -0
  44. flask_openapi/request.py +250 -0
  45. flask_openapi/scaffold.py +547 -0
  46. flask_openapi/templates.py +113 -0
  47. flask_openapi/types.py +27 -0
  48. flask_openapi/utils.py +633 -0
  49. flask_openapi/view.py +230 -0
  50. flask_openapi-4.3.1.dist-info/METADATA +258 -0
  51. flask_openapi-4.3.1.dist-info/RECORD +53 -0
  52. flask_openapi-4.3.1.dist-info/WHEEL +4 -0
  53. flask_openapi-4.3.1.dist-info/licenses/LICENSE.rst +21 -0
@@ -0,0 +1,547 @@
1
+ # -*- coding: utf-8 -*-
2
+ # @Author : llc
3
+ # @Time : 2022/8/30 9:40
4
+ import inspect
5
+ from functools import wraps
6
+ from typing import Any, Callable
7
+
8
+ from flask import current_app
9
+ from flask.wrappers import Response as FlaskResponse
10
+
11
+ from .models import ExternalDocumentation, Server, Tag
12
+ from .request import _validate_request
13
+ from .types import ParametersTuple, ResponseDict
14
+ from .utils import HTTPMethod
15
+
16
+
17
+ class APIScaffold:
18
+ def _collect_openapi_info(
19
+ self,
20
+ rule: str,
21
+ func: Callable,
22
+ *,
23
+ tags: list[Tag] | None = None,
24
+ summary: str | None = None,
25
+ description: str | None = None,
26
+ external_docs: ExternalDocumentation | None = None,
27
+ operation_id: str | None = None,
28
+ responses: ResponseDict | None = None,
29
+ deprecated: bool | None = None,
30
+ security: list[dict[str, list[Any]]] | None = None,
31
+ servers: list[Server] | None = None,
32
+ openapi_extensions: dict[str, Any] | None = None,
33
+ doc_ui: bool = True,
34
+ method: str = HTTPMethod.GET,
35
+ ) -> ParametersTuple:
36
+ raise NotImplementedError # pragma: no cover
37
+
38
+ def register_api(self, api) -> None:
39
+ raise NotImplementedError # pragma: no cover
40
+
41
+ def _add_url_rule(
42
+ self,
43
+ rule,
44
+ endpoint=None,
45
+ view_func=None,
46
+ provide_automatic_options=None,
47
+ **options,
48
+ ) -> None:
49
+ raise NotImplementedError # pragma: no cover
50
+
51
+ @staticmethod
52
+ def create_view_func(
53
+ func,
54
+ header,
55
+ cookie,
56
+ path,
57
+ query,
58
+ form,
59
+ body,
60
+ raw,
61
+ view_class=None,
62
+ view_kwargs=None,
63
+ responses: ResponseDict | None = None,
64
+ validate_response: bool | None = None,
65
+ ):
66
+ is_coroutine_function = inspect.iscoroutinefunction(func)
67
+ if is_coroutine_function:
68
+
69
+ @wraps(func)
70
+ async def view_func(**kwargs) -> FlaskResponse:
71
+ if hasattr(func, "__delay_validate_request__") and func.__delay_validate_request__ is True:
72
+ func_kwargs = kwargs
73
+ else:
74
+ func_kwargs = _validate_request(
75
+ header=header,
76
+ cookie=cookie,
77
+ path=path,
78
+ query=query,
79
+ form=form,
80
+ body=body,
81
+ raw=raw,
82
+ path_kwargs=kwargs,
83
+ )
84
+
85
+ # handle async request
86
+ if view_class:
87
+ signature = inspect.signature(view_class.__init__)
88
+ parameters = signature.parameters
89
+ if parameters.get("view_kwargs"):
90
+ view_object = view_class(view_kwargs=view_kwargs)
91
+ else:
92
+ view_object = view_class()
93
+ response = await func(view_object, **func_kwargs)
94
+ else:
95
+ response = await func(**func_kwargs)
96
+
97
+ if hasattr(current_app, "validate_response"):
98
+ if validate_response is None:
99
+ _validate_response = current_app.validate_response
100
+ else:
101
+ _validate_response = validate_response
102
+ else:
103
+ _validate_response = validate_response
104
+
105
+ if _validate_response and responses:
106
+ validate_response_callback = getattr(current_app, "validate_response_callback")
107
+ return validate_response_callback(response, responses)
108
+
109
+ return response
110
+ else:
111
+
112
+ @wraps(func)
113
+ def view_func(**kwargs) -> FlaskResponse:
114
+ if hasattr(func, "__delay_validate_request__") and func.__delay_validate_request__ is True:
115
+ func_kwargs = kwargs
116
+ else:
117
+ func_kwargs = _validate_request(
118
+ header=header,
119
+ cookie=cookie,
120
+ path=path,
121
+ query=query,
122
+ form=form,
123
+ body=body,
124
+ raw=raw,
125
+ path_kwargs=kwargs,
126
+ )
127
+
128
+ # handle request
129
+ if view_class:
130
+ signature = inspect.signature(view_class.__init__)
131
+ parameters = signature.parameters
132
+ if parameters.get("view_kwargs"):
133
+ view_object = view_class(view_kwargs=view_kwargs)
134
+ else:
135
+ view_object = view_class()
136
+ response = func(view_object, **func_kwargs)
137
+ else:
138
+ response = func(**func_kwargs)
139
+
140
+ if hasattr(current_app, "validate_response"):
141
+ if validate_response is None:
142
+ _validate_response = current_app.validate_response
143
+ else:
144
+ _validate_response = validate_response
145
+ else:
146
+ _validate_response = validate_response
147
+
148
+ if _validate_response and responses:
149
+ validate_response_callback = getattr(current_app, "validate_response_callback")
150
+ return validate_response_callback(response, responses)
151
+
152
+ return response
153
+
154
+ if not hasattr(func, "view"):
155
+ func.view = view_func
156
+
157
+ return func.view
158
+
159
+ def get(
160
+ self,
161
+ rule: str,
162
+ *,
163
+ tags: list[Tag] | None = None,
164
+ summary: str | None = None,
165
+ description: str | None = None,
166
+ external_docs: ExternalDocumentation | None = None,
167
+ operation_id: str | None = None,
168
+ responses: ResponseDict | None = None,
169
+ deprecated: bool | None = None,
170
+ security: list[dict[str, list[Any]]] | None = None,
171
+ servers: list[Server] | None = None,
172
+ openapi_extensions: dict[str, Any] | None = None,
173
+ validate_response: bool | None = None,
174
+ doc_ui: bool = True,
175
+ **options: Any,
176
+ ) -> Callable:
177
+ """
178
+ Decorator for defining a REST API endpoint with the HTTP GET method.
179
+ More information goto https://spec.openapis.org/oas/v3.1.0#operation-object
180
+
181
+ Args:
182
+ rule: The URL rule string.
183
+ tags: Adds metadata to a single tag.
184
+ summary: A short summary of what the operation does.
185
+ description: A verbose explanation of the operation behavior.
186
+ external_docs: Additional external documentation for this operation.
187
+ operation_id: Unique string used to identify the operation.
188
+ responses: API responses should be either a subclass of BaseModel, a dictionary, or None.
189
+ deprecated: Declares this operation to be deprecated.
190
+ security: A declaration of which security mechanisms can be used for this operation.
191
+ servers: An alternative server array to service this operation.
192
+ openapi_extensions: Allows extensions to the OpenAPI Schema.
193
+ doc_ui: Declares this operation to be shown. Default to True.
194
+ validate_response: Verify the response body.
195
+ """
196
+
197
+ def decorator(func) -> Callable:
198
+ header, cookie, path, query, form, body, raw = self._collect_openapi_info(
199
+ rule,
200
+ func,
201
+ tags=tags,
202
+ summary=summary,
203
+ description=description,
204
+ external_docs=external_docs,
205
+ operation_id=operation_id,
206
+ responses=responses,
207
+ deprecated=deprecated,
208
+ security=security,
209
+ servers=servers,
210
+ openapi_extensions=openapi_extensions,
211
+ doc_ui=doc_ui,
212
+ method=HTTPMethod.GET,
213
+ )
214
+
215
+ _validate_response = validate_response if validate_response is not None else self.get_validate_response()
216
+ view_func = self.create_view_func(
217
+ func,
218
+ header,
219
+ cookie,
220
+ path,
221
+ query,
222
+ form,
223
+ body,
224
+ raw,
225
+ responses=responses,
226
+ validate_response=_validate_response,
227
+ )
228
+
229
+ options.update({"methods": [HTTPMethod.GET]})
230
+ self._add_url_rule(rule, view_func=view_func, **options)
231
+
232
+ return func
233
+
234
+ return decorator
235
+
236
+ def post(
237
+ self,
238
+ rule: str,
239
+ *,
240
+ tags: list[Tag] | None = None,
241
+ summary: str | None = None,
242
+ description: str | None = None,
243
+ external_docs: ExternalDocumentation | None = None,
244
+ operation_id: str | None = None,
245
+ responses: ResponseDict | None = None,
246
+ deprecated: bool | None = None,
247
+ security: list[dict[str, list[Any]]] | None = None,
248
+ servers: list[Server] | None = None,
249
+ openapi_extensions: dict[str, Any] | None = None,
250
+ validate_response: bool | None = None,
251
+ doc_ui: bool = True,
252
+ **options: Any,
253
+ ) -> Callable:
254
+ """
255
+ Decorator for defining a REST API endpoint with the HTTP POST method.
256
+ More information goto https://spec.openapis.org/oas/v3.1.0#operation-object
257
+
258
+ Args:
259
+ rule: The URL rule string.
260
+ tags: Adds metadata to a single tag.
261
+ summary: A short summary of what the operation does.
262
+ description: A verbose explanation of the operation behavior.
263
+ external_docs: Additional external documentation for this operation.
264
+ operation_id: Unique string used to identify the operation.
265
+ responses: API responses should be either a subclass of BaseModel, a dictionary, or None.
266
+ deprecated: Declares this operation to be deprecated.
267
+ security: A declaration of which security mechanisms can be used for this operation.
268
+ servers: An alternative server array to service this operation.
269
+ openapi_extensions: Allows extensions to the OpenAPI Schema.
270
+ doc_ui: Declares this operation to be shown. Default to True.
271
+ validate_response: Verify the response body.
272
+ """
273
+
274
+ def decorator(func) -> Callable:
275
+ header, cookie, path, query, form, body, raw = self._collect_openapi_info(
276
+ rule,
277
+ func,
278
+ tags=tags,
279
+ summary=summary,
280
+ description=description,
281
+ external_docs=external_docs,
282
+ operation_id=operation_id,
283
+ responses=responses,
284
+ deprecated=deprecated,
285
+ security=security,
286
+ servers=servers,
287
+ openapi_extensions=openapi_extensions,
288
+ doc_ui=doc_ui,
289
+ method=HTTPMethod.POST,
290
+ )
291
+
292
+ _validate_response = validate_response if validate_response is not None else self.get_validate_response()
293
+ view_func = self.create_view_func(
294
+ func,
295
+ header,
296
+ cookie,
297
+ path,
298
+ query,
299
+ form,
300
+ body,
301
+ raw,
302
+ responses=responses,
303
+ validate_response=_validate_response,
304
+ )
305
+
306
+ options.update({"methods": [HTTPMethod.POST]})
307
+ self._add_url_rule(rule, view_func=view_func, **options)
308
+
309
+ return func
310
+
311
+ return decorator
312
+
313
+ def put(
314
+ self,
315
+ rule: str,
316
+ *,
317
+ tags: list[Tag] | None = None,
318
+ summary: str | None = None,
319
+ description: str | None = None,
320
+ external_docs: ExternalDocumentation | None = None,
321
+ operation_id: str | None = None,
322
+ responses: ResponseDict | None = None,
323
+ deprecated: bool | None = None,
324
+ security: list[dict[str, list[Any]]] | None = None,
325
+ servers: list[Server] | None = None,
326
+ openapi_extensions: dict[str, Any] | None = None,
327
+ validate_response: bool | None = None,
328
+ doc_ui: bool = True,
329
+ **options: Any,
330
+ ) -> Callable:
331
+ """
332
+ Decorator for defining a REST API endpoint with the HTTP PUT method.
333
+ More information goto https://spec.openapis.org/oas/v3.1.0#operation-object
334
+
335
+ Args:
336
+ rule: The URL rule string.
337
+ tags: Adds metadata to a single tag.
338
+ summary: A short summary of what the operation does.
339
+ description: A verbose explanation of the operation behavior.
340
+ external_docs: Additional external documentation for this operation.
341
+ operation_id: Unique string used to identify the operation.
342
+ responses: API responses should be either a subclass of BaseModel, a dictionary, or None.
343
+ deprecated: Declares this operation to be deprecated.
344
+ security: A declaration of which security mechanisms can be used for this operation.
345
+ servers: An alternative server array to service this operation.
346
+ openapi_extensions: Allows extensions to the OpenAPI Schema.
347
+ doc_ui: Declares this operation to be shown. Default to True.
348
+ validate_response: Verify the response body.
349
+ """
350
+
351
+ def decorator(func) -> Callable:
352
+ header, cookie, path, query, form, body, raw = self._collect_openapi_info(
353
+ rule,
354
+ func,
355
+ tags=tags,
356
+ summary=summary,
357
+ description=description,
358
+ external_docs=external_docs,
359
+ operation_id=operation_id,
360
+ responses=responses,
361
+ deprecated=deprecated,
362
+ security=security,
363
+ servers=servers,
364
+ openapi_extensions=openapi_extensions,
365
+ doc_ui=doc_ui,
366
+ method=HTTPMethod.PUT,
367
+ )
368
+
369
+ _validate_response = validate_response if validate_response is not None else self.get_validate_response()
370
+ view_func = self.create_view_func(
371
+ func,
372
+ header,
373
+ cookie,
374
+ path,
375
+ query,
376
+ form,
377
+ body,
378
+ raw,
379
+ responses=responses,
380
+ validate_response=_validate_response,
381
+ )
382
+
383
+ options.update({"methods": [HTTPMethod.PUT]})
384
+ self._add_url_rule(rule, view_func=view_func, **options)
385
+
386
+ return func
387
+
388
+ return decorator
389
+
390
+ def delete(
391
+ self,
392
+ rule: str,
393
+ *,
394
+ tags: list[Tag] | None = None,
395
+ summary: str | None = None,
396
+ description: str | None = None,
397
+ external_docs: ExternalDocumentation | None = None,
398
+ operation_id: str | None = None,
399
+ responses: ResponseDict | None = None,
400
+ deprecated: bool | None = None,
401
+ security: list[dict[str, list[Any]]] | None = None,
402
+ servers: list[Server] | None = None,
403
+ openapi_extensions: dict[str, Any] | None = None,
404
+ validate_response: bool | None = None,
405
+ doc_ui: bool = True,
406
+ **options: Any,
407
+ ) -> Callable:
408
+ """
409
+ Decorator for defining a REST API endpoint with the HTTP DELETE method.
410
+ More information goto https://spec.openapis.org/oas/v3.1.0#operation-object
411
+
412
+ Args:
413
+ rule: The URL rule string.
414
+ tags: Adds metadata to a single tag.
415
+ summary: A short summary of what the operation does.
416
+ description: A verbose explanation of the operation behavior.
417
+ external_docs: Additional external documentation for this operation.
418
+ operation_id: Unique string used to identify the operation.
419
+ responses: API responses should be either a subclass of BaseModel, a dictionary, or None.
420
+ deprecated: Declares this operation to be deprecated.
421
+ security: A declaration of which security mechanisms can be used for this operation.
422
+ servers: An alternative server array to service this operation.
423
+ openapi_extensions: Allows extensions to the OpenAPI Schema.
424
+ doc_ui: Declares this operation to be shown. Default to True.
425
+ validate_response: Verify the response body.
426
+ """
427
+
428
+ def decorator(func) -> Callable:
429
+ header, cookie, path, query, form, body, raw = self._collect_openapi_info(
430
+ rule,
431
+ func,
432
+ tags=tags,
433
+ summary=summary,
434
+ description=description,
435
+ external_docs=external_docs,
436
+ operation_id=operation_id,
437
+ responses=responses,
438
+ deprecated=deprecated,
439
+ security=security,
440
+ servers=servers,
441
+ openapi_extensions=openapi_extensions,
442
+ doc_ui=doc_ui,
443
+ method=HTTPMethod.DELETE,
444
+ )
445
+
446
+ _validate_response = validate_response if validate_response is not None else self.get_validate_response()
447
+ view_func = self.create_view_func(
448
+ func,
449
+ header,
450
+ cookie,
451
+ path,
452
+ query,
453
+ form,
454
+ body,
455
+ raw,
456
+ responses=responses,
457
+ validate_response=_validate_response,
458
+ )
459
+
460
+ options.update({"methods": [HTTPMethod.DELETE]})
461
+ self._add_url_rule(rule, view_func=view_func, **options)
462
+
463
+ return func
464
+
465
+ return decorator
466
+
467
+ def patch(
468
+ self,
469
+ rule: str,
470
+ *,
471
+ tags: list[Tag] | None = None,
472
+ summary: str | None = None,
473
+ description: str | None = None,
474
+ external_docs: ExternalDocumentation | None = None,
475
+ operation_id: str | None = None,
476
+ responses: ResponseDict | None = None,
477
+ deprecated: bool | None = None,
478
+ security: list[dict[str, list[Any]]] | None = None,
479
+ servers: list[Server] | None = None,
480
+ openapi_extensions: dict[str, Any] | None = None,
481
+ validate_response: bool | None = None,
482
+ doc_ui: bool = True,
483
+ **options: Any,
484
+ ) -> Callable:
485
+ """
486
+ Decorator for defining a REST API endpoint with the HTTP PATCH method.
487
+ More information goto https://spec.openapis.org/oas/v3.1.0#operation-object
488
+
489
+ Args:
490
+ rule: The URL rule string.
491
+ tags: Adds metadata to a single tag.
492
+ summary: A short summary of what the operation does.
493
+ description: A verbose explanation of the operation behavior.
494
+ external_docs: Additional external documentation for this operation.
495
+ operation_id: Unique string used to identify the operation.
496
+ responses: API responses should be either a subclass of BaseModel, a dictionary, or None.
497
+ deprecated: Declares this operation to be deprecated.
498
+ security: A declaration of which security mechanisms can be used for this operation.
499
+ servers: An alternative server array to service this operation.
500
+ openapi_extensions: Allows extensions to the OpenAPI Schema.
501
+ doc_ui: Declares this operation to be shown. Default to True.
502
+ validate_response: Verify the response body.
503
+ """
504
+
505
+ def decorator(func) -> Callable:
506
+ header, cookie, path, query, form, body, raw = self._collect_openapi_info(
507
+ rule,
508
+ func,
509
+ tags=tags,
510
+ summary=summary,
511
+ description=description,
512
+ external_docs=external_docs,
513
+ operation_id=operation_id,
514
+ responses=responses,
515
+ deprecated=deprecated,
516
+ security=security,
517
+ servers=servers,
518
+ openapi_extensions=openapi_extensions,
519
+ doc_ui=doc_ui,
520
+ method=HTTPMethod.PATCH,
521
+ )
522
+
523
+ _validate_response = validate_response if validate_response is not None else self.get_validate_response()
524
+ view_func = self.create_view_func(
525
+ func,
526
+ header,
527
+ cookie,
528
+ path,
529
+ query,
530
+ form,
531
+ body,
532
+ raw,
533
+ responses=responses,
534
+ validate_response=_validate_response,
535
+ )
536
+
537
+ options.update({"methods": [HTTPMethod.PATCH]})
538
+ self._add_url_rule(rule, view_func=view_func, **options)
539
+
540
+ return func
541
+
542
+ return decorator
543
+
544
+ def get_validate_response(self):
545
+ if hasattr(self, "validate_response"):
546
+ if self.validate_response is not None:
547
+ return self.validate_response
@@ -0,0 +1,113 @@
1
+ # -*- coding: utf-8 -*-
2
+ # @Author : llc
3
+ # @Time : 2023/2/16 9:46
4
+
5
+
6
+ openapi_html_string = """
7
+ <!DOCTYPE html>
8
+ <html lang="en">
9
+ <head>
10
+ <meta charset="UTF-8">
11
+ <title>APIdoc</title>
12
+ <link rel="shortcut icon" href="
13
+ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAkBJREFUSEutlU9oE1EQxr/ZPdiDRBR6K
14
+ KIepAhevFqwZqNByT+ziaQevEQRUQ8eBQ9iCyLkJFiKJ21FRLCY3SbZpSoxT4sWBQ/24MEe9OJdiURrd3dka9XUNtm31Xd8M/P9ZubNe48Qcg0W7F4sLPY5
15
+ GxbmZyeHvgaFU5BDu13Tq8Mg5fLy3kciuv5N/TLaDSQNiOVr55hp7O+EiGiOPb4mzNTEWslKAfy2qA7PAtjZsWLChCinTqxKQKZFWs46A+BGkC+BJhtGcqj
16
+ dT6qCWM6+z+BCEADAJ2GkNocCaMVGDz63AqfFF2Xg3VMjtSsU4IBuH/KIH0pkDxCuiHLqUiiApltFEMaDAMQ82jDT50MfclS3LhLhancA3RZGsriuMY1la4
17
+ dZoenOAK4LIx3vZA+cokTCjrR6+D0BW1aLcNNljs+YmVfrBviBWt4aB2ONFpAQRjLWrX2BFSwBVr5BbXr/CNh/tNqveGoJ4FynLF3X2TNTyc6FbpGWt4+Bu
18
+ QRgR9cJItwU5dSpUICobpWIcCFo9v/Y+e6i6559Xsk2u96DeOHxJsf5fg9AQl582ZPwUiXldP1BYkW7fh9yvFDZ7jhqjYGtRJgH00Zm3kaESAjYB8Xj40+m
19
+ 0i9+xQROUaeXlEC3mN07vhApFGGmAYD2Al6/x97JZ+aRR0s2mey0nOX/Bf6f8HOxFxNmRsjESgEG89N9KrtvAPSCvRFhZoZlxKUr8B2jujVGwEDT9fa9rmZ
20
+ a/x3gCx7M2rvrU8m3suK+3w+AcssZ50vnfwAAAABJRU5ErkJggg==
21
+ ">
22
+ <style>
23
+ body {
24
+ background-color: #131417;
25
+ display: flex;
26
+ justify-content: center;
27
+ align-items: center;
28
+ height: 100vh;
29
+ margin: 0;
30
+ }
31
+
32
+ .grid {
33
+ display: grid;
34
+ grid-template-columns: repeat(6, 1fr);
35
+ grid-gap: 36px;
36
+ }
37
+
38
+ .box {
39
+ grid-column: span 2;
40
+ width: 300px;
41
+ height: 200px;
42
+ background: #2c303a;
43
+ border-radius: 30px;
44
+ display: flex;
45
+ flex-direction: column;
46
+ align-items: center;
47
+ justify-content: center;
48
+ position: relative;
49
+ transform: scale(1);
50
+ transition: all .3s ease;
51
+ }
52
+
53
+ /* Dealing with 2 orphan items */
54
+
55
+ .box:last-child:nth-child(3n - 1) {
56
+ grid-column-end: -2;
57
+ }
58
+
59
+ .box:nth-last-child(2):nth-child(3n + 1) {
60
+ grid-column-end: 4;
61
+ }
62
+
63
+ /* Dealing with single orphan */
64
+
65
+ .box:last-child:nth-child(3n - 2) {
66
+ grid-column-end: 5;
67
+ }
68
+
69
+ .box:hover {
70
+ transform: scale(1.1);
71
+ box-shadow: 0 0 20px #333743f0;
72
+ }
73
+
74
+ .box a {
75
+ color: white;
76
+ font-size: 30px;
77
+ user-select: none;
78
+ }
79
+
80
+ .box img {
81
+ user-select: none;
82
+ height: 64px;
83
+ margin-bottom: 10px;
84
+ }
85
+
86
+ </style>
87
+
88
+ </head>
89
+ <body>
90
+ <div class="grid">
91
+ {% for ui in ui_templates %}
92
+ <div class="box" onclick="window.location.href='{{ ui.name }}';return false">
93
+ <img height="64" src="{{ ui.name }}/images/{{ ui.name }}.svg">
94
+ <a>{{ ui.display_name }}</a>
95
+ </div>
96
+ {% else %}
97
+ <div style="color: white; grid-column: span 2; display: flex; flex-direction: column; grid-column-end: 5;">
98
+ <p>Please install at least one optional UI:</p>
99
+ <p style="font-family: Consolas; background-color: #404348; border-radius: 5px; padding: 5px; font-size: 12px">
100
+ $ pip install -U flask-openapi3[swagger,redoc,rapidoc,rapipdf,scalar,elements]
101
+ </p>
102
+ <p>More optional ui templates goto the document about
103
+ <a href="https://luolingchun.github.io/flask-openapi3/latest/Usage/UI_Templates/" style="color: #0969da">
104
+ UI_Templates.
105
+ </a>
106
+ </p>
107
+ </div>
108
+ {% endfor %}
109
+ </div>
110
+
111
+ </body>
112
+ </html>
113
+ """
flask_openapi/types.py ADDED
@@ -0,0 +1,27 @@
1
+ # -*- coding: utf-8 -*-
2
+ # @Author : llc
3
+ # @Time : 2023/7/9 15:25
4
+ from http import HTTPStatus
5
+ from typing import Any, Type
6
+
7
+ from pydantic import BaseModel
8
+
9
+ from .models import RawModel, SecurityScheme
10
+
11
+ _ResponseDictValue = Type[BaseModel] | dict[Any, Any] | None
12
+
13
+ ResponseDict = dict[str | int | HTTPStatus, _ResponseDictValue]
14
+
15
+ ResponseStrKeyDict = dict[str, _ResponseDictValue]
16
+
17
+ SecuritySchemesDict = dict[str, SecurityScheme | dict[str, Any]]
18
+
19
+ ParametersTuple = tuple[
20
+ Type[BaseModel] | None,
21
+ Type[BaseModel] | None,
22
+ Type[BaseModel] | None,
23
+ Type[BaseModel] | None,
24
+ Type[BaseModel] | None,
25
+ Type[BaseModel] | None,
26
+ Type[RawModel] | None,
27
+ ]