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
13 changes: 6 additions & 7 deletions .github/workflows/_checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ jobs:
with:
enable-cache: true
cache-dependency-glob: "**/pyproject.toml"
- run: uv python install 3.10
- run: uv python pin 3.10
- run: uv python install 3.11
- run: uv python pin 3.11
- run: just install lint-ci
- run: just adr-check

Expand Down Expand Up @@ -49,7 +49,6 @@ jobs:
fail-fast: false
matrix:
python-version:
- "3.10"
- "3.11"
- "3.12"
- "3.13"
Expand Down Expand Up @@ -96,7 +95,7 @@ jobs:
with:
enable-cache: true
cache-dependency-glob: "**/pyproject.toml"
- run: uv python install 3.10
- run: uv python install 3.11
- name: Each extra installs and imports in isolation
run: |
set -uo pipefail
Expand All @@ -110,12 +109,12 @@ jobs:
faststream faststream-sentry faststream-otl faststream-logging faststream-metrics faststream-all \
fastmcp fastmcp-metrics fastmcp-all"
failed=""
uv venv --python 3.10 .v-bare >/dev/null
uv venv --python 3.11 .v-bare >/dev/null
if uv pip install --python .v-bare/bin/python . >/dev/null 2>&1 \
&& .v-bare/bin/python -c "import lite_bootstrap"; then :; else failed="$failed __bare__"; fi
rm -rf .v-bare
for e in $extras; do
uv venv --python 3.10 ".v-$e" >/dev/null
uv venv --python 3.11 ".v-$e" >/dev/null
if uv pip install --python ".v-$e/bin/python" ".[$e]" >/dev/null 2>&1 \
&& ".v-$e/bin/python" -c "import lite_bootstrap"; then :; else failed="$failed $e"; fi
rm -rf ".v-$e"
Expand All @@ -138,7 +137,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
python-version: ["3.11", "3.12", "3.13", "3.14"]
target: [free, fastapi, litestar, faststream, fastmcp]
# These `include` entries name an existing `target`, so each adds `extras` to that
# target's five combinations rather than creating a job of its own. `free` carries
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/security-audit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
with:
enable-cache: true
cache-dependency-glob: "**/pyproject.toml"
- run: uv python install 3.10
- run: uv python install 3.11
- name: Export locked dependencies
run: uv export --all-extras --no-hashes > /tmp/requirements.txt
- name: Install pip-audit
Expand Down
6 changes: 2 additions & 4 deletions lite_bootstrap/instruments/base.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import dataclasses
import typing

import typing_extensions


@dataclasses.dataclass(kw_only=True, slots=True, frozen=True)
class BaseConfig:
Expand All @@ -21,13 +19,13 @@ def __post_init__(self) -> None:
"""

@classmethod
def from_dict(cls, data: dict[str, typing.Any]) -> typing_extensions.Self:
def from_dict(cls, data: dict[str, typing.Any]) -> typing.Self:
"""Build a config from a dict; unknown keys are silently dropped, explicit None overrides defaults."""
field_names = {f.name for f in dataclasses.fields(cls)}
return cls(**{k: v for k, v in data.items() if k in field_names})

@classmethod
def from_object(cls, obj: object) -> typing_extensions.Self:
def from_object(cls, obj: object) -> typing.Self:
"""Build a config by merging non-None attributes from obj; None or missing attributes fall back to defaults."""
field_names = {f.name for f in dataclasses.fields(cls)}
prepared_data = {field: value for field in field_names if (value := getattr(obj, field, None)) is not None}
Expand Down
13 changes: 5 additions & 8 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,12 @@ authors = [
{ name = "Artur Shiriev", email = "me@shiriev.ru" },
]
readme = "README.md"
requires-python = ">=3.10,<4"
requires-python = ">=3.11,<4"
license = "MIT"
keywords = ["microservices", "bootstrap", "opentelemetry", "sentry", "prometheus", "healthcheck", "fastapi", "litestar", "faststream", "structlog", "fastmcp", "python"]
classifiers = [
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Developers",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
Expand All @@ -21,11 +20,9 @@ classifiers = [
]
version = "0"
dependencies = [
# Runtime use: `typing_extensions.Self` (base.py) and `typing_extensions.TypedDict`
# (healthchecks) — the latter is required by pydantic/FastAPI on Python < 3.12
# (`typing.TypedDict` is rejected there). Pure Python, so ft-friendly.
# >=4.0 for `Self`; >=4.6 because 4.4 and 4.5 raise on import under Python >=3.12
# (they subclass `typing.TypeVar`). The higher floor wins.
# Runtime use: `typing_extensions.TypedDict` (healthchecks), required by pydantic/FastAPI on
# Python < 3.12 (`typing.TypedDict` is rejected there). Pure Python, so ft-friendly.
# >=4.6 because 4.4 and 4.5 raise on import under Python >=3.12 (they subclass `typing.TypeVar`).
"typing-extensions>=4.6",
]

Expand All @@ -49,7 +46,7 @@ sentry = [
# >=1.31 for the `max_value_length` init option; >=2.1 for sentry_sdk.set_tags (plural,
# SentryInstrument.bootstrap) -- the higher floor wins.
# 2.1 predates Python 3.13's FrameLocalsProxy, which the SDK fails to pickle when capturing a
# request, and 3.14 needs later fixes again. Marked rather than raised, so 3.10-3.12 keep 2.1.
# request, and 3.14 needs later fixes again. Marked rather than raised, so 3.11-3.12 keep 2.1.
# 2.69.0 signs `sentry-trace`/`baggage` into SigV4 SignedHeaders and then rewrites them after
# signing, so every aiobotocore AWS call inside a transaction fails with SignatureDoesNotMatch
# (getsentry/sentry-python#7426, fixed in 2.69.1).
Expand Down
Loading