cadwyn 3.15.2__py3-none-any.whl → 3.15.3a1__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.
Potentially problematic release.
This version of cadwyn might be problematic. Click here for more details.
- cadwyn/applications.py +56 -16
- cadwyn/routing.py +7 -2
- {cadwyn-3.15.2.dist-info → cadwyn-3.15.3a1.dist-info}/METADATA +1 -1
- {cadwyn-3.15.2.dist-info → cadwyn-3.15.3a1.dist-info}/RECORD +7 -7
- {cadwyn-3.15.2.dist-info → cadwyn-3.15.3a1.dist-info}/WHEEL +1 -1
- {cadwyn-3.15.2.dist-info → cadwyn-3.15.3a1.dist-info}/LICENSE +0 -0
- {cadwyn-3.15.2.dist-info → cadwyn-3.15.3a1.dist-info}/entry_points.txt +0 -0
cadwyn/applications.py
CHANGED
|
@@ -59,8 +59,13 @@ class Cadwyn(FastAPI):
|
|
|
59
59
|
swagger_ui_oauth2_redirect_url: str | None = "/docs/oauth2-redirect",
|
|
60
60
|
swagger_ui_init_oauth: dict[str, Any] | None = None,
|
|
61
61
|
middleware: Sequence[Middleware] | None = None,
|
|
62
|
-
exception_handlers:
|
|
63
|
-
|
|
62
|
+
exception_handlers: (
|
|
63
|
+
dict[
|
|
64
|
+
int | type[Exception],
|
|
65
|
+
Callable[[Request, Any], Coroutine[Any, Any, Response]],
|
|
66
|
+
]
|
|
67
|
+
| None
|
|
68
|
+
) = None,
|
|
64
69
|
on_startup: Sequence[Callable[[], Any]] | None = None,
|
|
65
70
|
on_shutdown: Sequence[Callable[[], Any]] | None = None,
|
|
66
71
|
lifespan: Lifespan[Self] | None = None,
|
|
@@ -76,13 +81,18 @@ class Cadwyn(FastAPI):
|
|
|
76
81
|
deprecated: bool | None = None,
|
|
77
82
|
include_in_schema: bool = True,
|
|
78
83
|
swagger_ui_parameters: dict[str, Any] | None = None,
|
|
79
|
-
generate_unique_id_function: Callable[[routing.APIRoute], str] = Default(
|
|
84
|
+
generate_unique_id_function: Callable[[routing.APIRoute], str] = Default(
|
|
85
|
+
generate_unique_id
|
|
86
|
+
), # noqa: B008
|
|
80
87
|
separate_input_output_schemas: bool = True,
|
|
81
88
|
**extra: Any,
|
|
82
89
|
) -> None:
|
|
83
90
|
self.versions = versions
|
|
84
91
|
# TODO: Remove argument entirely in any major version.
|
|
85
|
-
latest_schemas_package =
|
|
92
|
+
latest_schemas_package = (
|
|
93
|
+
extra.pop("latest_schemas_package", None)
|
|
94
|
+
or self.versions.head_schemas_package
|
|
95
|
+
)
|
|
86
96
|
self.versions.head_schemas_package = latest_schemas_package
|
|
87
97
|
self._latest_schemas_package = cast(ModuleType, latest_schemas_package)
|
|
88
98
|
|
|
@@ -138,10 +148,12 @@ class Cadwyn(FastAPI):
|
|
|
138
148
|
"responses": responses,
|
|
139
149
|
"generate_unique_id_function": generate_unique_id_function,
|
|
140
150
|
}
|
|
141
|
-
self.router: _RootHeaderAPIRouter =
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
151
|
+
self.router: _RootHeaderAPIRouter = (
|
|
152
|
+
_RootHeaderAPIRouter( # pyright: ignore[reportIncompatibleVariableOverride]
|
|
153
|
+
**self._kwargs_to_router,
|
|
154
|
+
api_version_header_name=api_version_header_name,
|
|
155
|
+
api_version_var=self.versions.api_version_var,
|
|
156
|
+
)
|
|
145
157
|
)
|
|
146
158
|
|
|
147
159
|
self.docs_url = docs_url
|
|
@@ -161,12 +173,16 @@ class Cadwyn(FastAPI):
|
|
|
161
173
|
)
|
|
162
174
|
|
|
163
175
|
@property # pragma: no cover
|
|
164
|
-
@deprecated(
|
|
176
|
+
@deprecated(
|
|
177
|
+
"It is going to be deleted in the future. Use VersionBundle.head_schemas_package instead"
|
|
178
|
+
)
|
|
165
179
|
def latest_schemas_package(self):
|
|
166
180
|
return self._latest_schemas_package
|
|
167
181
|
|
|
168
182
|
@latest_schemas_package.setter # pragma: no cover
|
|
169
|
-
@deprecated(
|
|
183
|
+
@deprecated(
|
|
184
|
+
"It is going to be deleted in the future. Use VersionBundle.head_schemas_package instead"
|
|
185
|
+
)
|
|
170
186
|
def latest_schemas_package(self, value: ModuleType | None):
|
|
171
187
|
self._latest_schemas_package = value
|
|
172
188
|
|
|
@@ -228,7 +244,7 @@ class Cadwyn(FastAPI):
|
|
|
228
244
|
terms_of_service=self.terms_of_service,
|
|
229
245
|
contact=self.contact,
|
|
230
246
|
license_info=self.license_info,
|
|
231
|
-
routes=self.router.
|
|
247
|
+
routes=self.router.unversioned_routes,
|
|
232
248
|
tags=self.openapi_tags,
|
|
233
249
|
servers=self.servers,
|
|
234
250
|
)
|
|
@@ -253,7 +269,9 @@ class Cadwyn(FastAPI):
|
|
|
253
269
|
self.swaggers[header_value_str] = openapi
|
|
254
270
|
|
|
255
271
|
async def openapi_jsons(self, req: Request) -> JSONResponse:
|
|
256
|
-
version = req.query_params.get("version") or req.headers.get(
|
|
272
|
+
version = req.query_params.get("version") or req.headers.get(
|
|
273
|
+
self.router.api_version_header_name
|
|
274
|
+
)
|
|
257
275
|
openapi_of_a_version = self.swaggers.get(version)
|
|
258
276
|
if not openapi_of_a_version:
|
|
259
277
|
raise HTTPException(
|
|
@@ -287,7 +305,9 @@ class Cadwyn(FastAPI):
|
|
|
287
305
|
if version:
|
|
288
306
|
root_path = self._extract_root_path(req)
|
|
289
307
|
openapi_url = root_path + f"{self.openapi_url}?version={version}"
|
|
290
|
-
return get_redoc_html(
|
|
308
|
+
return get_redoc_html(
|
|
309
|
+
openapi_url=openapi_url, title=f"{self.title} - ReDoc"
|
|
310
|
+
)
|
|
291
311
|
|
|
292
312
|
return self._render_docs_dashboard(req, docs_url=cast(str, self.redoc_url))
|
|
293
313
|
|
|
@@ -300,7 +320,10 @@ class Cadwyn(FastAPI):
|
|
|
300
320
|
"docs.html",
|
|
301
321
|
{
|
|
302
322
|
"request": req,
|
|
303
|
-
"table": {
|
|
323
|
+
"table": {
|
|
324
|
+
version: f"{base_url}{docs_url}?version={version}"
|
|
325
|
+
for version in sorted(self.swaggers)
|
|
326
|
+
},
|
|
304
327
|
},
|
|
305
328
|
)
|
|
306
329
|
|
|
@@ -317,7 +340,9 @@ class Cadwyn(FastAPI):
|
|
|
317
340
|
raise ValueError("header_value should be in ISO 8601 format") from e
|
|
318
341
|
|
|
319
342
|
if header_value_as_dt not in self.router.versioned_routers: # pragma: no branch
|
|
320
|
-
self.router.versioned_routers[header_value_as_dt] = APIRouter(
|
|
343
|
+
self.router.versioned_routers[header_value_as_dt] = APIRouter(
|
|
344
|
+
**self._kwargs_to_router
|
|
345
|
+
)
|
|
321
346
|
if self.openapi_url is not None: # pragma: no branch
|
|
322
347
|
self.router.versioned_routers[header_value_as_dt].add_route(
|
|
323
348
|
path=self.openapi_url,
|
|
@@ -325,12 +350,27 @@ class Cadwyn(FastAPI):
|
|
|
325
350
|
include_in_schema=False,
|
|
326
351
|
)
|
|
327
352
|
|
|
353
|
+
version_router = self.router.versioned_routers[header_value_as_dt]
|
|
328
354
|
added_routes: list[BaseRoute] = []
|
|
355
|
+
added_route_count = 0
|
|
329
356
|
for router in (first_router, *other_routers):
|
|
330
357
|
self.router.versioned_routers[header_value_as_dt].include_router(
|
|
331
358
|
router,
|
|
332
|
-
dependencies=[
|
|
359
|
+
dependencies=[
|
|
360
|
+
Depends(
|
|
361
|
+
_get_api_version_dependency(
|
|
362
|
+
self.router.api_version_header_name, header_value
|
|
363
|
+
)
|
|
364
|
+
)
|
|
365
|
+
],
|
|
333
366
|
)
|
|
367
|
+
added_route_count += len(router.routes)
|
|
368
|
+
|
|
369
|
+
added_routes = (
|
|
370
|
+
version_router.routes[-added_route_count :]
|
|
371
|
+
)
|
|
372
|
+
self.router.routes.extend(added_routes)
|
|
373
|
+
|
|
334
374
|
self.enrich_swagger()
|
|
335
375
|
return added_routes
|
|
336
376
|
|
cadwyn/routing.py
CHANGED
|
@@ -9,7 +9,7 @@ from typing import Any
|
|
|
9
9
|
from fastapi.routing import APIRouter
|
|
10
10
|
from starlette.datastructures import URL
|
|
11
11
|
from starlette.responses import RedirectResponse
|
|
12
|
-
from starlette.routing import BaseRoute, Match
|
|
12
|
+
from starlette.routing import BaseRoute, Match, Route
|
|
13
13
|
from starlette.types import Receive, Scope, Send
|
|
14
14
|
|
|
15
15
|
from .route_generation import InternalRepresentationOf, generate_versioned_routers # pyright: ignore[reportDeprecated]
|
|
@@ -46,6 +46,7 @@ class _RootHeaderAPIRouter(APIRouter):
|
|
|
46
46
|
self.versioned_routers: dict[date, APIRouter] = {}
|
|
47
47
|
self.api_version_header_name = api_version_header_name.lower()
|
|
48
48
|
self.api_version_var = api_version_var
|
|
49
|
+
self.unversioned_routes: list[Route] = []
|
|
49
50
|
|
|
50
51
|
@cached_property
|
|
51
52
|
def sorted_versions(self):
|
|
@@ -94,13 +95,17 @@ class _RootHeaderAPIRouter(APIRouter):
|
|
|
94
95
|
# if header_value is None, then it's an unversioned request and we need to use the unversioned routes
|
|
95
96
|
# if there will be a value, we search for the most suitable version
|
|
96
97
|
if not header_value:
|
|
97
|
-
routes = self.
|
|
98
|
+
routes = self.unversioned_routes
|
|
98
99
|
elif header_value in self.versioned_routers:
|
|
99
100
|
routes = self.versioned_routers[header_value].routes
|
|
100
101
|
else:
|
|
101
102
|
routes = self.pick_version(request_header_value=header_value)
|
|
102
103
|
await self.process_request(scope=scope, receive=receive, send=send, routes=routes)
|
|
103
104
|
|
|
105
|
+
def add_api_route(self, *args, **kwargs):
|
|
106
|
+
super().add_api_route(*args, **kwargs)
|
|
107
|
+
self.unversioned_routes.append(self.routes[-1])
|
|
108
|
+
|
|
104
109
|
async def process_request(self, scope: Scope, receive: Receive, send: Send, routes: Sequence[BaseRoute]) -> None:
|
|
105
110
|
"""
|
|
106
111
|
its a copy-paste from starlette.routing.Router
|
|
@@ -4,7 +4,7 @@ cadwyn/_asts.py,sha256=OF1qQKPqTbgYhH1tYF-MB8CCU0r6YITZpMFegzmk0Ic,10118
|
|
|
4
4
|
cadwyn/_compat.py,sha256=yAPmfGl2vVEYXlNHHPMoa2JkEJCVPjbP_Uz0WOIVOp4,5494
|
|
5
5
|
cadwyn/_package_utils.py,sha256=trxTYLmppv-10SKhScfyDQJh21rsQGFoLaOtHycKKR0,1443
|
|
6
6
|
cadwyn/_utils.py,sha256=BFsfZBpdoL5RMAaT1V1cXJVpTZCmwksQ-Le2MTHivGI,4841
|
|
7
|
-
cadwyn/applications.py,sha256=
|
|
7
|
+
cadwyn/applications.py,sha256=nreLcBP8CSc22JLfRWjPP1Ngt4xawTwgl0qTil4d_Hc,17983
|
|
8
8
|
cadwyn/codegen/README.md,sha256=hc7AE87LsEsvbh-wX1H10JEWh-8bLHoe-1CkY3h00FI,879
|
|
9
9
|
cadwyn/codegen/__init__.py,sha256=JgddDjxMTjSfVrMXHwNu1ODgdn2QfPWpccrRKquBV6k,355
|
|
10
10
|
cadwyn/codegen/_common.py,sha256=FTI4fqpUFGBMACVlPiDMHTWhqwW_-zQNa_4Qh7m-hCA,5877
|
|
@@ -20,7 +20,7 @@ cadwyn/main.py,sha256=kt2Vn7TIA4ZnD_xrgz57TOjUk-4zVP8SV8nuTZBEaaU,218
|
|
|
20
20
|
cadwyn/middleware.py,sha256=8cuBri_yRkl0goe6G0MLwtL04WGbW9Infah3wy9hUVM,3372
|
|
21
21
|
cadwyn/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
22
22
|
cadwyn/route_generation.py,sha256=nn_PWDa2WQOF-z3IOYBfG9K8po0tHm2C_Q0sRJRr5Ck,39843
|
|
23
|
-
cadwyn/routing.py,sha256=
|
|
23
|
+
cadwyn/routing.py,sha256=38-NhKXGQkUlz3zKnfwIIw9QSYz2h2nXEaSMlBkXzoU,6507
|
|
24
24
|
cadwyn/static/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
25
25
|
cadwyn/static/docs.html,sha256=WNm5ANJVy51TcIUFOaqKf1Z8eF86CC85TTHPxACtkzw,3455
|
|
26
26
|
cadwyn/structure/__init__.py,sha256=HjaNd6H4m4Cia42-dCO7A7sLWuVII7oldjaCabhbs_o,697
|
|
@@ -31,8 +31,8 @@ cadwyn/structure/enums.py,sha256=iMokxA2QYJ61SzyB-Pmuq3y7KL7-e6TsnjLVUaVZQnw,954
|
|
|
31
31
|
cadwyn/structure/modules.py,sha256=1FK-lLm-zOTXEvn-QtyBH38aDRht5PDQiZrOPCsBlM4,1268
|
|
32
32
|
cadwyn/structure/schemas.py,sha256=0ylArAkUw626VkUOJSulOwJs7CS6lrGBRECEG5HFD4Q,8897
|
|
33
33
|
cadwyn/structure/versions.py,sha256=PuXYze89tWvLsOOiuAQtYRi-p1ue2FPfBWWR2bl8hLg,37236
|
|
34
|
-
cadwyn-3.15.
|
|
35
|
-
cadwyn-3.15.
|
|
36
|
-
cadwyn-3.15.
|
|
37
|
-
cadwyn-3.15.
|
|
38
|
-
cadwyn-3.15.
|
|
34
|
+
cadwyn-3.15.3a1.dist-info/LICENSE,sha256=KeCWewiDQYpmSnzF-p_0YpoWiyDcUPaCuG8OWQs4ig4,1072
|
|
35
|
+
cadwyn-3.15.3a1.dist-info/METADATA,sha256=aaXSojcoje-vXvK6fGtFVPOJIlDkqjrMWozw2J9md28,4399
|
|
36
|
+
cadwyn-3.15.3a1.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
37
|
+
cadwyn-3.15.3a1.dist-info/entry_points.txt,sha256=eO05hLn9GoRzzpwT9GONPmXKsonjuMNssM2D2WHWKGk,46
|
|
38
|
+
cadwyn-3.15.3a1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|