Skip to content

Commit e2132c0

Browse files
authored
Merge pull request #120 from dapper91/dev
- initialize dispatcher middleware stack in constructor. - generic context type added.
2 parents 1f490d3 + 7328073 commit e2132c0

14 files changed

+131
-108
lines changed

CHANGELOG.rst

+7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
Changelog
22
=========
33

4+
1.13.0 (2025-02-15)
5+
------------------
6+
7+
- initialize dispatcher middleware stack in constructor.
8+
- generic context type added.
9+
10+
411
1.12.2 (2025-01-15)
512
------------------
613

pjrpc/__about__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
__description__ = 'Extensible JSON-RPC library'
33
__url__ = 'https://github.com/dapper91/pjrpc'
44

5-
__version__ = '1.12.2'
5+
__version__ = '1.13.0'
66

77
__author__ = 'Dmitry Pershin'
88
__email__ = '[email protected]'

pjrpc/client/client.py

+39-35
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,15 @@ def wrapped(*args: Any, **kwargs: Any) -> 'BaseBatch.BaseProxy':
4040
return wrapped
4141

4242
@abc.abstractmethod
43-
def __call__(self, _trace_ctx: SimpleNamespace = SimpleNamespace()) -> Union[Awaitable[Any], Any]:
43+
def __call__(self, _trace_ctx: Optional[SimpleNamespace] = None) -> Union[Awaitable[Any], Any]:
4444
"""
4545
Makes an RPC call.
4646
4747
:param _trace_ctx: tracers request context
4848
"""
4949

