prodkit 0.1.0__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 (35) hide show
  1. prodkit-0.1.0/.gitignore +27 -0
  2. prodkit-0.1.0/CHANGELOG.md +22 -0
  3. prodkit-0.1.0/LICENSE +21 -0
  4. prodkit-0.1.0/PKG-INFO +264 -0
  5. prodkit-0.1.0/README.md +222 -0
  6. prodkit-0.1.0/pyproject.toml +111 -0
  7. prodkit-0.1.0/src/prodkit/__init__.py +57 -0
  8. prodkit-0.1.0/src/prodkit/contracts/__init__.py +0 -0
  9. prodkit-0.1.0/src/prodkit/contracts/plugin.py +61 -0
  10. prodkit-0.1.0/src/prodkit/core/__init__.py +0 -0
  11. prodkit-0.1.0/src/prodkit/core/config.py +245 -0
  12. prodkit-0.1.0/src/prodkit/core/context.py +53 -0
  13. prodkit-0.1.0/src/prodkit/core/event_bus.py +42 -0
  14. prodkit-0.1.0/src/prodkit/core/exceptions.py +23 -0
  15. prodkit-0.1.0/src/prodkit/core/lifecycle.py +54 -0
  16. prodkit-0.1.0/src/prodkit/core/plugin_manager.py +52 -0
  17. prodkit-0.1.0/src/prodkit/core/production.py +123 -0
  18. prodkit-0.1.0/src/prodkit/core/registry.py +38 -0
  19. prodkit-0.1.0/src/prodkit/plugins/__init__.py +54 -0
  20. prodkit-0.1.0/src/prodkit/plugins/compression/__init__.py +22 -0
  21. prodkit-0.1.0/src/prodkit/plugins/cors/__init__.py +38 -0
  22. prodkit-0.1.0/src/prodkit/plugins/errors/__init__.py +98 -0
  23. prodkit-0.1.0/src/prodkit/plugins/health/__init__.py +72 -0
  24. prodkit-0.1.0/src/prodkit/plugins/logging/__init__.py +116 -0
  25. prodkit-0.1.0/src/prodkit/plugins/request_id/__init__.py +61 -0
  26. prodkit-0.1.0/src/prodkit/plugins/security/__init__.py +78 -0
  27. prodkit-0.1.0/src/prodkit/py.typed +0 -0
  28. prodkit-0.1.0/tests/__init__.py +0 -0
  29. prodkit-0.1.0/tests/conftest.py +35 -0
  30. prodkit-0.1.0/tests/integration/__init__.py +0 -0
  31. prodkit-0.1.0/tests/integration/test_logging.py +81 -0
  32. prodkit-0.1.0/tests/integration/test_production.py +232 -0
  33. prodkit-0.1.0/tests/unit/__init__.py +0 -0
  34. prodkit-0.1.0/tests/unit/test_config.py +124 -0
  35. prodkit-0.1.0/tests/unit/test_kernel.py +116 -0
