fastapi-commons 0.8.4__tar.gz → 0.8.6__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.
Files changed (45) hide show
  1. fastapi_commons-0.8.6/AUTHORS.md +3 -0
  2. fastapi_commons-0.8.4/CHANGELOG.rst → fastapi_commons-0.8.6/CHANGELOG.md +3 -8
  3. fastapi_commons-0.8.6/PKG-INFO +212 -0
  4. fastapi_commons-0.8.6/README.md +179 -0
  5. fastapi_commons-0.8.6/pyproject.toml +170 -0
  6. fastapi_commons-0.8.4/pyproject.toml → fastapi_commons-0.8.6/pyproject.toml.orig +15 -24
  7. fastapi_commons-0.8.4/.coveragerc +0 -28
  8. fastapi_commons-0.8.4/.env_template +0 -7
  9. fastapi_commons-0.8.4/.github/workflows/checks.yml +0 -63
  10. fastapi_commons-0.8.4/.github/workflows/python-publish.yaml +0 -47
  11. fastapi_commons-0.8.4/.github/workflows/release-on-tag-push.yml +0 -52
  12. fastapi_commons-0.8.4/.gitignore +0 -52
  13. fastapi_commons-0.8.4/.pre-commit-config.yaml +0 -35
  14. fastapi_commons-0.8.4/.python-version +0 -1
  15. fastapi_commons-0.8.4/AUTHORS.rst +0 -5
  16. fastapi_commons-0.8.4/PKG-INFO +0 -36
  17. fastapi_commons-0.8.4/README.md +0 -2
  18. fastapi_commons-0.8.4/README.rst +0 -4
  19. fastapi_commons-0.8.4/setup.cfg +0 -4
  20. fastapi_commons-0.8.4/src/fastapi_commons.egg-info/PKG-INFO +0 -36
  21. fastapi_commons-0.8.4/src/fastapi_commons.egg-info/SOURCES.txt +0 -39
  22. fastapi_commons-0.8.4/src/fastapi_commons.egg-info/dependency_links.txt +0 -1
  23. fastapi_commons-0.8.4/src/fastapi_commons.egg-info/requires.txt +0 -16
  24. fastapi_commons-0.8.4/src/fastapi_commons.egg-info/scm_file_list.json +0 -36
  25. fastapi_commons-0.8.4/src/fastapi_commons.egg-info/scm_version.json +0 -8
  26. fastapi_commons-0.8.4/src/fastapi_commons.egg-info/top_level.txt +0 -1
  27. fastapi_commons-0.8.4/uv.lock +0 -1890
  28. {fastapi_commons-0.8.4 → fastapi_commons-0.8.6}/LICENSE +0 -0
  29. {fastapi_commons-0.8.4 → fastapi_commons-0.8.6}/src/fastapi_commons/__init__.py +0 -0
  30. {fastapi_commons-0.8.4 → fastapi_commons-0.8.6}/src/fastapi_commons/auth.py +0 -0
  31. {fastapi_commons-0.8.4 → fastapi_commons-0.8.6}/src/fastapi_commons/conf.py +0 -0
  32. {fastapi_commons-0.8.4 → fastapi_commons-0.8.6}/src/fastapi_commons/handlers.py +0 -0
  33. {fastapi_commons-0.8.4 → fastapi_commons-0.8.6}/src/fastapi_commons/helpers.py +0 -0
  34. {fastapi_commons-0.8.4 → fastapi_commons-0.8.6}/src/fastapi_commons/instrumentation.py +0 -0
  35. {fastapi_commons-0.8.4 → fastapi_commons-0.8.6}/src/fastapi_commons/log/__init__.py +0 -0
  36. {fastapi_commons-0.8.4 → fastapi_commons-0.8.6}/src/fastapi_commons/log/filters.py +0 -0
  37. {fastapi_commons-0.8.4 → fastapi_commons-0.8.6}/src/fastapi_commons/middleware/__init__.py +0 -0
  38. {fastapi_commons-0.8.4 → fastapi_commons-0.8.6}/src/fastapi_commons/middleware/correlation_id.py +0 -0
  39. {fastapi_commons-0.8.4 → fastapi_commons-0.8.6}/src/fastapi_commons/middleware/log_context.py +0 -0
  40. {fastapi_commons-0.8.4 → fastapi_commons-0.8.6}/src/fastapi_commons/middleware/prometheus.py +0 -0
  41. {fastapi_commons-0.8.4 → fastapi_commons-0.8.6}/tests/__init__.py +0 -0
  42. {fastapi_commons-0.8.4 → fastapi_commons-0.8.6}/tests/conftest.py +0 -0
  43. {fastapi_commons-0.8.4 → fastapi_commons-0.8.6}/tests/unit/__init__.py +0 -0
  44. {fastapi_commons-0.8.4 → fastapi_commons-0.8.6}/tests/unit/test_auth.py +0 -0
  45. {fastapi_commons-0.8.4 → fastapi_commons-0.8.6}/tests/unit/test_poc.py +0 -0