5050
@abc.abstractmethod
51-
def call(self, _trace_ctx: SimpleNamespace = SimpleNamespace()) -> Union[Awaitable[Any], Any]:
51+
def call(self, _trace_ctx: Optional[SimpleNamespace] = None) -> Union[Awaitable[Any], Any]:
5252
"""
5353
Makes an RPC call.
5454
@@ -97,7 +97,7 @@ def __call__(self, method: str, *args: Any, **kwargs: Any) -> 'BaseBatch':
9797
return self.add(method, *args, **kwargs)
9898

9999
@abc.abstractmethod
100-
def call(self, _trace_ctx: SimpleNamespace = SimpleNamespace()) -> Union[Awaitable[Any], Any]:
100+
def call(self, _trace_ctx: Optional[SimpleNamespace] = None) -> Union[Awaitable[Any], Any]:
101101
"""
102102
Makes a JSON-RPC request.
103103
@@ -107,7 +107,7 @@ def call(self, _trace_ctx: SimpleNamespace = SimpleNamespace()) -> Union[Awaitab
107107

108108
@abc.abstractmethod
109109
def send(
110-
self, request: BatchRequest, _trace_ctx: SimpleNamespace = SimpleNamespace(), **kwargs: Any,
110+
self, request: BatchRequest, _trace_ctx: Optional[SimpleNamespace] = None, **kwargs: Any,
111111
) -> Union[Awaitable[Optional[BatchResponse]], Optional[BatchResponse]]:
112112
"""
113113
Sends a JSON-RPC batch request.
@@ -183,10 +183,10 @@ class Proxy(BaseBatch.BaseProxy):
183183
def __init__(self, batch: 'Batch'):
184184
super().__init__(batch)
185185

186-
def __call__(self, _trace_ctx: SimpleNamespace = SimpleNamespace()) -> Any:
186+
def __call__(self, _trace_ctx: Optional[SimpleNamespace] = None) -> Any:
187187
return self.call(_trace_ctx)
188188

189-
def call(self, _trace_ctx: SimpleNamespace = SimpleNamespace()) -> Any:
189+
def call(self, _trace_ctx: Optional[SimpleNamespace] = None) -> Any:
190190
return self._batch.call(_trace_ctx)
191191

192192
@property
@@ -196,13 +196,13 @@ def proxy(self) -> 'Proxy':
196196
def __init__(self, client: 'AbstractClient'):
197197
super().__init__(client)
198198

199-
def call(self, _trace_ctx: SimpleNamespace = SimpleNamespace()) -> Optional[Any]:
200-
response = self.send(self._requests)
199+
def call(self, _trace_ctx: Optional[SimpleNamespace] = None) -> Optional[Any]:
200+
response = self.send(self._requests, _trace_ctx=_trace_ctx)
201201

202202
return response.result if response is not None else None
203203

204204
def send(
205-
self, request: BatchRequest, _trace_ctx: SimpleNamespace = SimpleNamespace(), **kwargs: Any,
205+
self, request: BatchRequest, _trace_ctx: Optional[SimpleNamespace] = None, **kwargs: Any,
206206
) -> Optional[BatchResponse]:
207207
return cast(
208208
Optional[BatchResponse], self._client._send(
@@ -225,10 +225,10 @@ class Proxy(BaseBatch.BaseProxy):
225225
def __init__(self, batch: 'AsyncBatch'):
226226
super().__init__(batch)
227227

228-
async def __call__(self, _trace_ctx: SimpleNamespace = SimpleNamespace()) -> Any:
228+
async def __call__(self, _trace_ctx: Optional[SimpleNamespace] = None) -> Any:
229229
return await self.call(_trace_ctx)
230230

231-
async def call(self, _trace_ctx: SimpleNamespace = SimpleNamespace()) -> Any:
231+
async def call(self, _trace_ctx: Optional[SimpleNamespace] = None) -> Any:
232232
return await self._batch.call(_trace_ctx)
233233

234234
@property
@@ -238,13 +238,13 @@ def proxy(self) -> 'Proxy':
238238
def __init__(self, client: 'AbstractAsyncClient'):
239239
super().__init__(client)
240240

241-
async def call(self, _trace_ctx: SimpleNamespace = SimpleNamespace()) -> Optional[Any]:
241+
async def call(self, _trace_ctx: Optional[SimpleNamespace] = None) -> Optional[Any]:
242242
response = await self.send(self._requests, _trace_ctx=_trace_ctx)
243243

244244
return response.result if response is not None else None
245245

246246
async def send(
247-
self, request: BatchRequest, _trace_ctx: SimpleNamespace = SimpleNamespace(), **kwargs: Any,
247+
self, request: BatchRequest, _trace_ctx: Optional[SimpleNamespace] = None, **kwargs: Any,
248248
) -> Optional[BatchResponse]:
249249
return await cast(
250250
Awaitable[Optional[BatchResponse]], self._client._send(
@@ -304,7 +304,7 @@ def __init__(
304304
json_decoder: Optional[json.JSONDecoder] = None,
305305
strict: bool = True,
306306
request_args: Optional[Dict[str, Any]] = None,
307-
tracers: Iterable[Tracer] = (),
307+
tracers: Iterable[Tracer[Any]] = (),
308308
retry_strategy: Optional[retry.RetryStrategy] = None,
309309
):
310310
self.request_class = request_class
@@ -326,7 +326,7 @@ def __call__(
326326
self,
327327
method: str,
328328
*args: Any,
329-
_trace_ctx: SimpleNamespace = SimpleNamespace(),
329+
_trace_ctx: Optional[SimpleNamespace] = None,
330330
**kwargs: Any,
331331
) -> Union[Awaitable[Any], Any]:
332332
"""
@@ -339,7 +339,7 @@ def __call__(
339339
:returns: response result
340340
"""
341341

342-
return self.call(method, *args, **kwargs)
342+
return self.call(method, *args, _trace_ctx=_trace_ctx, **kwargs)
343343

344344
@property
345345
def proxy(self) -> 'Proxy':
@@ -359,7 +359,7 @@ def _send(
359359
request: AbstractRequest,
360360
response_class: Type[AbstractResponse],
361361
validator: Callable[..., None],
362-
_trace_ctx: SimpleNamespace = SimpleNamespace(),
362+
_trace_ctx: Optional[SimpleNamespace] = None,
363363
**kwargs: Any,
364364
) -> Union[Awaitable[Optional[AbstractResponse]], Optional[AbstractResponse]]:
365365
pass
@@ -407,7 +407,7 @@ def notify(
407407
self,
408408
method: str,
409409
*args: Any,
410-
_trace_ctx: SimpleNamespace = SimpleNamespace(),
410+
_trace_ctx: Optional[SimpleNamespace] = None,
411411
**kwargs: Any,
412412
) -> Optional[Response]:
413413
"""
@@ -429,7 +429,7 @@ def notify(
429429
return self.send(request, _trace_ctx=_trace_ctx)
430430

431431
def call(
432-
self, method: str, *args: Any, _trace_ctx: SimpleNamespace = SimpleNamespace(), **kwargs: Any,
432+
self, method: str, *args: Any, _trace_ctx: Optional[SimpleNamespace] = None, **kwargs: Any,
433433
) -> Any:
434434
"""
435435
Makes JSON-RPC call.
@@ -456,7 +456,7 @@ def call(
456456
def send(
457457
self,
458458
request: Request,
459-
_trace_ctx: SimpleNamespace = SimpleNamespace(),
459+
_trace_ctx: Optional[SimpleNamespace] = None,
460460
_retry_strategy: MaybeSet[retry.RetryStrategy] = UNSET,
461461
**kwargs: Any,
462462
) -> Optional[Response]:
@@ -486,25 +486,27 @@ def traced(method: Callable[..., Any]) -> Callable[..., Any]:
486486
def wrapper(
487487
self: 'AbstractClient',
488488
request: AbstractRequest,
489-
_trace_ctx: SimpleNamespace,
489+
_trace_ctx: Optional[SimpleNamespace] = None,
490490
**kwargs: Any,
491491
) -> Optional[AbstractResponse]:
492492
"""
493493
Adds tracing logic to the method.
494494
"""
495495

496+
trace_ctx = _trace_ctx or SimpleNamespace()
497+
496498
for tracer in self._tracers:
497-
tracer.on_request_begin(_trace_ctx, request)
499+
tracer.on_request_begin(trace_ctx, request)
498500

499501
try:
500-
response = method(self, request, _trace_ctx=_trace_ctx, **kwargs)
502+
response = method(self, request, _trace_ctx=trace_ctx, **kwargs)
501503
except BaseException as e:
502504
for tracer in self._tracers:
503-
tracer.on_error(_trace_ctx, request, e)
505+
tracer.on_error(trace_ctx, request, e)
504506
raise
505507

506508
for tracer in self._tracers:
507-
tracer.on_request_end(_trace_ctx, request, response)
509+
tracer.on_request_end(trace_ctx, request, response)
508510

509511
return response
510512

@@ -541,7 +543,7 @@ def _send(
541543
request: AbstractRequest,
542544
response_class: Type[AbstractResponse],
543545
validator: Callable[..., None],
544-
_trace_ctx: SimpleNamespace = SimpleNamespace(),
546+
_trace_ctx: Optional[SimpleNamespace] = None,
545547
**kwargs: Any,
546548
) -> Optional[AbstractResponse]:
547549
kwargs = {**self._request_args, **kwargs}
@@ -588,7 +590,7 @@ async def _request(self, request_text: str, is_notification: bool = False, **kwa
588590
async def send(
589591
self,
590592
request: Request,
591-
_trace_ctx: SimpleNamespace = SimpleNamespace(),
593+
_trace_ctx: Optional[SimpleNamespace] = None,
592594
_retry_strategy: MaybeSet[retry.RetryStrategy] = UNSET,
593595
**kwargs: Any,
594596
) -> Optional[Response]:
@@ -618,25 +620,27 @@ def traced(method: Callable[..., Any]) -> Callable[..., Any]:
618620
async def wrapper(
619621
self: 'AbstractAsyncClient',
620622
request: Request,
621-
_trace_ctx: SimpleNamespace = SimpleNamespace(),
623+
_trace_ctx: Optional[SimpleNamespace] = None,
622624
**kwargs: Any,
623625
) -> Response:
624626
"""
625627
Adds tracing logic to the method.
626628
"""
627629

630+
trace_ctx = _trace_ctx or SimpleNamespace()
631+
628632
for tracer in self._tracers:
629-
tracer.on_request_begin(_trace_ctx, request)
633+
tracer.on_request_begin(trace_ctx, request)
630634

631635
try:
632-
response = await method(self, request, _trace_ctx=_trace_ctx, **kwargs)
636+
response = await method(self, request, _trace_ctx=trace_ctx, **kwargs)
633637
except BaseException as e:
634638
for tracer in self._tracers:
635-
tracer.on_error(_trace_ctx, request, e)
639+
tracer.on_error(trace_ctx, request, e)
636640
raise
637641

638642
for tracer in self._tracers:
639-
tracer.on_request_end(_trace_ctx, request, response)
643+
tracer.on_request_end(trace_ctx, request, response)
640644

641645
return response
642646

@@ -673,7 +677,7 @@ async def _send(
673677
request: AbstractRequest,
674678
response_class: Type[AbstractResponse],
675679
validator: Callable[..., None],
676-
_trace_ctx: SimpleNamespace = SimpleNamespace(),
680+
_trace_ctx: Optional[SimpleNamespace] = None,
677681
**kwargs: Any,
678682
) -> Optional[AbstractResponse]:
679683
kwargs = {**self._request_args, **kwargs}
@@ -697,7 +701,7 @@ async def notify(
697701
self,
698702
method: str,
699703
*args: Any,
700-
_trace_ctx: SimpleNamespace = SimpleNamespace(),
704+
_trace_ctx: Optional[SimpleNamespace] = None,
701705
**kwargs: Any,
702706
) -> Optional[Response]:
703707
"""
@@ -719,7 +723,7 @@ async def notify(
719723
return await self.send(request, _trace_ctx=_trace_ctx)
720724

721725
async def call(
722-
self, method: str, *args: Any, _trace_ctx: SimpleNamespace = SimpleNamespace(), **kwargs: Any,
726+
self, method: str, *args: Any, _trace_ctx: Optional[SimpleNamespace] = None, **kwargs: Any,
723727
) -> Any:
724728
"""
725729
Makes JSON-RPC call.

pjrpc/client/tracer.py

+11-10
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
11
import logging
2-
from types import SimpleNamespace
3-
from typing import Optional
2+
from typing import Generic, Optional, TypeVar
43

54
from pjrpc import AbstractRequest, AbstractResponse
65

76
client_logger = logging.getLogger(__package__)
87

8+
ContextType = TypeVar('ContextType')
99

10-
class Tracer:
10+
11+
class Tracer(Generic[ContextType]):
1112
"""
1213
JSON-RPC client tracer.
1314
"""
1415

15-
def on_request_begin(self, trace_context: SimpleNamespace, request: AbstractRequest) -> None:
16+
def on_request_begin(self, trace_context: ContextType, request: AbstractRequest) -> None:
1617
"""
1718
Handler called before JSON-RPC request begins.
1819
@@ -21,7 +22,7 @@ def on_request_begin(self, trace_context: SimpleNamespace, request: AbstractRequ
2122
"""
2223

2324
def on_request_end(
24-
self, trace_context: SimpleNamespace, request: AbstractRequest, response: Optional[AbstractResponse],
25+
self, trace_context: ContextType, request: AbstractRequest, response: Optional[AbstractResponse],
2526
) -> None:
2627
"""
2728
Handler called after JSON-RPC request ends.
@@ -32,7 +33,7 @@ def on_request_end(
3233
"""
3334

3435
def on_error(
35-
self, trace_context: SimpleNamespace, request: AbstractRequest, error: BaseException,
36+
self, trace_context: ContextType, request: AbstractRequest, error: BaseException,
3637
) -> None:
3738
"""
3839
Handler called when JSON-RPC request failed.
@@ -43,7 +44,7 @@ def on_error(
4344
"""
4445

4546

46-
class LoggingTracer(Tracer):
47+
class LoggingTracer(Tracer[ContextType], Generic[ContextType]):
4748
"""
4849
JSON-RPC client logging tracer.
4950
"""
@@ -52,15 +53,15 @@ def __init__(self, logger: logging.Logger = client_logger, level: int = logging.
5253
self._logger = logger
5354
self._level = level
5455

55-
def on_request_begin(self, trace_context: SimpleNamespace, request: AbstractRequest) -> None:
56+
def on_request_begin(self, trace_context: ContextType, request: AbstractRequest) -> None:
5657
self._logger.log(self._level, "sending request: %r", request)
5758

5859
def on_request_end(
59-
self, trace_context: SimpleNamespace, request: AbstractRequest, response: Optional[AbstractResponse],
60+
self, trace_context: ContextType, request: AbstractRequest, response: Optional[AbstractResponse],
6061
) -> None:
6162
self._logger.log(self._level, "received response: %r", response)
6263

6364
def on_error(
64-
self, trace_context: SimpleNamespace, request: AbstractRequest, error: BaseException,
65+
self, trace_context: ContextType, request: AbstractRequest, error: BaseException,
6566
) -> None:
6667
self._logger.log(self._level, "request '%s' sending error: %r", request, error)

0 commit comments

Comments
 (0)