turboapi 0.5.2__cp313-cp313-macosx_10_12_x86_64.whl → 0.5.21__cp313-cp313-macosx_10_12_x86_64.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.
- turboapi/request_handler.py +23 -6
- turboapi/rust_integration.py +4 -0
- turboapi/turbonet.cpython-313-darwin.so +0 -0
- {turboapi-0.5.2.dist-info → turboapi-0.5.21.dist-info}/METADATA +1 -1
- {turboapi-0.5.2.dist-info → turboapi-0.5.21.dist-info}/RECORD +7 -7
- {turboapi-0.5.2.dist-info → turboapi-0.5.21.dist-info}/WHEEL +0 -0
- {turboapi-0.5.2.dist-info → turboapi-0.5.21.dist-info}/licenses/LICENSE +0 -0
turboapi/request_handler.py
CHANGED
|
@@ -229,9 +229,12 @@ class RequestBodyParser:
|
|
|
229
229
|
"""
|
|
230
230
|
if not body:
|
|
231
231
|
return {}
|
|
232
|
-
|
|
232
|
+
|
|
233
233
|
try:
|
|
234
|
-
|
|
234
|
+
# CRITICAL: Make a defensive copy immediately using bytearray to force real copy
|
|
235
|
+
# Free-threaded Python with Metal/MLX can have concurrent memory access issues
|
|
236
|
+
body_copy = bytes(bytearray(body))
|
|
237
|
+
json_data = json.loads(body_copy.decode('utf-8'))
|
|
235
238
|
except (json.JSONDecodeError, UnicodeDecodeError) as e:
|
|
236
239
|
raise ValueError(f"Invalid JSON body: {e}")
|
|
237
240
|
|
|
@@ -348,9 +351,16 @@ class ResponseHandler:
|
|
|
348
351
|
try:
|
|
349
352
|
import json
|
|
350
353
|
body = json.loads(body.decode('utf-8'))
|
|
351
|
-
except
|
|
352
|
-
#
|
|
353
|
-
|
|
354
|
+
except json.JSONDecodeError:
|
|
355
|
+
# Not JSON, try as plain text
|
|
356
|
+
try:
|
|
357
|
+
body = body.decode('utf-8')
|
|
358
|
+
except UnicodeDecodeError:
|
|
359
|
+
# Binary data (audio, image, etc.) - keep as bytes
|
|
360
|
+
pass
|
|
361
|
+
except UnicodeDecodeError:
|
|
362
|
+
# Binary data (audio, image, etc.) - keep as bytes
|
|
363
|
+
pass
|
|
354
364
|
return body, result.status_code
|
|
355
365
|
|
|
356
366
|
# Handle tuple returns: (content, status_code)
|
|
@@ -394,6 +404,13 @@ class ResponseHandler:
|
|
|
394
404
|
def make_serializable(obj):
|
|
395
405
|
if isinstance(obj, Model):
|
|
396
406
|
return obj.model_dump()
|
|
407
|
+
elif isinstance(obj, bytes):
|
|
408
|
+
# Binary data - try to decode as UTF-8, otherwise base64 encode
|
|
409
|
+
try:
|
|
410
|
+
return obj.decode('utf-8')
|
|
411
|
+
except UnicodeDecodeError:
|
|
412
|
+
import base64
|
|
413
|
+
return base64.b64encode(obj).decode('ascii')
|
|
397
414
|
elif isinstance(obj, dict):
|
|
398
415
|
return {k: make_serializable(v) for k, v in obj.items()}
|
|
399
416
|
elif isinstance(obj, (list, tuple)):
|
|
@@ -491,7 +508,7 @@ def create_enhanced_handler(original_handler, route_definition):
|
|
|
491
508
|
|
|
492
509
|
# Call original async handler and await it
|
|
493
510
|
result = await original_handler(**filtered_kwargs)
|
|
494
|
-
|
|
511
|
+
|
|
495
512
|
# Normalize response
|
|
496
513
|
content, status_code = ResponseHandler.normalize_response(result)
|
|
497
514
|
|
turboapi/rust_integration.py
CHANGED
|
@@ -43,6 +43,10 @@ def classify_handler(handler, route) -> tuple[str, dict[str, str], dict]:
|
|
|
43
43
|
if BaseModel is not None and inspect.isclass(annotation) and issubclass(annotation, BaseModel):
|
|
44
44
|
# Found a model parameter - use fast model path (sync only for now)
|
|
45
45
|
model_info = {"param_name": param_name, "model_class": annotation}
|
|
46
|
+
# For async handlers, model parsing needs the enhanced path
|
|
47
|
+
# since Rust-side model parsing only supports sync handlers
|
|
48
|
+
if is_async:
|
|
49
|
+
needs_body = True
|
|
46
50
|
continue # Don't add to param_types
|
|
47
51
|
except TypeError:
|
|
48
52
|
pass
|
|
Binary file
|
|
@@ -10,20 +10,20 @@ turboapi/main_app.py,sha256=5w6x1DX_XChPCcZf24b4CC8qe24XFyGY3BRuR71qkCM,13411
|
|
|
10
10
|
turboapi/middleware.py,sha256=3G5zhPKiHm07b_xv_dOsO88W1PfO78SGMySJe4d9nb4,10737
|
|
11
11
|
turboapi/models.py,sha256=OzyDTEl97zcXa6DTrsR_hZZjj8Lr9QwsD0BrC74BE5o,4476
|
|
12
12
|
turboapi/openapi.py,sha256=wwS4akekFns-OYQUh7bjKBzRqdg9Z7z5MFo27LlFkEY,7281
|
|
13
|
-
turboapi/request_handler.py,sha256=
|
|
13
|
+
turboapi/request_handler.py,sha256=YHfJFqQJI_mZdczpARprOkpsNnCIojTrlW_vLgTdPQw,24593
|
|
14
14
|
turboapi/responses.py,sha256=wiYkG53NNwXu1RDyRlZFF-8jxx51xL6LOTUj5TG__2c,6052
|
|
15
15
|
turboapi/routing.py,sha256=-39IUSfsMswCLR-zJ6c4Ri0tYd7_UjYnQyioT4a1W_Q,7601
|
|
16
|
-
turboapi/rust_integration.py,sha256=
|
|
16
|
+
turboapi/rust_integration.py,sha256=StR_4PHIzz1Qk9T-MG5veu3qerwKohoXFeOagk6Be6E,15543
|
|
17
17
|
turboapi/security.py,sha256=U2ZQSMWK9a6YzSk5F39TgeZriJ7JtDNZo3RldVPphKI,17493
|
|
18
18
|
turboapi/server_integration.py,sha256=cnyT4Eqrw3lkZjdVkDvN2qMH5yXh68LJhC2w9ccH9Qc,17904
|
|
19
19
|
turboapi/staticfiles.py,sha256=MLSvPeYUQGPEL4_mVQ2z3ItREZxUTEN-awQrNxPAgsM,2861
|
|
20
20
|
turboapi/status.py,sha256=7qVEXVQ3AVFcgEKbmdq6dTypCP275qIbk51hMUQztXA,3049
|
|
21
21
|
turboapi/templating.py,sha256=YlZeesNAuAcqkdUhkE1xGzTY0w_-nhbG5bJWntYe2AM,2087
|
|
22
22
|
turboapi/testclient.py,sha256=TBuRPms8G9MncARfwtvCKvqrtfthraTcy0TkPmweMao,10669
|
|
23
|
-
turboapi/turbonet.cpython-313-darwin.so,sha256=
|
|
23
|
+
turboapi/turbonet.cpython-313-darwin.so,sha256=qaOvLmIwboqv7_subdCl-6q5I38tMZ6VLxRSLo_Ba5Q,5669784
|
|
24
24
|
turboapi/version_check.py,sha256=NmKEt9Qloi5NrGYvVusjFTDhMhZzZfazuXyjcOPO2vc,9357
|
|
25
25
|
turboapi/websockets.py,sha256=7Ao_dKfGWHu2nMU5pm9X20E9P0qnh4lJOykHFmzc5tc,4226
|
|
26
|
-
turboapi-0.5.
|
|
27
|
-
turboapi-0.5.
|
|
28
|
-
turboapi-0.5.
|
|
29
|
-
turboapi-0.5.
|
|
26
|
+
turboapi-0.5.21.dist-info/METADATA,sha256=8q-P0UJmWeRKs9E3YJpaOLNJeZc9OK_elGvCvNjcunM,17556
|
|
27
|
+
turboapi-0.5.21.dist-info/WHEEL,sha256=y-bBezkr9XqWB_KK0tUa5PfJn4Rf73obH4dbo4t0ZEc,107
|
|
28
|
+
turboapi-0.5.21.dist-info/licenses/LICENSE,sha256=09pmQi_FlhCpUCJ8bMQQoax_oOooJS3FKezznBBU8OQ,1068
|
|
29
|
+
turboapi-0.5.21.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|