django-bolt 0.2.5__cp310-abi3-win_amd64.whl → 0.2.7__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/_core.pyd +0 -0
- django_bolt/compression.py +8 -42
- django_bolt/management/commands/runbolt.py +34 -17
- {django_bolt-0.2.5.dist-info → django_bolt-0.2.7.dist-info}/METADATA +2 -1
- {django_bolt-0.2.5.dist-info → django_bolt-0.2.7.dist-info}/RECORD +7 -7
- {django_bolt-0.2.5.dist-info → django_bolt-0.2.7.dist-info}/WHEEL +0 -0
- {django_bolt-0.2.5.dist-info → django_bolt-0.2.7.dist-info}/entry_points.txt +0 -0
django_bolt/_core.pyd
CHANGED
|
Binary file
|
django_bolt/compression.py
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
Compression configuration for Django-Bolt.
|
|
3
3
|
|
|
4
4
|
Provides configuration options for response compression (gzip, brotli, zstd).
|
|
5
|
-
|
|
5
|
+
Compression levels are handled automatically by Actix Web with optimized defaults.
|
|
6
6
|
"""
|
|
7
|
-
from typing import
|
|
7
|
+
from typing import Literal
|
|
8
8
|
from dataclasses import dataclass
|
|
9
9
|
|
|
10
10
|
|
|
@@ -17,41 +17,31 @@ class CompressionConfig:
|
|
|
17
17
|
|
|
18
18
|
Args:
|
|
19
19
|
backend: The compression backend to use (default: "brotli")
|
|
20
|
-
|
|
20
|
+
Can be "gzip", "brotli", or "zstd". Built-in compression with optimized defaults.
|
|
21
21
|
minimum_size: Minimum response size in bytes to enable compression (default: 500)
|
|
22
22
|
Responses smaller than this will not be compressed.
|
|
23
|
-
gzip_compress_level: Range [0-9] for gzip compression (default: 9)
|
|
24
|
-
Higher values provide better compression but are slower.
|
|
25
|
-
brotli_quality: Range [0-11] for brotli compression (default: 5)
|
|
26
|
-
Controls compression-speed vs compression-density tradeoff.
|
|
27
|
-
brotli_lgwin: Base 2 logarithm of window size for brotli (default: 22)
|
|
28
|
-
Range is 10 to 24. Larger values can improve compression for large files.
|
|
29
|
-
zstd_level: Range [1-22] for zstd compression (default: 3)
|
|
30
|
-
Higher values provide better compression but are slower.
|
|
31
23
|
gzip_fallback: Use GZIP if the client doesn't support the configured backend (default: True)
|
|
24
|
+
Falls back to gzip for broader client compatibility.
|
|
32
25
|
|
|
33
26
|
Examples:
|
|
34
27
|
# Default compression (brotli with gzip fallback)
|
|
35
28
|
api = BoltAPI(compression=CompressionConfig())
|
|
36
29
|
|
|
37
|
-
#
|
|
30
|
+
# Brotli compression with smaller minimum size
|
|
38
31
|
api = BoltAPI(compression=CompressionConfig(
|
|
39
32
|
backend="brotli",
|
|
40
|
-
brotli_quality=11,
|
|
41
33
|
minimum_size=256
|
|
42
34
|
))
|
|
43
35
|
|
|
44
|
-
# Gzip only (
|
|
36
|
+
# Gzip only (no fallback)
|
|
45
37
|
api = BoltAPI(compression=CompressionConfig(
|
|
46
38
|
backend="gzip",
|
|
47
|
-
gzip_compress_level=9,
|
|
48
39
|
gzip_fallback=False
|
|
49
40
|
))
|
|
50
41
|
|
|
51
|
-
#
|
|
42
|
+
# Zstd compression with gzip fallback
|
|
52
43
|
api = BoltAPI(compression=CompressionConfig(
|
|
53
|
-
backend="zstd"
|
|
54
|
-
zstd_level=1
|
|
44
|
+
backend="zstd"
|
|
55
45
|
))
|
|
56
46
|
|
|
57
47
|
# Disable compression
|
|
@@ -59,10 +49,6 @@ class CompressionConfig:
|
|
|
59
49
|
"""
|
|
60
50
|
backend: Literal["gzip", "brotli", "zstd"] = "brotli"
|
|
61
51
|
minimum_size: int = 500
|
|
62
|
-
gzip_compress_level: int = 9
|
|
63
|
-
brotli_quality: int = 5
|
|
64
|
-
brotli_lgwin: int = 22
|
|
65
|
-
zstd_level: int = 3
|
|
66
52
|
gzip_fallback: bool = True
|
|
67
53
|
|
|
68
54
|
def __post_init__(self):
|
|
@@ -75,30 +61,10 @@ class CompressionConfig:
|
|
|
75
61
|
if self.minimum_size < 0:
|
|
76
62
|
raise ValueError("minimum_size must be non-negative")
|
|
77
63
|
|
|
78
|
-
# Validate gzip_compress_level
|
|
79
|
-
if not (0 <= self.gzip_compress_level <= 9):
|
|
80
|
-
raise ValueError("gzip_compress_level must be between 0 and 9")
|
|
81
|
-
|
|
82
|
-
# Validate brotli_quality
|
|
83
|
-
if not (0 <= self.brotli_quality <= 11):
|
|
84
|
-
raise ValueError("brotli_quality must be between 0 and 11")
|
|
85
|
-
|
|
86
|
-
# Validate brotli_lgwin
|
|
87
|
-
if not (10 <= self.brotli_lgwin <= 24):
|
|
88
|
-
raise ValueError("brotli_lgwin must be between 10 and 24")
|
|
89
|
-
|
|
90
|
-
# Validate zstd_level
|
|
91
|
-
if not (1 <= self.zstd_level <= 22):
|
|
92
|
-
raise ValueError("zstd_level must be between 1 and 22")
|
|
93
|
-
|
|
94
64
|
def to_rust_config(self) -> dict:
|
|
95
65
|
"""Convert to dictionary for passing to Rust."""
|
|
96
66
|
return {
|
|
97
67
|
"backend": self.backend,
|
|
98
68
|
"minimum_size": self.minimum_size,
|
|
99
|
-
"gzip_compress_level": self.gzip_compress_level,
|
|
100
|
-
"brotli_quality": self.brotli_quality,
|
|
101
|
-
"brotli_lgwin": self.brotli_lgwin,
|
|
102
|
-
"zstd_level": self.zstd_level,
|
|
103
69
|
"gzip_fallback": self.gzip_fallback,
|
|
104
70
|
}
|
|
@@ -40,6 +40,12 @@ class Command(BaseCommand):
|
|
|
40
40
|
default=1024,
|
|
41
41
|
help="Socket listen backlog size (default: 1024)"
|
|
42
42
|
)
|
|
43
|
+
parser.add_argument(
|
|
44
|
+
"--keep-alive",
|
|
45
|
+
type=int,
|
|
46
|
+
default=None,
|
|
47
|
+
help="HTTP keep-alive timeout in seconds (default: OS setting)"
|
|
48
|
+
)
|
|
43
49
|
|
|
44
50
|
def handle(self, *args, **options):
|
|
45
51
|
processes = options['processes']
|
|
@@ -252,10 +258,12 @@ class Command(BaseCommand):
|
|
|
252
258
|
else:
|
|
253
259
|
self.stdout.write(self.style.SUCCESS(f"[django-bolt] Starting server on http://{options['host']}:{options['port']}"))
|
|
254
260
|
self.stdout.write(f"[django-bolt] Workers: {options['workers']}, Processes: {options['processes']}")
|
|
255
|
-
# Set environment variable for Rust to read worker count and
|
|
261
|
+
# Set environment variable for Rust to read worker count, backlog, and keep-alive
|
|
256
262
|
import os
|
|
257
263
|
os.environ['DJANGO_BOLT_WORKERS'] = str(options['workers'])
|
|
258
264
|
os.environ['DJANGO_BOLT_BACKLOG'] = str(options['backlog'])
|
|
265
|
+
if options.get('keep_alive') is not None:
|
|
266
|
+
os.environ['DJANGO_BOLT_KEEP_ALIVE'] = str(options['keep_alive'])
|
|
259
267
|
|
|
260
268
|
# Determine compression config (server-level in Actix)
|
|
261
269
|
# Priority: Django setting > first API with compression config
|
|
@@ -358,25 +366,34 @@ class Command(BaseCommand):
|
|
|
358
366
|
|
|
359
367
|
def import_api(self, dotted_path):
|
|
360
368
|
"""Import a BoltAPI instance from dotted path like 'myapp.api:api'"""
|
|
369
|
+
if ':' not in dotted_path:
|
|
370
|
+
return None
|
|
371
|
+
|
|
372
|
+
module_path, attr_name = dotted_path.split(':', 1)
|
|
373
|
+
|
|
361
374
|
try:
|
|
362
|
-
if ':' not in dotted_path:
|
|
363
|
-
return None
|
|
364
|
-
|
|
365
|
-
module_path, attr_name = dotted_path.split(':', 1)
|
|
366
375
|
module = importlib.import_module(module_path)
|
|
367
|
-
|
|
368
|
-
if
|
|
376
|
+
except ModuleNotFoundError as e:
|
|
377
|
+
# Check if the error is for the target module itself (optional)
|
|
378
|
+
# or for a dependency within the module (fatal error)
|
|
379
|
+
if e.name == module_path or e.name == module_path.split('.')[0]:
|
|
380
|
+
# Target module doesn't exist - this is fine, api.py is optional
|
|
369
381
|
return None
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
382
|
+
else:
|
|
383
|
+
# Module exists but has a missing dependency - let the original error bubble up
|
|
384
|
+
# This preserves the full traceback for debugging
|
|
385
|
+
raise
|
|
386
|
+
|
|
387
|
+
# If attribute doesn't exist, return None (not an error, just doesn't have that attr)
|
|
388
|
+
if not hasattr(module, attr_name):
|
|
389
|
+
return None
|
|
390
|
+
|
|
391
|
+
api = getattr(module, attr_name)
|
|
392
|
+
|
|
393
|
+
# Verify it's a BoltAPI instance
|
|
394
|
+
if isinstance(api, BoltAPI):
|
|
395
|
+
return api
|
|
396
|
+
|
|
380
397
|
return None
|
|
381
398
|
|
|
382
399
|
def merge_apis(self, apis):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: django-bolt
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.7
|
|
4
4
|
Classifier: Development Status :: 3 - Alpha
|
|
5
5
|
Classifier: Intended Audience :: Developers
|
|
6
6
|
Classifier: License :: OSI Approved :: MIT License
|
|
@@ -25,6 +25,7 @@ Requires-Dist: click>=8.1
|
|
|
25
25
|
Requires-Dist: msgspec>=0.18
|
|
26
26
|
Requires-Dist: multipart>=1.3
|
|
27
27
|
Requires-Dist: pyjwt>=2.10.1
|
|
28
|
+
Requires-Dist: uvloop>=0.22.1 ; sys_platform != 'win32'
|
|
28
29
|
Requires-Dist: pyyaml>=6.0 ; extra == 'yaml'
|
|
29
30
|
Provides-Extra: yaml
|
|
30
31
|
Summary: High-performance API framework for Django with Rust-powered endpoints delivering 60k+ RPS
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
django_bolt-0.2.
|
|
2
|
-
django_bolt-0.2.
|
|
3
|
-
django_bolt-0.2.
|
|
1
|
+
django_bolt-0.2.7.dist-info/METADATA,sha256=_varQS5ZLBLJVCW7vUIZn-DQE9nK5HuAoVmDli3pEQQ,22036
|
|
2
|
+
django_bolt-0.2.7.dist-info/WHEEL,sha256=4EDp_7DiFfWl1yYv5M4wSosAn5L_xgD1dyrQxQxfCx8,95
|
|
3
|
+
django_bolt-0.2.7.dist-info/entry_points.txt,sha256=cUEGAdiOY6BryNhsgOS_50AONPPHajI3yvhqr56ZiaU,51
|
|
4
4
|
django_bolt/__init__.py,sha256=BerkkdUuHfxTJUKTFoXxfjYr6OFCb3MH88NIBEjphm4,3183
|
|
5
|
-
django_bolt/_core.pyd,sha256=
|
|
5
|
+
django_bolt/_core.pyd,sha256=7wP1RQ3TG4ecYpPqOP-cfaHmmuerHq3HVIvxDrR0Y-8,8912384
|
|
6
6
|
django_bolt/_json.py,sha256=oGxi29DHB8UYvbqjtqtrP6gThk7Qonlw333c4_cTr6s,4917
|
|
7
7
|
django_bolt/admin/__init__.py,sha256=BNN1afSvWvt-377rNzZLdNDEvKyMZXkmB_0MhTxAN8k,601
|
|
8
8
|
django_bolt/admin/admin_detection.py,sha256=1yQkLx9rF5DLMjJqbx8n4c82UgS9JEAnUcPdRfFqAXk,5825
|
|
@@ -22,7 +22,7 @@ django_bolt/auth/token.py,sha256=LAkjupXcQDLY8IoTrS9TrSDitK8Pfjef-zb3zUZT-i4,114
|
|
|
22
22
|
django_bolt/binding.py,sha256=UtmwW55RKyBwNxbX5QQ74NF0EF5k5zaMGa5el7mgljg,12860
|
|
23
23
|
django_bolt/bootstrap.py,sha256=zXkVhcDZxluQBWXc_UHK0FfgOfpdgxCg01DmSbSdXos,3007
|
|
24
24
|
django_bolt/cli.py,sha256=0TBGM37cCqKEew_QA26ru7KkR8_6mP5wKXgFhr8GWng,4647
|
|
25
|
-
django_bolt/compression.py,sha256=
|
|
25
|
+
django_bolt/compression.py,sha256=pcCnf34kNW62Y2D_XKU0U1ZbcS8z0cfzK2rDg6DNAuk,2497
|
|
26
26
|
django_bolt/decorators.py,sha256=hvfIZMxZI3S4eo6KYiOiEC-1Z96fSwQxQopLB4jmez0,6656
|
|
27
27
|
django_bolt/dependencies.py,sha256=mX19F2X5nbZ5Rzq9GbdeNBuX7EufftQljuHQlCeqpw0,4441
|
|
28
28
|
django_bolt/error_handlers.py,sha256=uD9_9vnub8FxZCRXgcqOdMic5M8cFD-sPXePdSl9IaY,10032
|
|
@@ -33,7 +33,7 @@ django_bolt/logging/config.py,sha256=SE_7yvYzPVdgvMUAK9yU3Dyn2HJY_EVkajm0aAhgcNw
|
|
|
33
33
|
django_bolt/logging/middleware.py,sha256=_tkVN8cN8BloLv7Ebk-2RKBFkH4ooOTNs_dAxXSa0yU,10057
|
|
34
34
|
django_bolt/management/__init__.py,sha256=f0hFqUIOIxXbeDzGL06KrZqWGSsIGVSVVh3EemtatMY,38
|
|
35
35
|
django_bolt/management/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
36
|
-
django_bolt/management/commands/runbolt.py,sha256=
|
|
36
|
+
django_bolt/management/commands/runbolt.py,sha256=sLTUuaOTZhYq7LB4FYTRmxuGf8RGhKlPiA6LAQtvjsI,19062
|
|
37
37
|
django_bolt/middleware/__init__.py,sha256=C6e6vdSLqe4brMrKR4TueroD4f_OPsnoZZDlxkbyjbw,608
|
|
38
38
|
django_bolt/middleware/compiler.py,sha256=Knxh3XouU70ymIskDB-JWn1TcHSMPQvUBXtTPHEJJRY,4766
|
|
39
39
|
django_bolt/middleware/middleware.py,sha256=Qdr16OM15oOS1OYNnxFY3hJ0un9E8VaVwht-A8Qcuws,8113
|
|
@@ -89,4 +89,4 @@ django_bolt/testing/helpers.py,sha256=hq2HD1IEwHuW8tMgZO9ZW6BFdcE_JQXaV8sZc58LBD
|
|
|
89
89
|
django_bolt/types.py,sha256=sk8huP2mArTr5A7FmTVmIke5z0oR-SW0OmzzRfrRlxQ,7982
|
|
90
90
|
django_bolt/typing.py,sha256=sGlFUUXY8EJbYWCgARgNGLZPu7SaxxohZaSx1SRLYaE,8686
|
|
91
91
|
django_bolt/views.py,sha256=KewSpL6g-zZxXnEkwun6hueX3S_Eji-d2dawzoqe-GM,41715
|
|
92
|
-
django_bolt-0.2.
|
|
92
|
+
django_bolt-0.2.7.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|