@@ -0,0 +1,27 @@
1
+ # Byte-compiled / caches
2
+ __pycache__/
3
+ *.py[cod]
4
+ .pytest_cache/
5
+ .mypy_cache/
6
+ .ruff_cache/
7
+ .coverage
8
+ htmlcov/
9
+
10
+ # Environments
11
+ .venv/
12
+ venv/
13
+ .env
14
+
15
+ # Build artifacts
16
+ build/
17
+ dist/
18
+ *.egg-info/
19
+
20
+ # Editors / OS
21
+ .vscode/
22
+ .idea/
23
+ .DS_Store
24
+ Thumbs.db
25
+ LI.MD
26
+ PUB.MD
27
+ EX.MD
@@ -0,0 +1,22 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [0.1.0] - 2026-07-16
11
+
12
+ ### Added
13
+ - Kernel: layered configuration (args > env > `prodkit.toml` > profile > defaults),
14
+ plugin manager with dependency topological sort, service registry, event bus,
15
+ lifespan composition, fail-fast config validation.
16
+ - Plugin contract with async startup/shutdown hooks and prioritized middleware
17
+ registration.
18
+ - Environment profiles: `development`, `staging`, `production`.
19
+ - Built-in plugins: `request-id`, `logging` (structured JSON/console), `errors`
20
+ (RFC 9457 problem+json), `health` (`/health`, `/ready`, `/live`), `security`
21
+ (security headers, trusted hosts, HTTPS redirect), `cors`, `compression` (gzip).
22
+ - `Production(app)` one-line entrypoint.
prodkit-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Pushkar Pant
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
prodkit-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,264 @@
1
+ Metadata-Version: 2.4
2
+ Name: prodkit
3
+ Version: 0.1.0
4
+ Summary: The production framework for FastAPI. One line. Production ready.
5
+ Project-URL: Homepage, https://github.com/Pushkarpant/PRODKIT
6
+ Project-URL: Documentation, https://github.com/Pushkarpant/PRODKIT#readme
7
+ Project-URL: Repository, https://github.com/Pushkarpant/PRODKIT
8
+ Project-URL: Changelog, https://github.com/Pushkarpant/PRODKIT/blob/main/CHANGELOG.md
9
+ Project-URL: Issues, https://github.com/Pushkarpant/PRODKIT/issues
10
+ Author: ProdKit Contributors
11
+ License-Expression: MIT
12
+ License-File: LICENSE
13
+ Keywords: fastapi,health-check,logging,middleware,observability,production,security
14
+ Classifier: Development Status :: 3 - Alpha
15
+ Classifier: Framework :: FastAPI
16
+ Classifier: Intended Audience :: Developers
17
+ Classifier: Operating System :: OS Independent
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3.10
20
+ Classifier: Programming Language :: Python :: 3.11
21
+ Classifier: Programming Language :: Python :: 3.12
22
+ Classifier: Programming Language :: Python :: 3.13
23
+ Classifier: Topic :: Internet :: WWW/HTTP :: HTTP Servers
24
+ Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
25
+ Classifier: Typing :: Typed
26
+ Requires-Python: >=3.10
27
+ Requires-Dist: fastapi>=0.110
28
+ Requires-Dist: pydantic-settings>=2.1
29
+ Requires-Dist: pydantic>=2.5
30
+ Requires-Dist: tomli>=2.0; python_version < '3.11'
31
+ Provides-Extra: brotli
32
+ Requires-Dist: brotli-asgi>=1.4; extra == 'brotli'
33
+ Provides-Extra: dev
34
+ Requires-Dist: httpx>=0.27; extra == 'dev'
35
+ Requires-Dist: import-linter>=2.0; extra == 'dev'
36
+ Requires-Dist: mypy>=1.11; extra == 'dev'
37
+ Requires-Dist: pytest-cov>=5.0; extra == 'dev'
38
+ Requires-Dist: pytest>=8.0; extra == 'dev'
39
+ Requires-Dist: ruff>=0.6; extra == 'dev'
40
+ Requires-Dist: tomli>=2.0; extra == 'dev'
41
+ Description-Content-Type: text/markdown
42
+
43
+ # ProdKit
44
+
45
+ > **One line. Production ready.**
46
+
47
+ The production framework for [FastAPI](https://fastapi.tiangolo.com/).
48
+
49
+ ```python
50
+ from fastapi import FastAPI
51
+ from prodkit import Production
52
+
53
+ app = FastAPI()
54
+ Production(app)
55
+ ```
56
+
57
+ That's it. Your app now has security headers, structured JSON logging with
58
+ request-ID correlation, RFC 9457 error responses, Kubernetes-ready health
59
+ endpoints, and gzip compression — configured to current best practice,
60
+ hardened for production, and pleasant in development.
61
+
62
+ [![CI](https://github.com/Pushkarpant/PRODKIT/actions/workflows/ci.yml/badge.svg)](https://github.com/Pushkarpant/PRODKIT/actions/workflows/ci.yml)
63
+ [![PyPI](https://img.shields.io/pypi/v/prodkit)](https://pypi.org/project/prodkit/)
64
+ [![Python](https://img.shields.io/pypi/pyversions/prodkit)](https://pypi.org/project/prodkit/)
65
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
66
+
67
+ ---
68
+
69
+ ## Why
70
+
71
+ Every production FastAPI service re-implements the same ~500 lines of glue:
72
+ middleware ordering, security headers, structured logging, health checks,
73
+ error normalization, graceful shutdown. FastAPI deliberately doesn't ship
74
+ this — it's a micro framework. **ProdKit is the batteries.**
75
+
76
+ And unlike a project template, ProdKit is a library: when best practices
77
+ evolve, `pip install -U prodkit` updates every app you own.
78
+
79
+ ## Installation
80
+
81
+ [**`pip install prodkit`**](https://pypi.org/project/prodkit/)
82
+
83
+ ```bash
84
+ pip install prodkit
85
+ ```
86
+
87
+ Requires Python 3.10+ and FastAPI 0.110+. The base install depends only on
88
+ FastAPI and Pydantic — nothing else.
89
+
90
+ ## Quick Start
91
+
92
+ ```python
93
+ from fastapi import FastAPI
94
+ from prodkit import Production
95
+
96
+ app = FastAPI()
97
+ Production(app) # production profile by default
98
+
99
+ @app.get("/hello")
100
+ def hello():
101
+ return {"message": "hello"}
102
+ ```
103
+
104
+ ```bash
105
+ uvicorn main:app
106
+ ```
107
+
108
+ ```text
109
+ $ curl -i localhost:8000/hello
110
+ HTTP/1.1 200 OK
111
+ x-request-id: 26fdc49565614c2a9ef1a3b8d4e0f712
112
+ x-content-type-options: nosniff
113
+ x-frame-options: DENY
114
+ strict-transport-security: max-age=63072000; includeSubDomains
115
+ referrer-policy: strict-origin-when-cross-origin
116
+ ...
117
+ ```
118
+
119
+ For local development, flip the profile — pretty console logs, debug error
120
+ details, no HSTS:
121
+
122
+ ```python
123
+ Production(app, environment="development")
124
+ ```
125
+
126
+ ## What You Get
127
+
128
+ | Feature | Details |
129
+ |---|---|
130
+ | 🆔 **Request IDs** | `X-Request-ID` on every response, propagated into every log line. Inbound IDs untrusted by default. |
131
+ | 📋 **Structured logging** | One JSON object per request in production (Datadog/Loki/CloudWatch-ready); pretty console logs in development. |
132
+ | 🛡️ **Security headers** | OWASP-aligned: `nosniff`, `X-Frame-Options`, HSTS, `Referrer-Policy`, `Permissions-Policy`. Your own headers always win. |
133
+ | 🚨 **Error normalization** | [RFC 9457](https://www.rfc-editor.org/rfc/rfc9457) `problem+json` responses. Unhandled 500s are **opaque to clients** — the traceback goes to logs, correlated by request ID. |
134
+ | ❤️ **Health endpoints** | `/health`, `/live` (liveness) and `/ready` (readiness — aggregates checks from every plugin, 503 until all pass). Kubernetes-native. |
135
+ | 🌐 **CORS** | Explicit origins only; the wildcard-with-credentials footgun is refused at boot. |
136
+ | 📦 **Compression** | Gzip for responses over 500 bytes. |
137
+ | 🔌 **Plugin system** | Every feature above is a plugin. Write your own with 6 optional hooks. |
138
+
139
+ ## Configuration
140
+
141
+ Everything is configurable through four layers (highest wins):
142
+
143
+ ```
144
+ Python args > environment variables > prodkit.toml > profile defaults
145
+ ```
146
+
147
+ **Python:**
148
+
149
+ ```python
150
+ Production(
151
+ app,
152
+ environment="production",
153
+ cors={"origins": ["https://app.example.com"]}, # dict = configure & enable
154
+ compression=False, # bool = toggle
155
+ security={"trusted_hosts": ["api.example.com"]},
156
+ )
157
+ ```
158
+
159
+ **Environment variables** (`__` descends into sections):
160
+
161
+ ```bash
162
+ PRODKIT_ENVIRONMENT=production
163
+ PRODKIT_LOGGING__LEVEL=WARNING
164
+ PRODKIT_SECURITY__TRUSTED_HOSTS=api.example.com,admin.example.com
165
+ ```
166
+
167
+ **`prodkit.toml`:**
168
+
169
+ ```toml
170
+ [prodkit]
171
+ environment = "production"
172
+
173
+ [logging]
174
+ level = "INFO"
175
+
176
+ [cors]
177
+ enabled = true
178
+ origins = ["https://app.example.com"]
179
+ ```
180
+
181
+ ### Fail-fast, refuse-unsafe
182
+
183
+ Misconfiguration fails **at startup with a named key**, never silently:
184
+
185
+ ```text
186
+ ProdKitConfigError: Invalid ProdKit configuration:
187
+ - logging.levle: Extra inputs are not permitted
188
+ ```
189
+
190
+ And configurations that would weaken a production deployment are refused,
191
+ not warned about:
192
+
193
+ - `debug=True` in production
194
+ - error responses that would leak tracebacks in production
195
+ - CORS `origins=["*"]` combined with `allow_credentials=True`
196
+
197
+ ## Writing a Plugin
198
+
199
+ ```python
200
+ from prodkit import Check, Plugin, Production
201
+
202
+ class DatabasePlugin(Plugin):
203
+ name = "database"
204
+
205
+ async def startup(self, ctx):
206
+ self.pool = await create_pool(...)
207
+ ctx.registry.provide("db", self.pool)
208
+
209
+ async def shutdown(self, ctx):
210
+ await self.pool.close()
211
+
212
+ def checks(self, ctx):
213
+ return [Check(name="database", passed=self.pool.is_alive())]
214
+
215
+ Production(app, plugins=[DatabasePlugin()])
216
+ ```
217
+
218
+ Your check now shows up in `/ready` automatically. Plugins can declare
219
+ `requires = ("other-plugin",)` and the kernel activates them in dependency
220
+ order — cycles and missing dependencies fail at boot.
221
+
222
+ Middleware registered by plugins carries an explicit integer priority, so
223
+ the middleware onion is always correctly ordered no matter what order
224
+ plugins load in (request-id outermost, compression innermost).
225
+
226
+ ## Plays Nice With Your App
227
+
228
+ - **Same app object.** Routes, dependencies, and existing middleware keep
229
+ working. Remove `Production(app)` and you have a plain FastAPI app again.
230
+ - **Your lifespan survives.** ProdKit *composes* with an existing `lifespan`:
231
+ plugin startup → your lifespan → plugin shutdown (LIFO).
232
+ - **Your headers win.** Security headers use set-if-absent semantics.
233
+ - **Every feature can be turned off.** `Production(app, security=False, ...)`
234
+
235
+ ## Project Status
236
+
237
+ **v0.1.0 — alpha.** Core kernel and seven built-in plugins, 60 tests, 98%
238
+ coverage, strict mypy, CI across Python 3.10–3.13.
239
+
240
+ Roadmap: `prodkit doctor` CLI with a production-readiness score (v0.2),
241
+ Prometheus metrics + Redis backends (v0.3), Dockerfile/nginx/CI generators
242
+ (v0.4), public plugin SDK (v0.5), auth helpers (v0.6), stable API (v1.0).
243
+ Full details in [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md).
244
+
245
+ ## Contributing
246
+
247
+ Contributions welcome — see [CONTRIBUTING.md](CONTRIBUTING.md).
248
+ Security reports: see [SECURITY.md](SECURITY.md) (never open a public issue).
249
+
250
+ ```bash
251
+ git clone https://github.com/Pushkarpant/PRODKIT
252
+ cd PRODKIT
253
+ python -m venv .venv && source .venv/bin/activate
254
+ pip install -e ".[dev]"
255
+ pytest
256
+ ```
257
+
258
+ ## License
259
+
260
+ [MIT](LICENSE)
261
+
262
+ ---
263
+
264
+ *FastAPI builds APIs. ProdKit makes them production-ready.*
@@ -0,0 +1,222 @@
1
+ # ProdKit
2
+
3
+ > **One line. Production ready.**
4
+
5
+ The production framework for [FastAPI](https://fastapi.tiangolo.com/).
6
+
7
+ ```python
8
+ from fastapi import FastAPI
9
+ from prodkit import Production
10
+
11
+ app = FastAPI()
12
+ Production(app)
13
+ ```
14
+
15
+ That's it. Your app now has security headers, structured JSON logging with
16
+ request-ID correlation, RFC 9457 error responses, Kubernetes-ready health
17
+ endpoints, and gzip compression — configured to current best practice,
18
+ hardened for production, and pleasant in development.
19
+
20
+ [![CI](https://github.com/Pushkarpant/PRODKIT/actions/workflows/ci.yml/badge.svg)](https://github.com/Pushkarpant/PRODKIT/actions/workflows/ci.yml)
21
+ [![PyPI](https://img.shields.io/pypi/v/prodkit)](https://pypi.org/project/prodkit/)
22
+ [![Python](https://img.shields.io/pypi/pyversions/prodkit)](https://pypi.org/project/prodkit/)
23
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
24
+
25
+ ---
26
+
27
+ ## Why
28
+
29
+ Every production FastAPI service re-implements the same ~500 lines of glue:
30
+ middleware ordering, security headers, structured logging, health checks,
31
+ error normalization, graceful shutdown. FastAPI deliberately doesn't ship
32
+ this — it's a micro framework. **ProdKit is the batteries.**
33
+
34
+ And unlike a project template, ProdKit is a library: when best practices
35
+ evolve, `pip install -U prodkit` updates every app you own.
36
+
37
+ ## Installation
38
+
39
+ [**`pip install prodkit`**](https://pypi.org/project/prodkit/)
40
+
41
+ ```bash
42
+ pip install prodkit
43
+ ```
44
+
45
+ Requires Python 3.10+ and FastAPI 0.110+. The base install depends only on
46
+ FastAPI and Pydantic — nothing else.
47
+
48
+ ## Quick Start
49
+
50
+ ```python
51
+ from fastapi import FastAPI
52
+ from prodkit import Production
53
+
54
+ app = FastAPI()
55
+ Production(app) # production profile by default
56
+
57
+ @app.get("/hello")
58
+ def hello():
59
+ return {"message": "hello"}
60
+ ```
61
+
62
+ ```bash
63
+ uvicorn main:app
64
+ ```
65
+
66
+ ```text
67
+ $ curl -i localhost:8000/hello
68
+ HTTP/1.1 200 OK
69
+ x-request-id: 26fdc49565614c2a9ef1a3b8d4e0f712
70
+ x-content-type-options: nosniff
71
+ x-frame-options: DENY
72
+ strict-transport-security: max-age=63072000; includeSubDomains
73
+ referrer-policy: strict-origin-when-cross-origin
74
+ ...
75
+ ```
76
+
77
+ For local development, flip the profile — pretty console logs, debug error
78
+ details, no HSTS:
79
+
80
+ ```python
81
+ Production(app, environment="development")
82
+ ```
83
+
84
+ ## What You Get
85
+
86
+ | Feature | Details |
87
+ |---|---|
88
+ | 🆔 **Request IDs** | `X-Request-ID` on every response, propagated into every log line. Inbound IDs untrusted by default. |
89
+ | 📋 **Structured logging** | One JSON object per request in production (Datadog/Loki/CloudWatch-ready); pretty console logs in development. |
90
+ | 🛡️ **Security headers** | OWASP-aligned: `nosniff`, `X-Frame-Options`, HSTS, `Referrer-Policy`, `Permissions-Policy`. Your own headers always win. |
91
+ | 🚨 **Error normalization** | [RFC 9457](https://www.rfc-editor.org/rfc/rfc9457) `problem+json` responses. Unhandled 500s are **opaque to clients** — the traceback goes to logs, correlated by request ID. |
92
+ | ❤️ **Health endpoints** | `/health`, `/live` (liveness) and `/ready` (readiness — aggregates checks from every plugin, 503 until all pass). Kubernetes-native. |
93
+ | 🌐 **CORS** | Explicit origins only; the wildcard-with-credentials footgun is refused at boot. |
94
+ | 📦 **Compression** | Gzip for responses over 500 bytes. |
95
+ | 🔌 **Plugin system** | Every feature above is a plugin. Write your own with 6 optional hooks. |
96
+
97
+ ## Configuration
98
+
99
+ Everything is configurable through four layers (highest wins):
100
+
101
+ ```
102
+ Python args > environment variables > prodkit.toml > profile defaults
103
+ ```
104
+
105
+ **Python:**
106
+
107
+ ```python
108
+ Production(
109
+ app,
110
+ environment="production",
111
+ cors={"origins": ["https://app.example.com"]}, # dict = configure & enable
112
+ compression=False, # bool = toggle
113
+ security={"trusted_hosts": ["api.example.com"]},
114
+ )
115
+ ```
116
+
117
+ **Environment variables** (`__` descends into sections):
118
+
119
+ ```bash
120
+ PRODKIT_ENVIRONMENT=production
121
+ PRODKIT_LOGGING__LEVEL=WARNING
122
+ PRODKIT_SECURITY__TRUSTED_HOSTS=api.example.com,admin.example.com
123
+ ```
124
+
125
+ **`prodkit.toml`:**
126
+
127
+ ```toml
128
+ [prodkit]
129
+ environment = "production"
130
+
131
+ [logging]
132
+ level = "INFO"
133
+
134
+ [cors]
135
+ enabled = true
136
+ origins = ["https://app.example.com"]
137
+ ```
138
+
139
+ ### Fail-fast, refuse-unsafe
140
+
141
+ Misconfiguration fails **at startup with a named key**, never silently:
142
+
143
+ ```text
144
+ ProdKitConfigError: Invalid ProdKit configuration:
145
+ - logging.levle: Extra inputs are not permitted
146
+ ```
147
+
148
+ And configurations that would weaken a production deployment are refused,
149
+ not warned about:
150
+
151
+ - `debug=True` in production
152
+ - error responses that would leak tracebacks in production
153
+ - CORS `origins=["*"]` combined with `allow_credentials=True`
154
+
155
+ ## Writing a Plugin
156
+
157
+ ```python
158
+ from prodkit import Check, Plugin, Production
159
+
160
+ class DatabasePlugin(Plugin):
161
+ name = "database"
162
+
163
+ async def startup(self, ctx):
164
+ self.pool = await create_pool(...)
165
+ ctx.registry.provide("db", self.pool)
166
+
167
+ async def shutdown(self, ctx):
168
+ await self.pool.close()
169
+
170
+ def checks(self, ctx):
171
+ return [Check(name="database", passed=self.pool.is_alive())]
172
+
173
+ Production(app, plugins=[DatabasePlugin()])
174
+ ```
175
+
176
+ Your check now shows up in `/ready` automatically. Plugins can declare
177
+ `requires = ("other-plugin",)` and the kernel activates them in dependency
178
+ order — cycles and missing dependencies fail at boot.
179
+
180
+ Middleware registered by plugins carries an explicit integer priority, so
181
+ the middleware onion is always correctly ordered no matter what order
182
+ plugins load in (request-id outermost, compression innermost).
183
+
184
+ ## Plays Nice With Your App
185
+
186
+ - **Same app object.** Routes, dependencies, and existing middleware keep
187
+ working. Remove `Production(app)` and you have a plain FastAPI app again.
188
+ - **Your lifespan survives.** ProdKit *composes* with an existing `lifespan`:
189
+ plugin startup → your lifespan → plugin shutdown (LIFO).
190
+ - **Your headers win.** Security headers use set-if-absent semantics.
191
+ - **Every feature can be turned off.** `Production(app, security=False, ...)`
192
+
193
+ ## Project Status
194
+
195
+ **v0.1.0 — alpha.** Core kernel and seven built-in plugins, 60 tests, 98%
196
+ coverage, strict mypy, CI across Python 3.10–3.13.
197
+
198
+ Roadmap: `prodkit doctor` CLI with a production-readiness score (v0.2),
199
+ Prometheus metrics + Redis backends (v0.3), Dockerfile/nginx/CI generators
200
+ (v0.4), public plugin SDK (v0.5), auth helpers (v0.6), stable API (v1.0).
201
+ Full details in [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md).
202
+
203
+ ## Contributing
204
+
205
+ Contributions welcome — see [CONTRIBUTING.md](CONTRIBUTING.md).
206
+ Security reports: see [SECURITY.md](SECURITY.md) (never open a public issue).
207
+
208
+ ```bash
209
+ git clone https://github.com/Pushkarpant/PRODKIT
210
+ cd PRODKIT
211
+ python -m venv .venv && source .venv/bin/activate
212
+ pip install -e ".[dev]"
213
+ pytest
214
+ ```
215
+
216
+ ## License
217
+
218
+ [MIT](LICENSE)
219
+
220
+ ---
221
+
222
+ *FastAPI builds APIs. ProdKit makes them production-ready.*
@@ -0,0 +1,111 @@
1
+ [build-system]
2
+ requires = ["hatchling>=1.25"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "prodkit"
7
+ version = "0.1.0"
8
+ description = "The production framework for FastAPI. One line. Production ready."
9
+ readme = "README.md"
10
+ license = "MIT"
11
+ license-files = ["LICENSE"]
12
+ requires-python = ">=3.10"
13
+ authors = [{ name = "ProdKit Contributors" }]
14
+ keywords = [
15
+ "fastapi",
16
+ "production",
17
+ "middleware",
18
+ "security",
19
+ "observability",
20
+ "logging",
21
+ "health-check",
22
+ ]
23
+ classifiers = [
24
+ "Development Status :: 3 - Alpha",
25
+ "Intended Audience :: Developers",
26
+ "Operating System :: OS Independent",
27
+ "Programming Language :: Python :: 3",
28
+ "Programming Language :: Python :: 3.10",
29
+ "Programming Language :: Python :: 3.11",
30
+ "Programming Language :: Python :: 3.12",
31
+ "Programming Language :: Python :: 3.13",
32
+ "Framework :: FastAPI",
33
+ "Topic :: Internet :: WWW/HTTP :: HTTP Servers",
34
+ "Topic :: Software Development :: Libraries :: Application Frameworks",
35
+ "Typing :: Typed",
36
+ ]
37
+ dependencies = [
38
+ "fastapi>=0.110",
39
+ "pydantic>=2.5",
40
+ "pydantic-settings>=2.1",
41
+ "tomli>=2.0; python_version < '3.11'",
42
+ ]
43
+
44
+ [project.optional-dependencies]
45
+ brotli = ["brotli-asgi>=1.4"]
46
+ dev = [
47
+ "pytest>=8.0",
48
+ "pytest-cov>=5.0",
49
+ "httpx>=0.27",
50
+ "ruff>=0.6",
51
+ "mypy>=1.11",
52
+ "import-linter>=2.0",
53
+ "tomli>=2.0", # so mypy (python_version=3.10) can type-check the fallback import
54
+ ]
55
+
56
+ [project.urls]
57
+ Homepage = "https://github.com/Pushkarpant/PRODKIT"
58
+ Documentation = "https://github.com/Pushkarpant/PRODKIT#readme"
59
+ Repository = "https://github.com/Pushkarpant/PRODKIT"
60
+ Changelog = "https://github.com/Pushkarpant/PRODKIT/blob/main/CHANGELOG.md"
61
+ Issues = "https://github.com/Pushkarpant/PRODKIT/issues"
62
+
63
+ [tool.hatch.build.targets.wheel]
64
+ packages = ["src/prodkit"]
65
+
66
+ [tool.hatch.build.targets.sdist]
67
+ include = ["src/prodkit", "tests", "README.md", "LICENSE", "CHANGELOG.md"]
68
+
69
+ [tool.ruff]
70
+ target-version = "py310"
71
+ line-length = 99
72
+ src = ["src", "tests"]
73
+
74
+ [tool.ruff.lint]
75
+ select = [
76
+ "E", # pycodestyle errors
77
+ "W", # pycodestyle warnings
78
+ "F", # pyflakes
79
+ "I", # isort
80
+ "B", # bugbear
81
+ "UP", # pyupgrade
82
+ "S", # bandit (security)
83
+ "N", # pep8-naming
84
+ "C4", # comprehensions
85
+ "SIM", # simplify
86
+ "RUF", # ruff-specific
87
+ ]
88
+ [tool.ruff.lint.per-file-ignores]
89
+ "tests/**" = ["S101", "S106"] # asserts and test credentials are fine in tests
90
+
91
+ [tool.mypy]
92
+ python_version = "3.10"
93
+ strict = true
94
+ packages = ["prodkit"]
95
+ mypy_path = "src"
96
+
97
+ [tool.pytest.ini_options]
98
+ testpaths = ["tests"]
99
+ addopts = "--cov=prodkit --cov-report=term-missing --cov-fail-under=90"
100
+
101
+ [tool.coverage.run]
102
+ source = ["src/prodkit"]
103
+
104
+ [tool.importlinter]
105
+ root_package = "prodkit"
106
+
107
+ [[tool.importlinter.contracts]]
108
+ name = "Kernel must not depend on plugins"
109
+ type = "forbidden"
110
+ source_modules = ["prodkit.core", "prodkit.contracts"]
111
+ forbidden_modules = ["prodkit.plugins"]