Skip to content

Commit 41e5fa8

Browse files
authored
Merge pull request #178 from GetStream/audio-more
Non blocking json enc/dec
2 parents 9bf5f4d + 3aab82d commit 41e5fa8

File tree

4 files changed

+251
-147
lines changed

4 files changed

+251
-147
lines changed

getstream/base.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import json
22
import time
33
import uuid
4+
import asyncio
45
from typing import Any, Dict, Optional, Type, get_origin
56

67
from getstream.models import APIError
@@ -355,6 +356,14 @@ async def _request_async(
355356
) as span:
356357
call_kwargs = dict(kwargs)
357358
call_kwargs.pop("path_params", None)
359+
360+
if call_kwargs.get("json") is not None:
361+
json_body = call_kwargs.pop("json")
362+
json_str = await asyncio.to_thread(json.dumps, json_body)
363+
call_kwargs["content"] = json_str
364+
call_kwargs["headers"] = call_kwargs.get("headers", {})
365+
call_kwargs["headers"]["Content-Type"] = "application/json"
366+
358367
response = await getattr(self.client, method.lower())(
359368
url_path, params=query_params, *args, **call_kwargs
360369
)
@@ -377,7 +386,9 @@ async def _request_async(
377386
status_code=getattr(response, "status_code", None),
378387
)
379388
record_metrics(duration_ms, attributes=metric_attrs)
380-
return self._parse_response(response, data_type or Dict[str, Any])
389+
return await asyncio.to_thread(
390+
self._parse_response, response, data_type or Dict[str, Any]
391+
)
381392

382393
async def patch(
383394
self,

getstream/utils/__init__.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,28 @@ def build_query_param(**kwargs):
126126
return params
127127

128128

129+
async def build_query_param_async(**kwargs):
130+
"""
131+
Async version that offloads CPU-bound JSON serialization to thread pool.
132+
133+
Constructs a dictionary of query parameters from keyword arguments.
134+
135+
This function handles various data types:
136+
- JSON-serializable objects with a `to_json` method will be serialized using that method.
137+
- Booleans are converted to lowercase strings.
138+
- Lists are converted to comma-separated strings with URL-encoded values.
139+
- Other types (strings, integers, dictionaries) are handled appropriately.
140+
141+
Args:
142+
**kwargs: Arbitrary keyword arguments representing potential query parameters.
143+
144+
Returns:
145+
dict: A dictionary where keys are parameter names and values are URL-ready strings.
146+
"""
147+
# Use sync version in thread pool to avoid blocking event loop
148+
return await asyncio.to_thread(build_query_param, **kwargs)
149+
150+
129151
def build_body_dict(**kwargs):
130152
"""
131153
Constructs a dictionary for the body of a request, handling nested structures.
@@ -153,6 +175,24 @@ def handle_value(value):
153175
return data
154176

155177

178+
async def build_body_dict_async(**kwargs):
179+
"""
180+
Async version that offloads CPU-bound to_dict() calls to thread pool.
181+
182+
Constructs a dictionary for the body of a request, handling nested structures.
183+
If an object has a `to_dict` method, it calls this method to serialize the object.
184+
It handles nested dictionaries and lists recursively.
185+
186+
Args:
187+
**kwargs: Keyword arguments representing keys and values to be included in the body dictionary.
188+
189+
Returns:
190+
dict: A dictionary with keys corresponding to kwargs keys and values processed, potentially recursively.
191+
"""
192+
# Use sync version in thread pool to avoid blocking event loop
193+
return await asyncio.to_thread(build_body_dict, **kwargs)
194+
195+
156196
def configure_logging(level=None, handler=None, format=None):
157197
"""
158198
Configure logging for the Stream library.
@@ -232,7 +272,9 @@ async def sync_to_async(func, *args, **kwargs):
232272
"encode_datetime",
233273
"datetime_from_unix_ns",
234274
"build_query_param",
275+
"build_query_param_async",
235276
"build_body_dict",
277+
"build_body_dict_async",
236278
"validate_and_clean_url",
237279
"configure_logging",
238280
"UTC",

0 commit comments

Comments
 (0)