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 CHANGED
Binary file
@@ -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
- Inspired by Litestar's compression config.
5
+ Compression levels are handled automatically by Actix Web with optimized defaults.
6
6
  """
7
- from typing import Optional, Literal
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
- If the value is "gzip", "brotli", or "zstd", built-in compression is used.
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
- # Aggressive brotli compression
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 (maximum compression)
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
- # Fast zstd compression
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 backlog
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 not hasattr(module, attr_name):
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
- api = getattr(module, attr_name)
372
-
373
- # Verify it's a BoltAPI instance
374
- if isinstance(api, BoltAPI):
375
- return api
376
-
377
- except (ImportError, AttributeError, ValueError):
378
- pass
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.5
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.5.dist-info/METADATA,sha256=tBuV9WKfEKkPN5cAE_zyMNl3zBBWPITz5IR-KwCfWtA,21980
2
- django_bolt-0.2.5.dist-info/WHEEL,sha256=4EDp_7DiFfWl1yYv5M4wSosAn5L_xgD1dyrQxQxfCx8,95
3
- django_bolt-0.2.5.dist-info/entry_points.txt,sha256=cUEGAdiOY6BryNhsgOS_50AONPPHajI3yvhqr56ZiaU,51
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=8obPhzwlAWjui8CW2z4l8kdNR-49fJJhxsPIA9aTj2k,8956416
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=8ioDa2j0TG_mna-Jh34-e6WjCeY0GSKwRPHMn8en8OQ,4025
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=02Iricges7kgbDEAnILcVuGYgbxeuuExE42OxL9J4TA,18227
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.5.dist-info/RECORD,,
92
+ django_bolt-0.2.7.dist-info/RECORD,,