cadwyn 3.14.0__tar.gz → 3.15.1__tar.gz

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.

Files changed (37) hide show
  1. {cadwyn-3.14.0 → cadwyn-3.15.1}/PKG-INFO +3 -3
  2. {cadwyn-3.14.0 → cadwyn-3.15.1}/README.md +2 -2
  3. {cadwyn-3.14.0 → cadwyn-3.15.1}/cadwyn/__init__.py +5 -1
  4. {cadwyn-3.14.0 → cadwyn-3.15.1}/cadwyn/__main__.py +1 -1
  5. {cadwyn-3.14.0 → cadwyn-3.15.1}/cadwyn/applications.py +47 -91
  6. {cadwyn-3.14.0 → cadwyn-3.15.1}/cadwyn/route_generation.py +4 -1
  7. {cadwyn-3.14.0 → cadwyn-3.15.1}/cadwyn/routing.py +1 -1
  8. {cadwyn-3.14.0 → cadwyn-3.15.1}/cadwyn/structure/versions.py +1 -1
  9. {cadwyn-3.14.0 → cadwyn-3.15.1}/pyproject.toml +9 -3
  10. {cadwyn-3.14.0 → cadwyn-3.15.1}/LICENSE +0 -0
  11. {cadwyn-3.14.0 → cadwyn-3.15.1}/cadwyn/_asts.py +0 -0
  12. {cadwyn-3.14.0 → cadwyn-3.15.1}/cadwyn/_compat.py +0 -0
  13. {cadwyn-3.14.0 → cadwyn-3.15.1}/cadwyn/_package_utils.py +0 -0
  14. {cadwyn-3.14.0 → cadwyn-3.15.1}/cadwyn/_utils.py +0 -0
  15. {cadwyn-3.14.0 → cadwyn-3.15.1}/cadwyn/codegen/README.md +0 -0
  16. {cadwyn-3.14.0 → cadwyn-3.15.1}/cadwyn/codegen/__init__.py +0 -0
  17. {cadwyn-3.14.0 → cadwyn-3.15.1}/cadwyn/codegen/_common.py +0 -0
  18. {cadwyn-3.14.0 → cadwyn-3.15.1}/cadwyn/codegen/_main.py +0 -0
  19. {cadwyn-3.14.0 → cadwyn-3.15.1}/cadwyn/codegen/_plugins/__init__.py +0 -0
  20. {cadwyn-3.14.0 → cadwyn-3.15.1}/cadwyn/codegen/_plugins/class_migrations.py +0 -0
  21. {cadwyn-3.14.0 → cadwyn-3.15.1}/cadwyn/codegen/_plugins/class_rebuilding.py +0 -0
  22. {cadwyn-3.14.0 → cadwyn-3.15.1}/cadwyn/codegen/_plugins/class_renaming.py +0 -0
  23. {cadwyn-3.14.0 → cadwyn-3.15.1}/cadwyn/codegen/_plugins/import_auto_adding.py +0 -0
  24. {cadwyn-3.14.0 → cadwyn-3.15.1}/cadwyn/codegen/_plugins/module_migrations.py +0 -0
  25. {cadwyn-3.14.0 → cadwyn-3.15.1}/cadwyn/exceptions.py +0 -0
  26. {cadwyn-3.14.0 → cadwyn-3.15.1}/cadwyn/main.py +0 -0
  27. {cadwyn-3.14.0 → cadwyn-3.15.1}/cadwyn/middleware.py +0 -0
  28. {cadwyn-3.14.0 → cadwyn-3.15.1}/cadwyn/py.typed +0 -0
  29. {cadwyn-3.14.0 → cadwyn-3.15.1}/cadwyn/static/__init__.py +0 -0
  30. {cadwyn-3.14.0 → cadwyn-3.15.1}/cadwyn/static/docs.html +0 -0
  31. {cadwyn-3.14.0 → cadwyn-3.15.1}/cadwyn/structure/__init__.py +0 -0
  32. {cadwyn-3.14.0 → cadwyn-3.15.1}/cadwyn/structure/common.py +0 -0
  33. {cadwyn-3.14.0 → cadwyn-3.15.1}/cadwyn/structure/data.py +0 -0
  34. {cadwyn-3.14.0 → cadwyn-3.15.1}/cadwyn/structure/endpoints.py +0 -0
  35. {cadwyn-3.14.0 → cadwyn-3.15.1}/cadwyn/structure/enums.py +0 -0
  36. {cadwyn-3.14.0 → cadwyn-3.15.1}/cadwyn/structure/modules.py +0 -0
  37. {cadwyn-3.14.0 → cadwyn-3.15.1}/cadwyn/structure/schemas.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cadwyn