@@ -0,0 +1,3 @@
1
+ # Contributors
2
+
3
+ - Oleg Korsak <kamikaze.is.waiting.you@gmail.com>
@@ -1,14 +1,9 @@
1
- =========
2
- Changelog
3
- =========
1
+ # Changelog
4
2
 
5
- Version 0.1.0
6
- =============
3
+ ## Version 0.1.0
7
4
 
8
5
  - Breaking change: made absolute path generation for object storage to be optional.
9
6
 
10
-
11
- Version 0.0.1
12
- =============
7
+ ## Version 0.0.1
13
8
 
14
9
  - Initial commit
@@ -0,0 +1,212 @@
1
+ Metadata-Version: 2.4
2
+ Name: fastapi-commons
3
+ Version: 0.8.6
4
+ Summary: Re-usable FastAPI code
5
+ Keywords:
6
+ Author: Oleg Korsak
7
+ Author-email: Oleg Korsak <kamikaze.is.waiting.you@gmail.com>
8
+ License-Expression: GPL-3.0-only
9
+ License-File: AUTHORS.md
10
+ License-File: LICENSE
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Programming Language :: Python
13
+ Requires-Dist: aiohttp[speedups]>=3.14.3,<3.15.0
14
+ Requires-Dist: asyncpg~=0.31.0
15
+ Requires-Dist: fastapi~=0.141.1
16
+ Requires-Dist: msgspec~=0.21.1
17
+ Requires-Dist: pydantic[email]~=2.13.5
18
+ Requires-Dist: pydantic-settings~=2.15.0
19
+ Requires-Dist: python-jose~=3.5.0
20
+ Requires-Dist: sqlalchemy[asyncio]~=2.1.1
21
+ Requires-Dist: opentelemetry-api~=1.45.0
22
+ Requires-Dist: opentelemetry-sdk~=1.45.0
23
+ Requires-Dist: opentelemetry-exporter-otlp~=1.45.0
24
+ Requires-Dist: opentelemetry-instrumentation-fastapi~=0.65b0
25
+ Requires-Dist: opentelemetry-instrumentation-logging~=0.65b0
26
+ Requires-Dist: prometheus-client~=0.26.0
27
+ Requires-Dist: python3-commons[authn]~=0.24.6
28
+ Requires-Dist: starlette~=1.7.0
29
+ Requires-Python: >=3.14.0, <3.15.0
30
+ Project-URL: Homepage, https://github.com/kamikaze/fastapi-commons
31
+ Project-URL: Documentation, https://github.com/kamikaze/fastapi-commons/wiki
32
+ Description-Content-Type: text/markdown
33
+
34
+ # fastapi-commons
35
+
36
+ Common utilities, middleware, security, and observability helpers for production-ready [FastAPI](https://fastapi.tiangolo.com/) microservices.
37
+
38
+ ---
39
+
40
+ ## Overview
41
+
42
+ `fastapi-commons` provides shared building blocks across FastAPI services to eliminate boilerplate. It integrates Prometheus metrics, OpenTelemetry distributed tracing, contextual logging with correlation IDs, OpenID Connect (OIDC) JWT and database API key authentication, and structured exception handling.
43
+
44
+ ---
45
+
46
+ ## Features
47
+
48
+ ### 1. Observability & Prometheus Metrics
49
+ - **`PrometheusMiddleware`**: Tracks HTTP request counts, response statuses, in-progress requests, and request durations.
50
+ - Automatically resolves parameterized route templates (e.g. `/items/{id}` instead of `/items/123`) to prevent metric cardinality explosion.
51
+ - Supports OpenTelemetry trace exemplars on duration histograms to link metrics to traces.
52
+ - **`metrics`**: Pre-configured route handler exposing metrics in OpenMetrics / Prometheus exposition format.
53
+ - **Access log filtering**: Built-in `EndpointFilter` suppresses noisy `GET /metrics` access logs in Uvicorn.
54
+
55
+ ### 2. Distributed Tracing (OpenTelemetry)
56
+ - **`setup_opentelemetry`**: One-line configuration for OpenTelemetry tracing.
57
+ - Configures `TracerProvider`, `Resource` attributes, and `BatchSpanProcessor` with an OTLP gRPC exporter.
58
+ - Instruments FastAPI endpoints and Python logging for trace correlation.
59
+
60
+ ### 3. Correlation ID & Contextual Logging
61
+ - **`CorrelationIDMiddleware`**: Inspects or generates an `X-Correlation-ID` HTTP header, propagating it across request context and returning it in responses.
62
+ - **`LogContextMiddleware`**: Captures client information (such as client IP, respecting `X-Forwarded-For`).
63
+ - **`CorrelationIDFilter` & `LogContextFilter`**: Logging filters that inject correlation IDs and request context into Python log records.
64
+ - **`SHARED_LOG_CONFIG`**: Standard log format containing timestamps, log levels, logger names, trace IDs, span IDs, and service names.
65
+
66
+ ### 4. Authentication & Authorization
67
+ - **OIDC Token Verification (`get_token_verifier`)**:
68
+ - Validates Bearer JWT tokens against OpenID Connect (OIDC) JSON Web Key Sets (JWKS) via RS256.
69
+ - Deserializes and validates token claims into custom models using `msgspec`.
70
+ - Can be toggled via environment settings (`API_AUTH_ENABLED`).
71
+ - **Database API Key Verification (`get_api_key_verifier`)**:
72
+ - FastAPI dependency for validating API keys from request headers against database records using SQLAlchemy async sessions.
73
+
74
+ ### 5. Exception Handling
75
+ - **`@handle_exceptions`**: Decorator for endpoint functions and handlers that catches common application errors and maps them to standard HTTP exceptions:
76
+ - `PermissionError` $\to$ `401 Unauthorized`
77
+ - `LookupError` $\to$ `404 Not Found`
78
+ - `ValueError` $\to$ `400 Bad Request`
79
+ - `ConnectionRefusedError` $\to$ `503 Service Unavailable`
80
+ - `NotImplementedError` $\to$ `501 Not Implemented`
81
+ - `AppError` / `ValidationError` $\to$ `500 Internal Server Error`
82
+
83
+ ---
84
+
85
+ ## Installation
86
+
87
+ Using `uv` (recommended):
88
+
89
+ ```bash
90
+ uv add fastapi-commons
91
+ ```
92
+
93
+ Or using `pip`:
94
+
95
+ ```bash
96
+ pip install fastapi-commons
97
+ ```
98
+
99
+ ---
100
+
101
+ ## Usage Guide
102
+
103
+ ### Metrics & OpenTelemetry Setup
104
+
105
+ ```python
106
+ from fastapi import FastAPI
107
+ from fastapi_commons import PrometheusMiddleware, metrics, setup_opentelemetry
108
+
109
+ app = FastAPI(title="My Service")
110
+
111
+ # Setup OpenTelemetry tracing
112
+ setup_opentelemetry(app, app_name="my-service")
113
+
114
+ # Setup Prometheus metrics middleware and endpoint
115
+ app.add_middleware(PrometheusMiddleware, app_name="my-service")
116
+ app.add_route("/metrics", metrics)
117
+
118
+ @app.get("/items/{item_id}")
119
+ async def get_item(item_id: int):
120
+ return {"item_id": item_id}
121
+ ```
122
+
123
+ ### Correlation ID & Logging
124
+
125
+ ```python
126
+ import logging
127
+ from fastapi import FastAPI
128
+ from fastapi_commons.middleware.correlation_id import CorrelationIDMiddleware
129
+ from fastapi_commons.middleware.log_context import LogContextMiddleware
130
+ from fastapi_commons.log.filters import CorrelationIDFilter, LogContextFilter
131
+
132
+ app = FastAPI()
133
+
134
+ # Add middlewares
135
+ app.add_middleware(CorrelationIDMiddleware)
136
+ app.add_middleware(LogContextMiddleware)
137
+
138
+ # Attach filters to your log handlers
139
+ handler = logging.StreamHandler()
140
+ handler.addFilter(CorrelationIDFilter())
141
+ handler.addFilter(LogContextFilter())
142
+ logging.basicConfig(
143
+ level=logging.INFO,
144
+ format="%(asctime)s [%(correlation_id)s] [%(client_ip)s] %(message)s",
145
+ handlers=[handler],
146
+ )
147
+ ```
148
+
149
+ ### OIDC Authentication
150
+
151
+ ```python
152
+ from fastapi import Depends, FastAPI
153
+ from python3_commons.auth import TokenData
154
+ from fastapi_commons.auth import get_token_verifier
155
+
156
+ app = FastAPI()
157
+
158
+ class UserClaims(TokenData):
159
+ sub: str
160
+ email: str | None = None
161
+
162
+ verify_token = get_token_verifier(UserClaims)
163
+
164
+ @app.get("/protected")
165
+ async def protected_route(claims: UserClaims = Depends(verify_token)):
166
+ return {"message": f"Hello, {claims.sub}!"}
167
+ ```
168
+
169
+ ### Exception Handling Decorator
170
+
171
+ ```python
172
+ from fastapi import FastAPI
173
+ from fastapi_commons.handlers import handle_exceptions
174
+
175
+ app = FastAPI()
176
+
177
+ @app.get("/find/{item_id}")
178
+ @handle_exceptions
179
+ async def find_item(item_id: int):
180
+ if item_id < 0:
181
+ raise ValueError("Item ID must be positive")
182
+ if item_id == 404:
183
+ raise LookupError("Item not found")
184
+ return {"item_id": item_id}
185
+ ```
186
+
187
+ ---
188
+
189
+ ## Configuration
190
+
191
+ Settings can be customized via environment variables:
192
+
193
+ | Environment Variable | Default | Description |
194
+ |----------------------|---------------------|--------------------------------------------------|
195
+ | `API_AUTH_ENABLED` | `true` | Enable or disable API authentication enforcement |
196
+ | `OTLP_GRPC_ENDPOINT` | `http://tempo:4317` | OpenTelemetry gRPC collector endpoint |
197
+ | `OIDC_AUTHORITY_URL` | - | OpenID Connect authority / issuer URL |
198
+ | `OIDC_CLIENT_ID` | - | OpenID Connect client ID |
199
+ | `OIDC_CLIENT_SECRET` | - | OpenID Connect client secret |
200
+ | `OIDC_AUDIENCE` | - | Expected token audience |
201
+ | `OIDC_TIMEOUT` | `10.0` | OIDC HTTP request timeout (seconds) |
202
+ | `OIDC_VERIFY_CERT` | `true` | Verify TLS certificates for OIDC requests |
203
+
204
+ ---
205
+
206
+ ## License
207
+
208
+ This project is licensed under the GNU General Public License v3 (`GPL-3.0`). See [LICENSE](LICENSE) for details.
209
+
210
+ ## Contributors
211
+
212
+ See [AUTHORS.md](AUTHORS.md).
@@ -0,0 +1,179 @@
1
+ # fastapi-commons
2
+
3
+ Common utilities, middleware, security, and observability helpers for production-ready [FastAPI](https://fastapi.tiangolo.com/) microservices.
4
+
5
+ ---
6
+
7
+ ## Overview
8
+
9
+ `fastapi-commons` provides shared building blocks across FastAPI services to eliminate boilerplate. It integrates Prometheus metrics, OpenTelemetry distributed tracing, contextual logging with correlation IDs, OpenID Connect (OIDC) JWT and database API key authentication, and structured exception handling.
10
+
11
+ ---
12
+
13
+ ## Features
14
+
15
+ ### 1. Observability & Prometheus Metrics
16
+ - **`PrometheusMiddleware`**: Tracks HTTP request counts, response statuses, in-progress requests, and request durations.
17
+ - Automatically resolves parameterized route templates (e.g. `/items/{id}` instead of `/items/123`) to prevent metric cardinality explosion.
18
+ - Supports OpenTelemetry trace exemplars on duration histograms to link metrics to traces.
19
+ - **`metrics`**: Pre-configured route handler exposing metrics in OpenMetrics / Prometheus exposition format.
20
+ - **Access log filtering**: Built-in `EndpointFilter` suppresses noisy `GET /metrics` access logs in Uvicorn.
21
+
22
+ ### 2. Distributed Tracing (OpenTelemetry)
23
+ - **`setup_opentelemetry`**: One-line configuration for OpenTelemetry tracing.
24
+ - Configures `TracerProvider`, `Resource` attributes, and `BatchSpanProcessor` with an OTLP gRPC exporter.
25
+ - Instruments FastAPI endpoints and Python logging for trace correlation.
26
+
27
+ ### 3. Correlation ID & Contextual Logging
28
+ - **`CorrelationIDMiddleware`**: Inspects or generates an `X-Correlation-ID` HTTP header, propagating it across request context and returning it in responses.
29
+ - **`LogContextMiddleware`**: Captures client information (such as client IP, respecting `X-Forwarded-For`).
30
+ - **`CorrelationIDFilter` & `LogContextFilter`**: Logging filters that inject correlation IDs and request context into Python log records.
31
+ - **`SHARED_LOG_CONFIG`**: Standard log format containing timestamps, log levels, logger names, trace IDs, span IDs, and service names.
32
+
33
+ ### 4. Authentication & Authorization
34
+ - **OIDC Token Verification (`get_token_verifier`)**:
35
+ - Validates Bearer JWT tokens against OpenID Connect (OIDC) JSON Web Key Sets (JWKS) via RS256.
36
+ - Deserializes and validates token claims into custom models using `msgspec`.
37
+ - Can be toggled via environment settings (`API_AUTH_ENABLED`).
38
+ - **Database API Key Verification (`get_api_key_verifier`)**:
39
+ - FastAPI dependency for validating API keys from request headers against database records using SQLAlchemy async sessions.
40
+
41
+ ### 5. Exception Handling
42
+ - **`@handle_exceptions`**: Decorator for endpoint functions and handlers that catches common application errors and maps them to standard HTTP exceptions:
43
+ - `PermissionError` $\to$ `401 Unauthorized`
44
+ - `LookupError` $\to$ `404 Not Found`
45
+ - `ValueError` $\to$ `400 Bad Request`
46
+ - `ConnectionRefusedError` $\to$ `503 Service Unavailable`
47
+ - `NotImplementedError` $\to$ `501 Not Implemented`
48
+ - `AppError` / `ValidationError` $\to$ `500 Internal Server Error`
49
+
50
+ ---
51
+
52
+ ## Installation
53
+
54
+ Using `uv` (recommended):
55
+
56
+ ```bash
57
+ uv add fastapi-commons
58
+ ```
59
+
60
+ Or using `pip`:
61
+
62
+ ```bash
63
+ pip install fastapi-commons
64
+ ```
65
+
66
+ ---
67
+
68
+ ## Usage Guide
69
+
70
+ ### Metrics & OpenTelemetry Setup
71
+
72
+ ```python
73
+ from fastapi import FastAPI
74
+ from fastapi_commons import PrometheusMiddleware, metrics, setup_opentelemetry
75
+
76
+ app = FastAPI(title="My Service")
77
+
78
+ # Setup OpenTelemetry tracing
79
+ setup_opentelemetry(app, app_name="my-service")
80
+
81
+ # Setup Prometheus metrics middleware and endpoint
82
+ app.add_middleware(PrometheusMiddleware, app_name="my-service")
83
+ app.add_route("/metrics", metrics)
84
+
85
+ @app.get("/items/{item_id}")
86
+ async def get_item(item_id: int):
87
+ return {"item_id": item_id}
88
+ ```
89
+
90
+ ### Correlation ID & Logging
91
+
92
+ ```python
93
+ import logging
94
+ from fastapi import FastAPI
95
+ from fastapi_commons.middleware.correlation_id import CorrelationIDMiddleware
96
+ from fastapi_commons.middleware.log_context import LogContextMiddleware
97
+ from fastapi_commons.log.filters import CorrelationIDFilter, LogContextFilter
98
+
99
+ app = FastAPI()
100
+
101
+ # Add middlewares
102
+ app.add_middleware(CorrelationIDMiddleware)
103
+ app.add_middleware(LogContextMiddleware)
104
+
105
+ # Attach filters to your log handlers
106
+ handler = logging.StreamHandler()
107
+ handler.addFilter(CorrelationIDFilter())
108
+ handler.addFilter(LogContextFilter())
109
+ logging.basicConfig(
110
+ level=logging.INFO,
111
+ format="%(asctime)s [%(correlation_id)s] [%(client_ip)s] %(message)s",
112
+ handlers=[handler],
113
+ )
114
+ ```
115
+
116
+ ### OIDC Authentication
117
+
118
+ ```python
119
+ from fastapi import Depends, FastAPI
120
+ from python3_commons.auth import TokenData
121
+ from fastapi_commons.auth import get_token_verifier
122
+
123
+ app = FastAPI()
124
+
125
+ class UserClaims(TokenData):
126
+ sub: str
127
+ email: str | None = None
128
+
129
+ verify_token = get_token_verifier(UserClaims)
130
+
131
+ @app.get("/protected")
132
+ async def protected_route(claims: UserClaims = Depends(verify_token)):
133
+ return {"message": f"Hello, {claims.sub}!"}
134
+ ```
135
+
136
+ ### Exception Handling Decorator
137
+
138
+ ```python
139
+ from fastapi import FastAPI
140
+ from fastapi_commons.handlers import handle_exceptions
141
+
142
+ app = FastAPI()
143
+
144
+ @app.get("/find/{item_id}")
145
+ @handle_exceptions
146
+ async def find_item(item_id: int):
147
+ if item_id < 0:
148
+ raise ValueError("Item ID must be positive")
149
+ if item_id == 404:
150
+ raise LookupError("Item not found")
151
+ return {"item_id": item_id}
152
+ ```
153
+
154
+ ---
155
+
156
+ ## Configuration
157
+
158
+ Settings can be customized via environment variables:
159
+
160
+ | Environment Variable | Default | Description |
161
+ |----------------------|---------------------|--------------------------------------------------|
162
+ | `API_AUTH_ENABLED` | `true` | Enable or disable API authentication enforcement |
163
+ | `OTLP_GRPC_ENDPOINT` | `http://tempo:4317` | OpenTelemetry gRPC collector endpoint |
164
+ | `OIDC_AUTHORITY_URL` | - | OpenID Connect authority / issuer URL |
165
+ | `OIDC_CLIENT_ID` | - | OpenID Connect client ID |
166
+ | `OIDC_CLIENT_SECRET` | - | OpenID Connect client secret |
167
+ | `OIDC_AUDIENCE` | - | Expected token audience |
168
+ | `OIDC_TIMEOUT` | `10.0` | OIDC HTTP request timeout (seconds) |
169
+ | `OIDC_VERIFY_CERT` | `true` | Verify TLS certificates for OIDC requests |
170
+
171
+ ---
172
+
173
+ ## License
174
+
175
+ This project is licensed under the GNU General Public License v3 (`GPL-3.0`). See [LICENSE](LICENSE) for details.
176
+
177
+ ## Contributors
178
+
179
+ See [AUTHORS.md](AUTHORS.md).
@@ -0,0 +1,170 @@
1
+ [build-system]
2
+ requires = ["uv_build>=0.12.18,<0.13.0"]
3
+ build-backend = "uv_build"
4
+
5
+ [project]
6
+ name = "fastapi-commons"
7
+ version = "0.8.6"
8
+ description = "Re-usable FastAPI code"
9
+ license = "GPL-3.0-only"
10
+ license-files = [
11
+ "LICENSE",
12
+ "AUTHORS.md",
13
+ ]
14
+ readme = "README.md"
15
+ classifiers = [
16
+ "Development Status :: 4 - Beta",
17
+ "Programming Language :: Python",
18
+ ]
19
+ keywords = []
20
+ requires-python = ">=3.14.0,<3.15.0"
21
+ dependencies = [
22
+ "aiohttp[speedups]>=3.14.3,<3.15.0",
23
+ "asyncpg~=0.31.0",
24
+ "fastapi~=0.141.1",
25
+ "msgspec~=0.21.1",
26
+ "pydantic[email]~=2.13.5",
27
+ "pydantic-settings~=2.15.0",
28
+ "python-jose~=3.5.0",
29
+ "SQLAlchemy[asyncio]~=2.1.1",
30
+ "opentelemetry-api~=1.45.0",
31
+ "opentelemetry-sdk~=1.45.0",
32
+ "opentelemetry-exporter-otlp~=1.45.0",
33
+ "opentelemetry-instrumentation-fastapi~=0.65b0",
34
+ "opentelemetry-instrumentation-logging~=0.65b0",
35
+ "prometheus-client~=0.26.0",
36
+ "python3-commons[authn]~=0.24.6",
37
+ "starlette~=1.7.0",
38
+ ]
39
+
40
+ [[project.authors]]
41
+ name = "Oleg Korsak"
42
+ email = "kamikaze.is.waiting.you@gmail.com"
43
+
44
+ [project.urls]
45
+ Homepage = "https://github.com/kamikaze/fastapi-commons"
46
+ Documentation = "https://github.com/kamikaze/fastapi-commons/wiki"
47
+
48
+ [dependency-groups]
49
+ dev = [
50
+ "pre-commit",
51
+ "pyright",
52
+ "ruff",
53
+ "ty",
54
+ "types-aiobotocore-s3",
55
+ ]
56
+ testing = [
57
+ "pytest",
58
+ "pytest-asyncio",
59
+ "pytest-cov",
60
+ "pytest-mock",
61
+ ]
62
+
63
+ [tool.uv.build-backend]
64
+ source-include = [
65
+ "CHANGELOG.md",
66
+ "tests/**",
67
+ ]
68
+
69
+ [tool.ruff]
70
+ line-length = 120
71
+ indent-width = 4
72
+ target-version = "py314"
73
+
74
+ [tool.ruff.analyze]
75
+ detect-string-imports = true
76
+
77
+ [tool.ruff.lint]
78
+ select = [
79
+ "A",
80
+ "ANN",
81
+ "ARG",
82
+ "ASYNC",
83
+ "B",
84
+ "C4",
85
+ "DTZ",
86
+ "E",
87
+ "EM",
88
+ "EXE",
89
+ "F",
90
+ "FA",
91
+ "FAST",
92
+ "FBT",
93
+ "FLY",
94
+ "FURB",
95
+ "G",
96
+ "I",
97
+ "ICN",
98
+ "INP",
99
+ "ISC",
100
+ "LOG",
101
+ "N",
102
+ "NPY",
103
+ "PD",
104
+ "PERF",
105
+ "PIE",
106
+ "PLC",
107
+ "PLE",
108
+ "PLR",
109
+ "PLW",
110
+ "PT",
111
+ "PTH",
112
+ "PYI",
113
+ "Q",
114
+ "RET",
115
+ "RSE",
116
+ "RUF",
117
+ "S",
118
+ "SIM",
119
+ "SLF",
120
+ "SLOT",
121
+ "T20",
122
+ "TC",
123
+ "TID",
124
+ "TRY",
125
+ "UP",
126
+ "W",
127
+ "YTT",
128
+ ]
129
+ ignore = [
130
+ "TC001",
131
+ "TC002",
132
+ "TC003",
133
+ ]
134
+
135
+ [tool.ruff.lint.per-file-ignores]
136
+ "tests/*.py" = [
137
+ "DTZ",
138
+ "S101",
139
+ ]
140
+
141
+ [tool.ruff.lint.flake8-quotes]
142
+ docstring-quotes = "double"
143
+ inline-quotes = "single"
144
+
145
+ [tool.ruff.format]
146
+ exclude = ["*.pyi"]
147
+ indent-style = "space"
148
+ quote-style = "single"
149
+
150
+ [tool.pyright]
151
+ pythonVersion = "3.14"
152
+ venvPath = "."
153
+ venv = ".venv"
154
+ reportMatchNotExhaustive = "error"
155
+ reportUnnecessaryComparison = "error"
156
+
157
+ [tool.ty.rules]
158
+ unknown-argument = "ignore"
159
+
160
+ [tool.pytest.ini_options]
161
+ pythonpath = ["src"]
162
+ asyncio_mode = "strict"
163
+ asyncio_default_fixture_loop_scope = "function"
164
+ addopts = "--cov fastapi_commons --cov-fail-under=0 --cov-report term-missing --verbose"
165
+ norecursedirs = [
166
+ "dist",
167
+ "build",
168
+ ".tox",
169
+ ]
170
+ testpaths = ["tests"]
@@ -1,16 +1,17 @@
1
1
  [build-system]
2
- requires = ["setuptools", "wheel", "setuptools_scm"]
3
- build-backend = "setuptools.build_meta"
2
+ requires = ["uv_build>=0.12.18,<0.13.0"]
3
+ build-backend = "uv_build"
4
4
 
5
5
  [project]
6
6
  name = "fastapi-commons"
7
- dynamic = ["version"]
7
+ version = "0.8.6"
8
8
  description = "Re-usable FastAPI code"
9
9
  authors = [
10
10
  { name = "Oleg Korsak", email = "kamikaze.is.waiting.you@gmail.com" }
11
11
  ]
12
- license = "GPL-3.0"
13
- readme = { file = "README.rst", content-type = "text/x-rst" }
12
+ license = "GPL-3.0-only"
13
+ license-files = ["LICENSE", "AUTHORS.md"]
14
+ readme = "README.md"
14
15
  classifiers = [
15
16
  "Development Status :: 4 - Beta",
16
17
  "Programming Language :: Python"
@@ -22,32 +23,27 @@ dependencies = [
22
23
  "asyncpg~=0.31.0",
23
24
  "fastapi~=0.141.1",
24
25
  "msgspec~=0.21.1",
25
- "pydantic[email]~=2.13.4",
26
+ "pydantic[email]~=2.13.5",
26
27
  "pydantic-settings~=2.15.0",
27
28
  "python-jose~=3.5.0",
28
- "SQLAlchemy[asyncio]~=2.0.52",
29
- "opentelemetry-api~=1.44.0",
30
- "opentelemetry-sdk~=1.44.0",
31
- "opentelemetry-exporter-otlp~=1.44.0",
29
+ "SQLAlchemy[asyncio]~=2.1.1",
30
+ "opentelemetry-api~=1.45.0",
31
+ "opentelemetry-sdk~=1.45.0",
32
+ "opentelemetry-exporter-otlp~=1.45.0",
32
33
  "opentelemetry-instrumentation-fastapi~=0.65b0",
33
34
  "opentelemetry-instrumentation-logging~=0.65b0",
34
35
  "prometheus-client~=0.26.0",
35
- "python3-commons[authn]~=0.24.5",
36
- "starlette~=1.6.0",
36
+ "python3-commons[authn]~=0.24.6",
37
+ "starlette~=1.7.0",
37
38
  ]
38
39
 
39
40
  [dependency-groups]
40
41
  dev = [
41
- "build",
42
- "pip",
43
42
  "pre-commit",
44
43
  "pyright",
45
44
  "ruff",
46
- "setuptools",
47
- "setuptools_scm",
48
45
  "ty",
49
46
  "types-aiobotocore-s3",
50
- "wheel",
51
47
  ]
52
48
  testing = [
53
49
  "pytest",
@@ -60,14 +56,9 @@ testing = [
60
56
  Homepage = "https://github.com/kamikaze/fastapi-commons"
61
57
  Documentation = "https://github.com/kamikaze/fastapi-commons/wiki"
62
58
 
63
- [tool.setuptools.packages.find]
64
- where = ["src"]
65
- exclude = ["tests"]
59
+ [tool.uv.build-backend]
60
+ source-include = ["CHANGELOG.md", "tests/**"]
66
61
 
67
- [tool.setuptools_scm]
68
-
69
- [tool.bdist_wheel]
70
- universal = true
71
62
 
72
63
  [tool.ruff]
73
64
  line-length = 120
@@ -1,28 +0,0 @@
1
- # .coveragerc to control coverage.py
2
- [run]
3
- branch = True
4
- source = fastapi_commons
5
- # omit = bad_file.py
6
-
7
- [paths]
8
- source =
9
- src/
10
- */site-packages/
11
-
12
- [report]
13
- # Regexes for lines to exclude from consideration
14
- exclude_lines =
15
- # Have to re-enable the standard pragma
16
- pragma: no cover
17
-
18
- # Don't complain about missing debug-only code:
19
- def __repr__
20
- if self\.debug
21
-
22
- # Don't complain if tests don't hit defensive assertion code:
23
- raise AssertionError
24
- raise NotImplementedError
25
-
26
- # Don't complain if non-runnable code isn't run:
27
- if 0:
28
- if __name__ == .__main__.:
@@ -1,7 +0,0 @@
1
- LOGGING_LEVEL=DEBUG
2
-
3
- API_AUTH_ENABLED=false
4
- OIDC_AUTHORITY_URL=https://oidc.provider.com/auth
5
- OIDC_CLIENT_ID=12345-54321
6
- #OIDC_REDIRECT_URI=
7
- #OIDC_SCOPES=openid,profile,email