Skip to content

Commit

Permalink
Provide more extensibility for header-routing defaults
Browse files Browse the repository at this point in the history
  • Loading branch information
zmievsa committed Mar 5, 2024
1 parent ce6bc39 commit a75099e
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 6 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ Please follow [the Keep a Changelog standard](https://keepachangelog.com/en/1.0.

## [Unreleased]

## [3.11.0]

### Changed

* Header router is no longer reliant on the API version header -- now it simply takes the API version from the `VersionBundle.api_version_var`, thus making it easy for someone to extend header routing and set their own rules for how the default version is chosen

## [3.10.1]

### Fixed
Expand Down
1 change: 1 addition & 0 deletions cadwyn/applications.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ def __init__(
deprecated=deprecated,
responses=responses,
api_version_header_name=api_version_header_name,
api_version_var=self.versions.api_version_var,
lifespan=lifespan,
)
self.docs_url = docs_url
Expand Down
15 changes: 10 additions & 5 deletions cadwyn/routing.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import bisect
from collections import OrderedDict
from collections.abc import Sequence
from contextvars import ContextVar
from datetime import date
from functools import cached_property
from logging import getLogger
Expand Down Expand Up @@ -35,11 +36,18 @@ class _RootHeaderAPIRouter(APIRouter):
matched to the higher versioned route
"""

def __init__(self, *args: Any, api_version_header_name: str, **kwargs: Any):
def __init__(
self,
*args: Any,
api_version_header_name: str,
api_version_var: ContextVar[date] | ContextVar[date | None],
**kwargs: Any,
):
super().__init__(*args, **kwargs)
self.versioned_routes: dict[date, list[BaseRoute]] = {}
self.unversioned_routes: list[BaseRoute] = []
self.api_version_header_name = api_version_header_name.lower()
self.api_version_var = api_version_var

@cached_property
def sorted_versioned_routes(self):
Expand Down Expand Up @@ -90,10 +98,7 @@ async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
await self.lifespan(scope, receive, send)
return

request_headers = dict(scope["headers"])
header_value = request_headers.get(self.api_version_header_name.encode(), b"").decode()
if header_value:
header_value = date.fromisoformat(header_value)
header_value = self.api_version_var.get(None)

# if header_value is None, then it's an unversioned request and we need to use the unversioned routes
# if there will be a value, we search for the most suitable version
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "cadwyn"
version = "3.10.1"
version = "3.11.0"
description = "Production-ready community-driven modern Stripe-like API versioning in FastAPI"
authors = ["Stanislav Zmiev <zmievsa@gmail.com>"]
license = "MIT"
Expand Down

0 comments on commit a75099e

Please sign in to comment.