3
- Version: 3.14.0
3
+ Version: 3.15.1
4
4
  Summary: Production-ready community-driven modern Stripe-like API versioning in FastAPI
5
5
  Home-page: https://github.com/zmievsa/cadwyn
6
6
  License: MIT
@@ -54,8 +54,8 @@ Production-ready community-driven modern [Stripe-like](https://stripe.com/blog/a
54
54
  <a href="https://github.com/zmievsa/cadwyn/actions/workflows/ci.yaml?branch=main&event=push" target="_blank">
55
55
  <img src="https://github.com/zmievsa/cadwyn/actions/workflows/ci.yaml/badge.svg?branch=main&event=push" alt="Test">
56
56
  </a>
57
- <a href="https://codecov.io/gh/ovsyanka83/cadwyn" target="_blank">
58
- <img src="https://img.shields.io/codecov/c/github/ovsyanka83/cadwyn?color=%2334D058&logo=codecov" alt="Coverage">
57
+ <a href="https://codecov.io/gh/zmievsa/cadwyn" target="_blank">
58
+ <img src="https://img.shields.io/codecov/c/github/zmievsa/cadwyn?color=%2334D058&logo=codecov" alt="Coverage">
59
59
  </a>
60
60
  <a href="https://pypi.org/project/cadwyn/" target="_blank">
61
61
  <img alt="PyPI" src="https://img.shields.io/pypi/v/cadwyn?color=%2334D058&logo=pypi&label=PyPI package" alt="Package version">
@@ -8,8 +8,8 @@ Production-ready community-driven modern [Stripe-like](https://stripe.com/blog/a
8
8
  <a href="https://github.com/zmievsa/cadwyn/actions/workflows/ci.yaml?branch=main&event=push" target="_blank">
9
9
  <img src="https://github.com/zmievsa/cadwyn/actions/workflows/ci.yaml/badge.svg?branch=main&event=push" alt="Test">
10
10
  </a>
11
- <a href="https://codecov.io/gh/ovsyanka83/cadwyn" target="_blank">
12
- <img src="https://img.shields.io/codecov/c/github/ovsyanka83/cadwyn?color=%2334D058&logo=codecov" alt="Coverage">
11
+ <a href="https://codecov.io/gh/zmievsa/cadwyn" target="_blank">
12
+ <img src="https://img.shields.io/codecov/c/github/zmievsa/cadwyn?color=%2334D058&logo=codecov" alt="Coverage">
13
13
  </a>
14
14
  <a href="https://pypi.org/project/cadwyn/" target="_blank">
15
15
  <img alt="PyPI" src="https://img.shields.io/pypi/v/cadwyn?color=%2334D058&logo=pypi&label=PyPI package" alt="Package version">
@@ -2,7 +2,11 @@ import importlib.metadata
2
2
 
3
3
  from .applications import Cadwyn
4
4
  from .codegen import generate_code_for_versioned_packages
5
- from .route_generation import InternalRepresentationOf, VersionedAPIRouter, generate_versioned_routers
5
+ from .route_generation import (
6
+ InternalRepresentationOf, # pyright: ignore[reportDeprecated]
7
+ VersionedAPIRouter,
8
+ generate_versioned_routers,
9
+ )
6
10
  from .structure import VersionBundle
7
11
 
8
12
  __version__ = importlib.metadata.version("cadwyn")
@@ -60,7 +60,7 @@ def deprecated_generate_versioned_packages(
60
60
  possibly_version_bundle = getattr(version_bundle_module, version_bundle_variable_name)
61
61
  version_bundle = _get_version_bundle(possibly_version_bundle)
62
62
 
63
- return generate_code_for_versioned_packages(
63
+ return generate_code_for_versioned_packages( # pyright: ignore[reportDeprecated]
64
64
  template_package,
65
65
  version_bundle,
66
66
  ignore_coverage_for_latest_aliases=ignore_coverage_for_latest_aliases,
@@ -7,9 +7,14 @@ from typing import Any, cast
7
7
 
8
8
  from fastapi import APIRouter, FastAPI, HTTPException, routing
9
9
  from fastapi.datastructures import Default
10
- from fastapi.openapi.docs import get_redoc_html, get_swagger_ui_html
10
+ from fastapi.openapi.docs import (
11
+ get_redoc_html,
12
+ get_swagger_ui_html,
13
+ get_swagger_ui_oauth2_redirect_html,
14
+ )
11
15
  from fastapi.openapi.utils import get_openapi
12
16
  from fastapi.params import Depends
17
+ from fastapi.responses import HTMLResponse
13
18
  from fastapi.templating import Jinja2Templates
14
19
  from fastapi.utils import generate_unique_id
15
20
  from starlette.middleware import Middleware
@@ -19,7 +24,6 @@ from starlette.routing import BaseRoute, Route
19
24
  from starlette.types import Lifespan
20
25
  from typing_extensions import Self, deprecated
21
26
 
22
- from cadwyn._utils import same_definition_as_in
23
27
  from cadwyn.middleware import HeaderVersioningMiddleware, _get_api_version_dependency
24
28
  from cadwyn.route_generation import generate_versioned_routers
25
29
  from cadwyn.routing import _RootHeaderAPIRouter
@@ -139,6 +143,8 @@ class Cadwyn(FastAPI):
139
143
  api_version_var=self.versions.api_version_var,
140
144
  )
141
145
 
146
+ self.add_event_handler("startup", self.enrich_swagger)
147
+
142
148
  self.docs_url = docs_url
143
149
  self.redoc_url = redoc_url
144
150
  self.openapi_url = openapi_url
@@ -178,6 +184,18 @@ class Cadwyn(FastAPI):
178
184
  endpoint=self.swagger_dashboard,
179
185
  include_in_schema=False,
180
186
  )
187
+ if self.swagger_ui_oauth2_redirect_url:
188
+
189
+ async def swagger_ui_redirect(req: Request) -> HTMLResponse:
190
+ return (
191
+ get_swagger_ui_oauth2_redirect_html() # pragma: no cover # unimportant right now but # TODO
192
+ )
193
+
194
+ self.add_route(
195
+ self.swagger_ui_oauth2_redirect_url,
196
+ swagger_ui_redirect,
197
+ include_in_schema=False,
198
+ )
181
199
  if self.redoc_url is not None:
182
200
  unversioned_router.add_route(
183
201
  path=self.redoc_url,
@@ -247,20 +265,38 @@ class Cadwyn(FastAPI):
247
265
  return JSONResponse(openapi_of_a_version)
248
266
 
249
267
  async def swagger_dashboard(self, req: Request) -> Response:
250
- return self._render_docs_dashboard_or_concrete_verssion(get_swagger_ui_html, req, cast(str, self.docs_url))
268
+ version = req.query_params.get("version")
251
269
 
252
- async def redoc_dashboard(self, req: Request) -> Response:
253
- return self._render_docs_dashboard_or_concrete_verssion(get_redoc_html, req, cast(str, self.redoc_url))
270
+ if version:
271
+ root_path = self._extract_root_path(req)
272
+ openapi_url = root_path + f"{self.openapi_url}?version={version}"
273
+ oauth2_redirect_url = self.swagger_ui_oauth2_redirect_url
274
+ if oauth2_redirect_url:
275
+ oauth2_redirect_url = root_path + oauth2_redirect_url
276
+ return get_swagger_ui_html(
277
+ openapi_url=openapi_url,
278
+ title=f"{self.title} - Swagger UI",
279
+ oauth2_redirect_url=oauth2_redirect_url,
280
+ init_oauth=self.swagger_ui_init_oauth,
281
+ swagger_ui_parameters=self.swagger_ui_parameters,
282
+ )
283
+ return self._render_docs_dashboard(req, cast(str, self.docs_url))
254
284
 
255
- def _render_docs_dashboard_or_concrete_verssion(self, render_docs: Callable[..., Any], req: Request, docs_url: str):
256
- base_url = str(req.base_url).rstrip("/")
285
+ async def redoc_dashboard(self, req: Request) -> Response:
257
286
  version = req.query_params.get("version")
258
287
 
259
288
  if version:
260
- return render_docs(
261
- openapi_url=f"{self.openapi_url}?version={version}",
262
- title="Swagger UI",
263
- )
289
+ root_path = self._extract_root_path(req)
290
+ openapi_url = root_path + f"{self.openapi_url}?version={version}"
291
+ return get_redoc_html(openapi_url=openapi_url, title=f"{self.title} - ReDoc")
292
+
293
+ return self._render_docs_dashboard(req, docs_url=cast(str, self.redoc_url))
294
+
295
+ def _extract_root_path(self, req: Request):
296
+ return req.scope.get("root_path", "").rstrip("/")
297
+
298
+ def _render_docs_dashboard(self, req: Request, docs_url: str):
299
+ base_url = str(req.base_url).rstrip("/")
264
300
  return self._templates.TemplateResponse(
265
301
  "docs.html",
266
302
  {
@@ -297,91 +333,11 @@ class Cadwyn(FastAPI):
297
333
  dependencies=[Depends(_get_api_version_dependency(self.router.api_version_header_name, header_value))],
298
334
  )
299
335
 
300
- self.enrich_swagger()
301
336
  return added_routes
302
337
 
303
- @same_definition_as_in(FastAPI.include_router)
304
- def include_router(self, *args: Any, **kwargs: Any):
305
- route = super().include_router(*args, **kwargs)
306
- self.enrich_swagger()
307
- return route
308
-
309
- @same_definition_as_in(FastAPI.post)
310
- def post(self, *args: Any, **kwargs: Any):
311
- route = super().post(*args, **kwargs)
312
- self.enrich_swagger()
313
- return route
314
-
315
- @same_definition_as_in(FastAPI.get)
316
- def get(self, *args: Any, **kwargs: Any):
317
- route = super().get(*args, **kwargs)
318
- self.enrich_swagger()
319
- return route
320
-
321
- @same_definition_as_in(FastAPI.patch)
322
- def patch(self, *args: Any, **kwargs: Any):
323
- route = super().patch(*args, **kwargs)
324
- self.enrich_swagger()
325
- return route
326
-
327
- @same_definition_as_in(FastAPI.delete)
328
- def delete(self, *args: Any, **kwargs: Any):
329
- route = super().delete(*args, **kwargs)
330
- self.enrich_swagger()
331
- return route
332
-
333
- @same_definition_as_in(FastAPI.put)
334
- def put(self, *args: Any, **kwargs: Any):
335
- route = super().put(*args, **kwargs)
336
- self.enrich_swagger()
337
- return route
338
-
339
- @same_definition_as_in(FastAPI.trace)
340
- def trace(self, *args: Any, **kwargs: Any): # pragma: no cover
341
- route = super().trace(*args, **kwargs)
342
- self.enrich_swagger()
343
- return route
344
-
345
- @same_definition_as_in(FastAPI.options)
346
- def options(self, *args: Any, **kwargs: Any):
347
- route = super().options(*args, **kwargs)
348
- self.enrich_swagger()
349
- return route
350
-
351
- @same_definition_as_in(FastAPI.head)
352
- def head(self, *args: Any, **kwargs: Any):
353
- route = super().head(*args, **kwargs)
354
- self.enrich_swagger()
355
- return route
356
-
357
- @same_definition_as_in(FastAPI.add_api_route)
358
- def add_api_route(self, *args: Any, **kwargs: Any):
359
- route = super().add_api_route(*args, **kwargs)
360
- self.enrich_swagger()
361
- return route
362
-
363
- @same_definition_as_in(FastAPI.api_route)
364
- def api_route(self, *args: Any, **kwargs: Any):
365
- route = super().api_route(*args, **kwargs)
366
- self.enrich_swagger()
367
- return route
368
-
369
- @same_definition_as_in(FastAPI.add_api_websocket_route)
370
- def add_api_websocket_route(self, *args: Any, **kwargs: Any): # pragma: no cover
371
- route = super().add_api_websocket_route(*args, **kwargs)
372
- self.enrich_swagger()
373
- return route
374
-
375
- @same_definition_as_in(FastAPI.websocket)
376
- def websocket(self, *args: Any, **kwargs: Any): # pragma: no cover
377
- route = super().websocket(*args, **kwargs)
378
- self.enrich_swagger()
379
- return route
380
-
381
338
  def add_unversioned_routers(self, *routers: APIRouter):
382
339
  for router in routers:
383
340
  self.router.include_router(router)
384
- self.enrich_swagger()
385
341
 
386
342
  @deprecated("Use add add_unversioned_routers instead")
387
343
  def add_unversioned_routes(self, *routes: Route):
@@ -452,7 +452,10 @@ def _extract_internal_request_schemas_from_router(
452
452
  for key, annotation in annotations.items():
453
453
  if isinstance(annotation, type(Annotated[int, int])):
454
454
  args = get_args(annotation)
455
- if isinstance(args[1], type) and issubclass(args[1], InternalRepresentationOf): # pragma: no branch
455
+ if isinstance(args[1], type) and issubclass( # pragma: no branch
456
+ args[1],
457
+ InternalRepresentationOf, # pyright: ignore[reportDeprecated]
458
+ ):
456
459
  internal_schema = args[0]
457
460
  original_schema = args[1].mro()[2]
458
461
  schema_to_internal_request_body_representation[original_schema] = internal_schema
@@ -12,7 +12,7 @@ from starlette.responses import RedirectResponse
12
12
  from starlette.routing import BaseRoute, Match
13
13
  from starlette.types import Receive, Scope, Send
14
14
 
15
- from .route_generation import InternalRepresentationOf, generate_versioned_routers
15
+ from .route_generation import InternalRepresentationOf, generate_versioned_routers # pyright: ignore[reportDeprecated]
16
16
 
17
17
  # TODO: Remove this in a major version. This is only here for backwards compatibility
18
18
  __all__ = ["InternalRepresentationOf", "generate_versioned_routers"]
@@ -420,7 +420,7 @@ class VersionBundle:
420
420
  versioned_response_model: type[BaseModel] = get_another_version_of_cls(
421
421
  latest_response_model, version_dir, self.versioned_directories_with_head
422
422
  )
423
- return versioned_response_model.parse_obj(migrated_response.body)
423
+ return versioned_response_model.parse_obj(migrated_response.body) # pyright: ignore[reportDeprecated]
424
424
 
425
425
  def _get_closest_lesser_version(self, version: VersionDate):
426
426
  for defined_version in self.version_dates:
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "cadwyn"
3
- version = "3.14.0"
3
+ version = "3.15.1"
4
4
  description = "Production-ready community-driven modern Stripe-like API versioning in FastAPI"
5
5
  authors = ["Stanislav Zmiev <zmievsa@gmail.com>"]
6
6
  license = "MIT"
@@ -55,7 +55,7 @@ typing-extensions = "*"
55
55
  fastapi = ">=0.110.0"
56
56
  starlette = ">=0.36.3"
57
57
  pydantic = ">=1.0.0"
58
- typer = {version = ">=0.7.0", optional = true}
58
+ typer = { version = ">=0.7.0", optional = true }
59
59
  better-ast-comments = "~1.2.1"
60
60
  jinja2 = ">=3.1.2"
61
61
  issubclass = "^0.1.2"
@@ -104,7 +104,13 @@ exclude_lines = [
104
104
  "__rich_repr__",
105
105
  "__repr__",
106
106
  ]
107
- omit = ["./docs/plugin.py", "./site/plugin.py", "./tests/_data/_temp/**/*", "tests/tutorial/data/**/*", "scripts/*.py"]
107
+ omit = [
108
+ "./docs/plugin.py",
109
+ "./site/plugin.py",
110
+ "./tests/_data/_temp/**/*",
111
+ "tests/tutorial/data/**/*",
112
+ "scripts/*.py",
113
+ ]
108
114
 
109
115
  [tool.pyright]
110
116
  reportMissingImports = true
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes