django-bolt 0.1.0__cp310-abi3-win_amd64.whl → 0.1.2__cp310-abi3-win_amd64.whl
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.
Potentially problematic release.
This version of django-bolt might be problematic. Click here for more details.
- django_bolt/__init__.py +2 -2
- django_bolt/_core.pyd +0 -0
- django_bolt/_json.py +169 -0
- django_bolt/admin/static_routes.py +15 -21
- django_bolt/api.py +181 -61
- django_bolt/auth/__init__.py +2 -2
- django_bolt/decorators.py +15 -3
- django_bolt/dependencies.py +30 -24
- django_bolt/error_handlers.py +2 -1
- django_bolt/openapi/plugins.py +3 -2
- django_bolt/openapi/schema_generator.py +65 -20
- django_bolt/pagination.py +2 -1
- django_bolt/responses.py +3 -2
- django_bolt/serialization.py +5 -4
- {django_bolt-0.1.0.dist-info → django_bolt-0.1.2.dist-info}/METADATA +181 -201
- {django_bolt-0.1.0.dist-info → django_bolt-0.1.2.dist-info}/RECORD +18 -55
- django_bolt/auth/README.md +0 -464
- django_bolt/auth/REVOCATION_EXAMPLE.md +0 -391
- django_bolt/tests/__init__.py +0 -0
- django_bolt/tests/admin_tests/__init__.py +0 -1
- django_bolt/tests/admin_tests/conftest.py +0 -6
- django_bolt/tests/admin_tests/test_admin_with_django.py +0 -278
- django_bolt/tests/admin_tests/urls.py +0 -9
- django_bolt/tests/cbv/__init__.py +0 -0
- django_bolt/tests/cbv/test_class_views.py +0 -570
- django_bolt/tests/cbv/test_class_views_django_orm.py +0 -703
- django_bolt/tests/cbv/test_class_views_features.py +0 -1173
- django_bolt/tests/cbv/test_class_views_with_client.py +0 -622
- django_bolt/tests/conftest.py +0 -165
- django_bolt/tests/test_action_decorator.py +0 -399
- django_bolt/tests/test_auth_secret_key.py +0 -83
- django_bolt/tests/test_decorator_syntax.py +0 -159
- django_bolt/tests/test_error_handling.py +0 -481
- django_bolt/tests/test_file_response.py +0 -192
- django_bolt/tests/test_global_cors.py +0 -172
- django_bolt/tests/test_guards_auth.py +0 -441
- django_bolt/tests/test_guards_integration.py +0 -303
- django_bolt/tests/test_health.py +0 -283
- django_bolt/tests/test_integration_validation.py +0 -400
- django_bolt/tests/test_json_validation.py +0 -536
- django_bolt/tests/test_jwt_auth.py +0 -327
- django_bolt/tests/test_jwt_token.py +0 -458
- django_bolt/tests/test_logging.py +0 -837
- django_bolt/tests/test_logging_merge.py +0 -419
- django_bolt/tests/test_middleware.py +0 -492
- django_bolt/tests/test_middleware_server.py +0 -230
- django_bolt/tests/test_model_viewset.py +0 -323
- django_bolt/tests/test_models.py +0 -24
- django_bolt/tests/test_pagination.py +0 -1258
- django_bolt/tests/test_parameter_validation.py +0 -178
- django_bolt/tests/test_syntax.py +0 -626
- django_bolt/tests/test_testing_utilities.py +0 -163
- django_bolt/tests/test_testing_utilities_simple.py +0 -123
- django_bolt/tests/test_viewset_unified.py +0 -346
- {django_bolt-0.1.0.dist-info → django_bolt-0.1.2.dist-info}/WHEEL +0 -0
- {django_bolt-0.1.0.dist-info → django_bolt-0.1.2.dist-info}/entry_points.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: django-bolt
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.2
|
|
4
4
|
Classifier: Development Status :: 3 - Alpha
|
|
5
5
|
Classifier: Intended Audience :: Developers
|
|
6
6
|
Classifier: License :: OSI Approved :: MIT License
|
|
@@ -22,12 +22,10 @@ Classifier: Topic :: Internet :: WWW/HTTP :: HTTP Servers
|
|
|
22
22
|
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
|
|
23
23
|
Requires-Dist: django>=4.2
|
|
24
24
|
Requires-Dist: click>=8.1
|
|
25
|
-
Requires-Dist: pydantic>=2
|
|
26
25
|
Requires-Dist: msgspec>=0.18
|
|
27
|
-
Requires-Dist: maturin>=1.9.4
|
|
28
|
-
Requires-Dist: watchfiles>=0.24
|
|
29
|
-
Requires-Dist: pyyaml>=6.0
|
|
30
26
|
Requires-Dist: multipart>=1.3
|
|
27
|
+
Requires-Dist: pyyaml>=6.0 ; extra == 'yaml'
|
|
28
|
+
Provides-Extra: yaml
|
|
31
29
|
Summary: High-performance API framework for Django with Rust-powered endpoints delivering 60k+ RPS
|
|
32
30
|
Keywords: django,api,rust,performance,actix,pyo3,async
|
|
33
31
|
Author-email: Farhan <farhanalirazaazeemi@gmail.com>
|
|
@@ -42,32 +40,23 @@ Project-URL: Bug Tracker, https://github.com/FarhanAliRaza/django-bolt/issues
|
|
|
42
40
|
<div align="center">
|
|
43
41
|
<img src="docs/logo.png" alt="Django-Bolt Logo" width="400"/>
|
|
44
42
|
|
|
45
|
-
|
|
46
|
-
</div>
|
|
43
|
+
[](mailto:farhanalirazaazeemi@gmail.com)
|
|
47
44
|
|
|
48
|
-
|
|
45
|
+
</div>
|
|
49
46
|
|
|
50
|
-
|
|
47
|
+
# High-Performance Fully Typed API Framework for Django
|
|
51
48
|
|
|
52
|
-
**
|
|
53
|
-
|
|
54
|
-
- 🚀 **High Performance** - Rust-powered HTTP server (Actix Web + Tokio + PYO3)
|
|
55
|
-
- 🔐 **Authentication in Rust** - JWT/API Key validation without Python GIL
|
|
56
|
-
- 📦 **msgspec Serialization** - 5-10x faster than standard JSON
|
|
57
|
-
- 🎯 **Django Integration** - Use your existing Django models and other django features you love (django admin, django packages (All django packages will work except that use django middlware for now. I will work on some compatibilty layer to make them work but it is not a priority right now) )
|
|
58
|
-
- 🔄 **Async/Await** - Full async support with Python coroutines
|
|
59
|
-
- 🎛️ **Middleware System** - CORS, rate limiting, compression, custom middleware
|
|
60
|
-
- 🔒 **Guards & Permissions** - DRF and litestar inspired route protection
|
|
61
|
-
|
|
62
|
-
---
|
|
49
|
+
Your first question might be: why? Well, consider this: **Faster than _FastAPI_, but with Django ORM, Django Admin, and Django packages**. That’s exactly what this project achieves. Django-Bolt is a high-performance API framework for Django, providing Rust-powered API endpoints capable of 60k+ RPS. Similar to Django REST Framework or Django Ninja, it integrates seamlessly with existing Django projects while leveraging Actix Web for HTTP handling, PyO3 to bridge Python async handlers with Rust's async runtime, and msgspec for fast serialization. You can deploy it directly—no gunicorn or uvicorn needed.
|
|
63
50
|
|
|
64
51
|
## 🚀 Quick Start
|
|
65
52
|
|
|
66
|
-
### Installation
|
|
53
|
+
### Installation 🎉
|
|
67
54
|
|
|
68
|
-
|
|
55
|
+
```bash
|
|
56
|
+
pip install django-bolt
|
|
57
|
+
```
|
|
69
58
|
|
|
70
|
-
|
|
59
|
+
**📖 Full Documentation:** (Coming Soon).
|
|
71
60
|
|
|
72
61
|
### Run Your First API
|
|
73
62
|
|
|
@@ -93,34 +82,54 @@ async def get_user(user_id: int) -> UserSchema: # 🎉 Reponse is type validated
|
|
|
93
82
|
|
|
94
83
|
```bash
|
|
95
84
|
# Start the server
|
|
96
|
-
python manage.py runbolt --
|
|
85
|
+
python manage.py runbolt --dev # for development with reload enabled
|
|
86
|
+
[django-bolt] OpenAPI docs enabled at /docs
|
|
87
|
+
[django-bolt] Django admin enabled at http://0.0.0.0:8000/admin/ #django admin
|
|
88
|
+
[django-bolt] Static files serving enabled
|
|
89
|
+
[django-bolt] Found 94 routes
|
|
90
|
+
[django-bolt] Registered middleware for 83 handlers
|
|
91
|
+
[django-bolt] Starting server on http://0.0.0.0:8000
|
|
92
|
+
[django-bolt] Workers: 1, Processes: 1
|
|
93
|
+
[django-bolt] OpenAPI docs enabled at http://0.0.0.0:8000/docs/ #swagger docs builtin
|
|
94
|
+
|
|
97
95
|
# processes are python processes that handle request 1 actix worker
|
|
98
96
|
```
|
|
99
97
|
|
|
100
98
|
---
|
|
101
99
|
|
|
100
|
+
**Key Features:**
|
|
101
|
+
|
|
102
|
+
- 🚀 **High Performance** - Rust-powered HTTP server (Actix Web + Tokio + PyO3)
|
|
103
|
+
- 🔐 **Authentication in Rust** - JWT/API Key/Session validation without Python GIL
|
|
104
|
+
- 📦 **msgspec Serialization** - 5-10x faster than standard JSON
|
|
105
|
+
- 🎯 **Django Integration** - Use your existing Django models and other django features you love (django admin, django packages)
|
|
106
|
+
- 🔄 **Async/Await** - Full async support with Python coroutines
|
|
107
|
+
- 🎛️ **Middleware System** - CORS, rate limiting, compression (gzip/brotli/zstd)
|
|
108
|
+
- 🔒 **Guards & Permissions** - DRF and Litestar inspired route protection
|
|
109
|
+
- 📚 **OpenAPI Support** - 7 render plugins (Swagger, ReDoc, Scalar, RapidDoc, Stoplight, JSON, YAML)
|
|
110
|
+
- 📡 **Streaming Responses** - SSE, long-polling, async generators
|
|
111
|
+
- 🎨 **Class-Based Views** - ViewSet and ModelViewSet with DRF-style conventions
|
|
112
|
+
|
|
102
113
|
## 📊 Performance Benchmarks
|
|
103
114
|
|
|
104
115
|
> **⚠️ Disclaimer:** Django-Bolt is a **feature-incomplete framework** currently in development. Benchmarks were run on a Ryzen 5600G with 16GB RAM (8 processes × 1 worker, C=100 N=10000) on localhost. Performance will vary significantly based on hardware, OS, configuration, and workload.
|
|
105
116
|
>
|
|
106
|
-
> **📁 Resources:** Example project available at [python/
|
|
117
|
+
> **📁 Resources:** Example project available at [python/example/](python/example/). Run benchmarks with `make save-bench` or see [scripts/benchmark.sh](scripts/benchmark.sh).
|
|
107
118
|
|
|
108
119
|
| Endpoint Type | Requests/sec |
|
|
109
120
|
| -------------------------- | --------------- |
|
|
110
|
-
| Root endpoint | **~
|
|
111
|
-
| JSON parsing/validation | **~
|
|
112
|
-
| Path + Query params | **~
|
|
113
|
-
| HTML/Redirect responses | **~
|
|
114
|
-
| Form data handling | **~
|
|
115
|
-
| ORM reads (SQLite, 10 rec) | **~
|
|
121
|
+
| Root endpoint | **~85,000 RPS** |
|
|
122
|
+
| JSON parsing/validation | **~80,000 RPS** |
|
|
123
|
+
| Path + Query params | **~83,500 RPS** |
|
|
124
|
+
| HTML/Redirect responses | **~86,000 RPS** |
|
|
125
|
+
| Form data handling | **~68,000 RPS** |
|
|
126
|
+
| ORM reads (SQLite, 10 rec) | **~15,000 RPS** |
|
|
116
127
|
|
|
117
128
|
**Why so fast?**
|
|
118
129
|
|
|
119
|
-
-
|
|
130
|
+
- HTTP Parsing and Reponse is handled Actix-rs framework(One of the fastest in the world)
|
|
120
131
|
- Request routing uses matchit (zero-copy path matching)
|
|
121
|
-
- No middleware overhead if not required
|
|
122
132
|
- JSON serialization with msgspec
|
|
123
|
-
- Multi-process with SO_REUSEPORT (kernel-level load balancing)
|
|
124
133
|
|
|
125
134
|
---
|
|
126
135
|
|
|
@@ -169,17 +178,25 @@ python manage.py runbolt --host 0.0.0.0 --port 8000 --processes 4 --workers 1
|
|
|
169
178
|
|
|
170
179
|
- Algorithms: HS256, HS384, HS512, RS256, RS384, RS512, ES256, ES384, ES512
|
|
171
180
|
- Token validation in Rust (zero Python overhead)
|
|
172
|
-
- Expiration validation
|
|
173
|
-
- Custom claims support
|
|
181
|
+
- Expiration validation (`exp`) and not-before (`nbf`) checks
|
|
182
|
+
- Custom claims support with audience/issuer validation
|
|
174
183
|
- Django User integration helpers
|
|
175
|
-
- Token revocation support (optional)
|
|
184
|
+
- Token revocation support (optional: `InMemoryRevocation`, `DjangoCacheRevocation`, `DjangoORMRevocation`)
|
|
176
185
|
|
|
177
|
-
- ✅ **API Key Authentication** - **
|
|
186
|
+
- ✅ **API Key Authentication** - **Complete** (runs in Rust without GIL)
|
|
178
187
|
|
|
179
|
-
- Header-based API keys
|
|
188
|
+
- Header-based API keys (Bearer or ApiKey prefix)
|
|
180
189
|
- Per-key permissions
|
|
190
|
+
- Constant-time comparison (timing attack prevention)
|
|
181
191
|
- Fast validation in Rust
|
|
182
192
|
|
|
193
|
+
- ✅ **Session Authentication** - **Complete** (Django session integration)
|
|
194
|
+
|
|
195
|
+
- Django session backend integration
|
|
196
|
+
- Automatic user lookup from session
|
|
197
|
+
- Compatible with Django's session middleware
|
|
198
|
+
- Supports both cookie-based and custom session stores
|
|
199
|
+
|
|
183
200
|
- ✅ **Permission Guards** (all run in Rust):
|
|
184
201
|
|
|
185
202
|
- `AllowAny()` - Public access
|
|
@@ -190,81 +207,28 @@ python manage.py runbolt --host 0.0.0.0 --port 8000 --processes 4 --workers 1
|
|
|
190
207
|
- `HasAnyPermission("p1", "p2")` - OR logic
|
|
191
208
|
- `HasAllPermissions("p1", "p2")` - AND logic
|
|
192
209
|
|
|
193
|
-
- ✅ **Auth Context** - Request-level auth context with user info
|
|
210
|
+
- ✅ **Auth Context** - Request-level auth context with user info, permissions, and backend details
|
|
194
211
|
- ✅ **Token Utilities**:
|
|
195
212
|
|
|
196
|
-
- `create_jwt_for_user(user)` - Generate JWT for Django User
|
|
213
|
+
- `create_jwt_for_user(user, exp_hours=24)` - Generate JWT for Django User
|
|
214
|
+
- Custom claims and permissions support
|
|
197
215
|
|
|
198
|
-
|
|
199
|
-
- `InMemoryRevocation` - In-memory token blacklist
|
|
200
|
-
- `DjangoCacheRevocation` - Cache-based revocation
|
|
201
|
-
- `DjangoORMRevocation` - Database-backed revocation
|
|
216
|
+
**📖 See [docs/SECURITY.md](docs/SECURITY.md) for complete authentication documentation.**
|
|
202
217
|
|
|
203
218
|
### Developer Tools ✅
|
|
204
219
|
|
|
205
220
|
- ✅ **CLI** - `python -m django_bolt init` for project setup
|
|
206
|
-
- ✅ **Management Command** - `python manage.py runbolt`
|
|
207
|
-
- ✅ **Auto-Discovery** - Finds
|
|
208
|
-
-
|
|
221
|
+
- ✅ **Management Command** - `python manage.py runbolt` with auto-discovery
|
|
222
|
+
- ✅ **Auto-Discovery** - Finds `api.py` in project root and all Django apps
|
|
223
|
+
- ✅ **OpenAPI/Swagger** - 7 render plugins: Swagger UI, ReDoc, Scalar, RapidDoc, Stoplight Elements, JSON, YAML
|
|
224
|
+
- ✅ **Error Messages** - Clear, structured error messages with Django DEBUG integration
|
|
209
225
|
- ✅ **Type Hints** - Full type hint support with msgspec
|
|
226
|
+
- ✅ **Dependency Injection** - `Depends()` marker with per-request caching
|
|
210
227
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
## 📋 TODO / Roadmap
|
|
214
|
-
|
|
215
|
-
### Must Have (Blockers) 🚨
|
|
216
|
-
|
|
217
|
-
- ✅ **Core API functionality** - DONE
|
|
218
|
-
- ✅ **Authentication** - DONE (JWT complete)
|
|
219
|
-
- ✅ **Tests passing** - DONE (142 passed)
|
|
220
|
-
- ✅ **Better error messages** - DONE (Enhanced exception system with structured errors)
|
|
221
|
-
- ✅ **Health check endpoints** - DONE (`/health`, `/ready` with custom checks)
|
|
222
|
-
- ✅ **Request/Response logging** - DONE (Integrates with Django's logging)
|
|
223
|
-
- ❌ **PyPI package** - Missing (currently manual install)
|
|
224
|
-
|
|
225
|
-
### Should Have (Important) 🎯
|
|
226
|
-
|
|
227
|
-
- ✅ **Error handling with Django DEBUG integration** - DONE
|
|
228
|
-
- ✅ **Structured error responses** (FastAPI-compatible) - DONE
|
|
229
|
-
- ✅ **Response compression** - DONE (gzip/brotli/zstd)
|
|
230
|
-
- ✅ **OpenAPI/Swagger docs** - DONE (some parts remaining like grouping)
|
|
231
|
-
- ✅ **Django admin integration** - DONE
|
|
232
|
-
- ⚠️ **API Key auth** - Partial (only in-memory)
|
|
233
|
-
- ⚠️ **Testing utilities** - Partial
|
|
234
|
-
|
|
235
|
-
### Nice to Have (Can defer) 📝
|
|
236
|
-
|
|
237
|
-
- [ ] **Static file serving** - Efficient static file serving from Rust
|
|
238
|
-
- [ ] **Pagination helpers** - Built-in pagination utilities
|
|
239
|
-
- [ ] **OAuth2/OpenID** - OAuth2 and OpenID Connect support
|
|
240
|
-
- [ ] **API Versioning** - URL/header-based versioning
|
|
241
|
-
- [ ] **Content Negotiation** - Accept header-based content negotiation
|
|
242
|
-
- [ ] **ETags & Conditional Requests** - Caching optimization
|
|
243
|
-
- [ ] **Filtering & Sorting** - Query parameter-based filtering
|
|
228
|
+
**📖 See [docs/README.md](docs/README.md) for complete documentation index.**
|
|
244
229
|
|
|
245
230
|
---
|
|
246
231
|
|
|
247
|
-
## 🏗️ Architecture
|
|
248
|
-
|
|
249
|
-
### Core Components
|
|
250
|
-
|
|
251
|
-
1. **[src/lib.rs](src/lib.rs)** - Main Rust entry point, exposes PyO3 module
|
|
252
|
-
2. **[src/server.rs](src/server.rs)** - Actix Web server with multi-worker tokio runtime
|
|
253
|
-
3. **[src/router.rs](src/router.rs)** - matchit-based routing
|
|
254
|
-
4. **[src/middleware/](src/middleware/)** - Middleware pipeline
|
|
255
|
-
- `auth.rs` - JWT/API Key authentication (zero GIL overhead)
|
|
256
|
-
- `cors.rs` - CORS handling
|
|
257
|
-
- `rate_limit.rs` - Token bucket rate limiting
|
|
258
|
-
5. **[src/permissions.rs](src/permissions.rs)** - Guard evaluation
|
|
259
|
-
6. **[python/django_bolt/api.py](python/django_bolt/api.py)** - Python decorator-based API
|
|
260
|
-
7. **[python/django_bolt/auth/](python/django_bolt/auth/)** - Authentication system
|
|
261
|
-
- `backends.py` - Auth backend classes (compile to Rust metadata)
|
|
262
|
-
- `guards.py` - Permission guard classes
|
|
263
|
-
- `jwt_utils.py` - JWT utilities for Django User integration
|
|
264
|
-
- `middleware.py` - Middleware decorators
|
|
265
|
-
- `token.py` - Token handling
|
|
266
|
-
- `revocation.py` - Token revocation stores
|
|
267
|
-
|
|
268
232
|
### Request Flow
|
|
269
233
|
|
|
270
234
|
```
|
|
@@ -276,9 +240,10 @@ HTTP Request → Actix Web (Rust)
|
|
|
276
240
|
- CORS
|
|
277
241
|
- Rate Limiting
|
|
278
242
|
↓
|
|
279
|
-
Authentication (Rust - no GIL
|
|
280
|
-
- JWT validation
|
|
281
|
-
- API Key validation
|
|
243
|
+
Authentication (Rust - no GIL)
|
|
244
|
+
- JWT validation (HS256/384/512, RS256/384/512, ES256/384)
|
|
245
|
+
- API Key validation (constant-time comparison)
|
|
246
|
+
- Session validation (Django session integration)
|
|
282
247
|
↓
|
|
283
248
|
Guards/Permissions (Rust - no GIL)
|
|
284
249
|
- IsAuthenticated
|
|
@@ -300,6 +265,20 @@ HTTP Request → Actix Web (Rust)
|
|
|
300
265
|
|
|
301
266
|
---
|
|
302
267
|
|
|
268
|
+
## 📖 Documentation (Coming Soon)
|
|
269
|
+
|
|
270
|
+
- **[Getting Started Guide](docs/GETTING_STARTED.md)** - Complete tutorial from installation to first API
|
|
271
|
+
- **[Security Guide](docs/SECURITY.md)** - Authentication, authorization, CORS, rate limiting
|
|
272
|
+
- **[Middleware Guide](docs/MIDDLEWARE.md)** - CORS, rate limiting, custom middleware
|
|
273
|
+
- **[Responses Guide](docs/RESPONSES.md)** - All response types and streaming
|
|
274
|
+
- **[Class-Based Views](docs/CLASS_BASED_VIEWS.md)** - ViewSet and ModelViewSet patterns
|
|
275
|
+
- **[OpenAPI Guide](docs/OPENAPI.md)** - Auto-generated API documentation
|
|
276
|
+
- **[Pagination Guide](docs/PAGINATION.md)** - PageNumber, LimitOffset, Cursor pagination
|
|
277
|
+
- **[Logging Guide](docs/LOGGING.md)** - Request/response logging and metrics
|
|
278
|
+
- **[Full Documentation Index](docs/README.md)** - Complete list of all documentation
|
|
279
|
+
|
|
280
|
+
---
|
|
281
|
+
|
|
303
282
|
## 📖 Usage Examples
|
|
304
283
|
|
|
305
284
|
### Basic Routes
|
|
@@ -344,6 +323,7 @@ async def create_user(user: CreateUserRequest):
|
|
|
344
323
|
from django_bolt import BoltAPI
|
|
345
324
|
from django_bolt.auth import (
|
|
346
325
|
JWTAuthentication,
|
|
326
|
+
APIKeyAuthentication,
|
|
347
327
|
IsAuthenticated,
|
|
348
328
|
IsAdminUser,
|
|
349
329
|
HasPermission,
|
|
@@ -351,25 +331,25 @@ from django_bolt.auth import (
|
|
|
351
331
|
|
|
352
332
|
api = BoltAPI()
|
|
353
333
|
|
|
354
|
-
#
|
|
334
|
+
# JWT Authentication
|
|
355
335
|
@api.get(
|
|
356
336
|
"/protected",
|
|
357
337
|
auth=[JWTAuthentication()],
|
|
358
338
|
guards=[IsAuthenticated()]
|
|
359
339
|
)
|
|
360
340
|
async def protected_route(request):
|
|
361
|
-
|
|
362
|
-
user_id =
|
|
341
|
+
auth = request.get("auth", {})
|
|
342
|
+
user_id = auth.get("user_id")
|
|
363
343
|
return {"message": f"Hello, user {user_id}"}
|
|
364
344
|
|
|
365
|
-
#
|
|
345
|
+
# API Key Authentication
|
|
366
346
|
@api.get(
|
|
367
|
-
"/
|
|
368
|
-
auth=[
|
|
369
|
-
guards=[
|
|
347
|
+
"/api-data",
|
|
348
|
+
auth=[APIKeyAuthentication(api_keys={"key1", "key2"})],
|
|
349
|
+
guards=[IsAuthenticated()]
|
|
370
350
|
)
|
|
371
|
-
async def
|
|
372
|
-
return {"message": "
|
|
351
|
+
async def api_data(request):
|
|
352
|
+
return {"message": "API key authenticated"}
|
|
373
353
|
|
|
374
354
|
# Permission-based access
|
|
375
355
|
@api.post(
|
|
@@ -392,11 +372,13 @@ async def login(username: str, password: str):
|
|
|
392
372
|
return {"access_token": token, "token_type": "bearer"}
|
|
393
373
|
```
|
|
394
374
|
|
|
375
|
+
**📖 See [docs/SECURITY.md](docs/SECURITY.md) for complete authentication documentation.**
|
|
376
|
+
|
|
395
377
|
### Middleware
|
|
396
378
|
|
|
397
379
|
```python
|
|
398
380
|
from django_bolt import BoltAPI
|
|
399
|
-
from django_bolt.
|
|
381
|
+
from django_bolt.middleware import cors, rate_limit, skip_middleware
|
|
400
382
|
|
|
401
383
|
# Global middleware
|
|
402
384
|
api = BoltAPI(
|
|
@@ -404,29 +386,38 @@ api = BoltAPI(
|
|
|
404
386
|
"cors": {
|
|
405
387
|
"origins": ["http://localhost:3000"],
|
|
406
388
|
"methods": ["GET", "POST", "PUT", "DELETE"],
|
|
389
|
+
"credentials": True,
|
|
407
390
|
}
|
|
408
391
|
}
|
|
409
392
|
)
|
|
410
393
|
|
|
411
|
-
# Per-route rate limiting
|
|
394
|
+
# Per-route rate limiting (runs in Rust, no GIL)
|
|
412
395
|
@api.get("/limited")
|
|
413
|
-
@rate_limit(rps=
|
|
396
|
+
@rate_limit(rps=100, burst=200, key="ip") # 100 req/s with burst of 200
|
|
414
397
|
async def limited_endpoint():
|
|
415
|
-
return {"message": "Rate limited
|
|
398
|
+
return {"message": "Rate limited"}
|
|
399
|
+
|
|
400
|
+
# Rate limiting by user ID
|
|
401
|
+
@api.get("/user-limited", auth=[JWTAuthentication()], guards=[IsAuthenticated()])
|
|
402
|
+
@rate_limit(rps=50, burst=100, key="user")
|
|
403
|
+
async def user_limited():
|
|
404
|
+
return {"message": "Per-user rate limiting"}
|
|
416
405
|
|
|
417
406
|
# Custom CORS for specific route
|
|
418
407
|
@api.get("/public")
|
|
419
|
-
@cors(origins=["
|
|
408
|
+
@cors(origins=["https://example.com"], credentials=True, max_age=3600)
|
|
420
409
|
async def public_endpoint():
|
|
421
410
|
return {"message": "Public endpoint with CORS"}
|
|
422
411
|
|
|
423
412
|
# Skip global middleware
|
|
424
413
|
@api.get("/no-cors")
|
|
425
|
-
@skip_middleware("cors")
|
|
414
|
+
@skip_middleware("cors", "rate_limit")
|
|
426
415
|
async def no_cors():
|
|
427
|
-
return {"message": "
|
|
416
|
+
return {"message": "Middleware skipped"}
|
|
428
417
|
```
|
|
429
418
|
|
|
419
|
+
**📖 See [docs/MIDDLEWARE.md](docs/MIDDLEWARE.md) for complete middleware documentation.**
|
|
420
|
+
|
|
430
421
|
### Django ORM Integration
|
|
431
422
|
|
|
432
423
|
```python
|
|
@@ -464,7 +455,10 @@ async def list_articles(limit: int = 10):
|
|
|
464
455
|
|
|
465
456
|
```python
|
|
466
457
|
from django_bolt import BoltAPI
|
|
467
|
-
from django_bolt.responses import
|
|
458
|
+
from django_bolt.responses import (
|
|
459
|
+
PlainText, HTML, Redirect, File, FileResponse, StreamingResponse
|
|
460
|
+
)
|
|
461
|
+
import asyncio
|
|
468
462
|
|
|
469
463
|
api = BoltAPI()
|
|
470
464
|
|
|
@@ -478,25 +472,22 @@ async def html_response():
|
|
|
478
472
|
|
|
479
473
|
@api.get("/redirect")
|
|
480
474
|
async def redirect_response():
|
|
481
|
-
return Redirect("/new-location")
|
|
482
|
-
|
|
483
|
-
@api.get("/download")
|
|
484
|
-
async def download_file():
|
|
485
|
-
# Streams file from Rust (zero-copy)
|
|
486
|
-
return FileResponse("/path/to/file.pdf", filename="document.pdf")
|
|
487
|
-
```
|
|
475
|
+
return Redirect("/new-location", status_code=302)
|
|
488
476
|
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
import asyncio
|
|
477
|
+
@api.get("/download-memory")
|
|
478
|
+
async def download_memory():
|
|
479
|
+
# In-memory file download
|
|
480
|
+
content = b"File contents here"
|
|
481
|
+
return File(content, filename="document.txt", media_type="text/plain")
|
|
495
482
|
|
|
496
|
-
api
|
|
483
|
+
@api.get("/download-disk")
|
|
484
|
+
async def download_disk():
|
|
485
|
+
# Streams file from disk (zero-copy in Rust)
|
|
486
|
+
return FileResponse("/path/to/file.pdf", filename="document.pdf")
|
|
497
487
|
|
|
498
|
-
@api.get("/stream")
|
|
499
|
-
async def
|
|
488
|
+
@api.get("/stream-sse")
|
|
489
|
+
async def stream_sse():
|
|
490
|
+
# Server-Sent Events
|
|
500
491
|
async def generate():
|
|
501
492
|
for i in range(100):
|
|
502
493
|
yield f"data: {i}\n\n"
|
|
@@ -506,8 +497,23 @@ async def stream_data():
|
|
|
506
497
|
generate(),
|
|
507
498
|
media_type="text/event-stream"
|
|
508
499
|
)
|
|
500
|
+
|
|
501
|
+
@api.get("/stream-json")
|
|
502
|
+
async def stream_json():
|
|
503
|
+
# Streaming JSON (sync generator)
|
|
504
|
+
def generate():
|
|
505
|
+
yield '{"items": ['
|
|
506
|
+
for i in range(1000):
|
|
507
|
+
yield f'{{"id": {i}}}'
|
|
508
|
+
if i < 999:
|
|
509
|
+
yield ','
|
|
510
|
+
yield ']}'
|
|
511
|
+
|
|
512
|
+
return StreamingResponse(generate(), media_type="application/json")
|
|
509
513
|
```
|
|
510
514
|
|
|
515
|
+
**📖 See [docs/RESPONSES.md](docs/RESPONSES.md) for complete response documentation.**
|
|
516
|
+
|
|
511
517
|
---
|
|
512
518
|
|
|
513
519
|
## 🔧 Development
|
|
@@ -538,68 +544,11 @@ make rebuild # Clean and rebuild
|
|
|
538
544
|
|
|
539
545
|
# Testing
|
|
540
546
|
make test-py # Run Python tests
|
|
541
|
-
make smoke # Quick smoke tests
|
|
542
|
-
make orm-smoke # ORM-specific tests
|
|
543
547
|
|
|
544
548
|
# Benchmarking
|
|
545
|
-
make bench # Run benchmarks
|
|
546
549
|
make save-bench # Run and save results
|
|
547
|
-
make bench C=100 N=50000 # Custom benchmark
|
|
548
550
|
|
|
549
551
|
# Server
|
|
550
|
-
make run-bg HOST=127.0.0.1 PORT=8000 P=2 WORKERS=2
|
|
551
|
-
```
|
|
552
|
-
|
|
553
|
-
---
|
|
554
|
-
|
|
555
|
-
## 📁 Project Structure
|
|
556
|
-
|
|
557
|
-
```
|
|
558
|
-
django-bolt/
|
|
559
|
-
├── src/ # Rust server code
|
|
560
|
-
│ ├── lib.rs # PyO3 module entry point
|
|
561
|
-
│ ├── server.rs # Actix Web server
|
|
562
|
-
│ ├── router.rs # matchit routing
|
|
563
|
-
│ ├── middleware/
|
|
564
|
-
│ │ ├── mod.rs
|
|
565
|
-
│ │ ├── auth.rs # JWT/API Key auth (no GIL)
|
|
566
|
-
│ │ ├── cors.rs # CORS handling
|
|
567
|
-
│ │ └── rate_limit.rs # Token bucket rate limiting
|
|
568
|
-
│ ├── permissions.rs # Guard evaluation
|
|
569
|
-
│ └── streaming.rs # Streaming response handling
|
|
570
|
-
├── python/django_bolt/ # Python framework
|
|
571
|
-
│ ├── api.py # BoltAPI class, decorators
|
|
572
|
-
│ ├── responses.py # Response types
|
|
573
|
-
│ ├── exceptions.py # HTTP exceptions
|
|
574
|
-
│ ├── params.py # Parameter markers
|
|
575
|
-
│ ├── auth/ # Authentication system
|
|
576
|
-
│ │ ├── __init__.py
|
|
577
|
-
│ │ ├── backends.py # Auth backends
|
|
578
|
-
│ │ ├── guards.py # Permission guards
|
|
579
|
-
│ │ ├── middleware.py # Middleware decorators
|
|
580
|
-
│ │ ├── jwt_utils.py # JWT utilities
|
|
581
|
-
│ │ ├── token.py # Token handling
|
|
582
|
-
│ │ └── revocation.py # Token revocation
|
|
583
|
-
│ ├── management/commands/
|
|
584
|
-
│ │ └── runbolt.py # Django management command
|
|
585
|
-
│ ├── cli.py # django-bolt CLI
|
|
586
|
-
│ ├── tests/ # Test suite
|
|
587
|
-
│ │ ├── test_auth_secret_key.py
|
|
588
|
-
│ │ ├── test_guards_auth.py
|
|
589
|
-
│ │ ├── test_guards_integration.py
|
|
590
|
-
│ │ ├── test_jwt_auth.py
|
|
591
|
-
│ │ ├── test_jwt_token.py
|
|
592
|
-
│ │ ├── test_middleware.py
|
|
593
|
-
│ │ └── test_syntax.py
|
|
594
|
-
│ └── bootstrap.py # Django setup helper
|
|
595
|
-
└── python/examples/testproject/ # Example Django project
|
|
596
|
-
├── manage.py
|
|
597
|
-
├── testproject/
|
|
598
|
-
│ ├── settings.py
|
|
599
|
-
│ └── api.py # Example routes
|
|
600
|
-
└── users/ # Example app
|
|
601
|
-
├── models.py
|
|
602
|
-
└── api.py
|
|
603
552
|
```
|
|
604
553
|
|
|
605
554
|
---
|
|
@@ -618,12 +567,43 @@ Contributions welcome! Here's how:
|
|
|
618
567
|
|
|
619
568
|
### Areas That Need Help
|
|
620
569
|
|
|
621
|
-
-
|
|
622
|
-
-
|
|
623
|
-
-
|
|
624
|
-
-
|
|
570
|
+
- Testing utilities and test client
|
|
571
|
+
- WebSocket support
|
|
572
|
+
- OAuth2/OpenID Connect
|
|
573
|
+
- API versioning
|
|
574
|
+
- More examples and tutorials
|
|
625
575
|
|
|
626
576
|
---
|
|
627
577
|
|
|
628
|
-
|
|
629
|
-
|
|
578
|
+
## 🙏 Acknowledgments & Inspiration
|
|
579
|
+
|
|
580
|
+
Django-Bolt stands on the shoulders of giants. We're grateful to the following projects and communities that inspired our design and implementation:
|
|
581
|
+
|
|
582
|
+
### Core Inspirations
|
|
583
|
+
|
|
584
|
+
- **[Django REST Framework](https://github.com/encode/django-rest-framework)** - Our syntax, ViewSet patterns, and permission system are heavily inspired by DRF's elegant API design. The class-based views and guard system follow DRF's philosophy of making common patterns simple.
|
|
585
|
+
|
|
586
|
+
- **[FastAPI](https://github.com/tivy520/fastapi)** - We drew extensive inspiration from FastAPI's dependency injection system, parameter extraction patterns, and modern Python type hints usage. The codebase structure and async patterns heavily influenced our implementation.
|
|
587
|
+
|
|
588
|
+
- **[Litestar](https://github.com/litestar-org/litestar)** - Our OpenAPI plugin system is adapted from Litestar's excellent architecture. Many architectural decisions around middleware, guards, and route handling were inspired by Litestar's design philosophy.
|
|
589
|
+
|
|
590
|
+
- **[Robyn](https://github.com/sparckles/Robyn)** - Robyn's Rust-Python integration patterns and performance-first approach influenced our decision to use PyO3 and showed us the potential of Rust-powered Python web frameworks.
|
|
591
|
+
|
|
592
|
+
### Additional Credits
|
|
593
|
+
|
|
594
|
+
- **[Actix Web](https://github.com/actix/actix-web)** - The Rust HTTP framework that powers our performance
|
|
595
|
+
- **[PyO3](https://github.com/PyO3/pyo3)** - For making Rust-Python interop seamless
|
|
596
|
+
- **[msgspec](https://github.com/jcrist/msgspec)** - For blazing-fast serialization
|
|
597
|
+
- **[matchit](https://github.com/ibraheemdev/matchit)** - For zero-copy routing
|
|
598
|
+
|
|
599
|
+
Thank you to all the maintainers, contributors, and communities behind these projects. Django-Bolt wouldn't exist without your incredible work.
|
|
600
|
+
|
|
601
|
+
---
|
|
602
|
+
|
|
603
|
+
## 📄 License
|
|
604
|
+
|
|
605
|
+
Django-Bolt is open source and available under the MIT License.
|
|
606
|
+
|
|
607
|
+
---
|
|
608
|
+
|
|
609
|
+
For questions, issues, or feature requests, please visit our [GitHub repository](https://github.com/FarhanAliRaza/django-bolt).
|