Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 15 additions & 5 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,27 @@ Please follow [the Keep a Changelog standard](https://keepachangelog.com/en/1.0.

## [Unreleased]

## [4.2.0]

### Added

* Automatic changelog generation from version changes using `Cadwyn.generate_changelog` method and `GET /changelog` endpoint.
* Automatic creation of versioned_routers based on the `VersionBundle` passed to `Cadwyn` which means that all versions mentioned in the version bundle will already be available for routing even without the use of `generate_and_include_versioned_routers`

## Changed

* Renamed `Version.version_changes` to `Version.changes`

### Removed

* `regex`, `include`, `min_items`, `max_items`, and `unique_items` arguments were removed from `schema(...).field(...).had`. Notice that it's not a breaking change for most cases because passing these arguments caused exceptions

## [4.1.0]

### Added

* Exposed `cadwyn.generate_versioned_models` that allow you to generate pydantic models and enums even without a FastAPI app


## [4.0.0]

Versions 3.x.x are still supported in terms of bug and security fixes but all the new features will go into versions 4.x.x.
Expand Down Expand Up @@ -39,7 +53,6 @@ Versions 3.x.x are still supported in terms of bug and security fixes but all th
* `VersionBundle.migrate_response_body` is no longer a method of `VersionBundle` and is now importable directly from `cadwyn` as a function
* `cadwyn.structure` is no longer recommended to be used directly because everything from it is now available in `cadwyn` directly


## [3.15.8]

### Fixed
Expand Down Expand Up @@ -71,7 +84,6 @@ Versions 3.x.x are still supported in terms of bug and security fixes but all th

* Fix dependency overrides not working for versioned routes


## [3.15.4]

### Changed
Expand All @@ -82,7 +94,6 @@ Versions 3.x.x are still supported in terms of bug and security fixes but all th

* fastapi-pagination now does not require an explicit call to `Cadwyn.enrich_swagger`


## [3.15.3]

### Changed
Expand All @@ -94,7 +105,6 @@ Versions 3.x.x are still supported in terms of bug and security fixes but all th
* Compatibility with fastapi-pagination
* High cardinality of metrics for routers with path variables in starlette-exporter


## [3.15.2]

### Fixed
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ lint:
pre-commit run --all-files

format:
poetry run ruff . --fix && poetry run ruff format .;
poetry run ruff check . --fix && poetry run ruff format .;

test:
rm -f .coverage coverage.xml; \
Expand Down
2 changes: 2 additions & 0 deletions cadwyn/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import importlib.metadata

from .applications import Cadwyn
from .changelogs import hidden
from .route_generation import VersionedAPIRouter, generate_versioned_routers
from .schema_generation import generate_versioned_models, migrate_response_body
from .structure import (
Expand Down Expand Up @@ -37,4 +38,5 @@
"RequestInfo",
"ResponseInfo",
"generate_versioned_models",
"hidden",
]
4 changes: 2 additions & 2 deletions cadwyn/_render.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from cadwyn.schema_generation import (
PydanticFieldWrapper,
_EnumWrapper,
_PydanticRuntimeModelWrapper,
_PydanticModelWrapper,
generate_versioned_models,
)
from cadwyn.structure.versions import VersionBundle, get_cls_pythonpath
Expand Down Expand Up @@ -107,7 +107,7 @@ def _render_enum_model(wrapper: _EnumWrapper, original_cls_node: ast.ClassDef):
return original_cls_node


def _render_pydantic_model(wrapper: _PydanticRuntimeModelWrapper, original_cls_node: ast.ClassDef):
def _render_pydantic_model(wrapper: _PydanticModelWrapper, original_cls_node: ast.ClassDef):
# This is for possible schema renaming
original_cls_node.name = wrapper.name

Expand Down
27 changes: 25 additions & 2 deletions cadwyn/applications.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
from starlette.types import Lifespan
from typing_extensions import Self

from cadwyn.changelogs import CadwynChangelogResource, _generate_changelog
from cadwyn.middleware import HeaderVersioningMiddleware, _get_api_version_dependency
from cadwyn.route_generation import generate_versioned_routers
from cadwyn.routing import _RootHeaderAPIRouter
Expand All @@ -47,6 +48,8 @@ def __init__(
*,
versions: VersionBundle,
api_version_header_name: str = "x-api-version",
changelog_url: str | None = "/changelog",
include_changelog_url_in_schema: bool = True,
debug: bool = False,
title: str = "FastAPI",
summary: str | None = None,
Expand Down Expand Up @@ -154,13 +157,17 @@ def __init__(
api_version_var=self.versions.api_version_var,
)

self.changelog_url = changelog_url
self.include_changelog_url_in_schema = include_changelog_url_in_schema

self.docs_url = docs_url
self.redoc_url = redoc_url
self.openapi_url = openapi_url
self.redoc_url = redoc_url

unversioned_router = APIRouter(**self._kwargs_to_router)
self._add_openapi_endpoints(unversioned_router)
self._add_utility_endpoints(unversioned_router)
self._add_default_versioned_routers()
self.include_router(unversioned_router)
self.add_middleware(
HeaderVersioningMiddleware,
Expand All @@ -169,6 +176,10 @@ def __init__(
default_response_class=default_response_class,
)

def _add_default_versioned_routers(self) -> None:
for version in self.versions:
self.router.versioned_routers[version.value] = APIRouter(**self._kwargs_to_router)

@property
def dependency_overrides(self) -> dict[Callable[..., Any], Callable[..., Any]]:
# TODO: Remove this approach as it is no longer necessary
Expand All @@ -184,7 +195,19 @@ def dependency_overrides( # pyright: ignore[reportIncompatibleVariableOverride]
) -> None:
self._dependency_overrides_provider.dependency_overrides = value

def _add_openapi_endpoints(self, unversioned_router: APIRouter):
def generate_changelog(self) -> CadwynChangelogResource:
return _generate_changelog(self.versions, self.router)

def _add_utility_endpoints(self, unversioned_router: APIRouter):
if self.changelog_url is not None:
unversioned_router.add_api_route(
path=self.changelog_url,
endpoint=self.generate_changelog,
response_model=CadwynChangelogResource,
methods=["GET"],
include_in_schema=self.include_changelog_url_in_schema,
)

if self.openapi_url is not None:
unversioned_router.add_route(
path=self.openapi_url,
Expand Down
Loading
Loading