kurrentdbclient 0.3__py3-none-any.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.
Files changed (49) hide show
  1. kurrentdbclient/__init__.py +49 -0
  2. kurrentdbclient/asyncio_client.py +1662 -0
  3. kurrentdbclient/client.py +1914 -0
  4. kurrentdbclient/common.py +535 -0
  5. kurrentdbclient/connection.py +107 -0
  6. kurrentdbclient/connection_spec.py +371 -0
  7. kurrentdbclient/events.py +141 -0
  8. kurrentdbclient/exceptions.py +239 -0
  9. kurrentdbclient/gossip.py +104 -0
  10. kurrentdbclient/instrumentation/__init__.py +0 -0
  11. kurrentdbclient/instrumentation/opentelemetry/__init__.py +185 -0
  12. kurrentdbclient/instrumentation/opentelemetry/attributes.py +20 -0
  13. kurrentdbclient/instrumentation/opentelemetry/grpc.py +165 -0
  14. kurrentdbclient/instrumentation/opentelemetry/package.py +2 -0
  15. kurrentdbclient/instrumentation/opentelemetry/spanners.py +1097 -0
  16. kurrentdbclient/instrumentation/opentelemetry/utils.py +199 -0
  17. kurrentdbclient/instrumentation/opentelemetry/version.py +2 -0
  18. kurrentdbclient/persistent.py +1982 -0
  19. kurrentdbclient/projections.py +735 -0
  20. kurrentdbclient/protos/Grpc/cluster_pb2.py +92 -0
  21. kurrentdbclient/protos/Grpc/cluster_pb2.pyi +765 -0
  22. kurrentdbclient/protos/Grpc/cluster_pb2_grpc.py +514 -0
  23. kurrentdbclient/protos/Grpc/code_pb2.py +37 -0
  24. kurrentdbclient/protos/Grpc/code_pb2.pyi +357 -0
  25. kurrentdbclient/protos/Grpc/code_pb2_grpc.py +24 -0
  26. kurrentdbclient/protos/Grpc/gossip_pb2.py +46 -0
  27. kurrentdbclient/protos/Grpc/gossip_pb2.pyi +126 -0
  28. kurrentdbclient/protos/Grpc/gossip_pb2_grpc.py +98 -0
  29. kurrentdbclient/protos/Grpc/persistent_pb2.py +140 -0
  30. kurrentdbclient/protos/Grpc/persistent_pb2.pyi +1135 -0
  31. kurrentdbclient/protos/Grpc/persistent_pb2_grpc.py +399 -0
  32. kurrentdbclient/protos/Grpc/projections_pb2.py +99 -0
  33. kurrentdbclient/protos/Grpc/projections_pb2.pyi +558 -0
  34. kurrentdbclient/protos/Grpc/projections_pb2_grpc.py +485 -0
  35. kurrentdbclient/protos/Grpc/shared_pb2.py +62 -0
  36. kurrentdbclient/protos/Grpc/shared_pb2.pyi +218 -0
  37. kurrentdbclient/protos/Grpc/shared_pb2_grpc.py +24 -0
  38. kurrentdbclient/protos/Grpc/status_pb2.py +39 -0
  39. kurrentdbclient/protos/Grpc/status_pb2.pyi +67 -0
  40. kurrentdbclient/protos/Grpc/status_pb2_grpc.py +24 -0
  41. kurrentdbclient/protos/Grpc/streams_pb2.py +132 -0
  42. kurrentdbclient/protos/Grpc/streams_pb2.pyi +1038 -0
  43. kurrentdbclient/protos/Grpc/streams_pb2_grpc.py +269 -0
  44. kurrentdbclient/py.typed +0 -0
  45. kurrentdbclient/streams.py +1400 -0
  46. kurrentdbclient-0.3.dist-info/LICENSE +29 -0
  47. kurrentdbclient-0.3.dist-info/METADATA +3769 -0
  48. kurrentdbclient-0.3.dist-info/RECORD +49 -0
  49. kurrentdbclient-0.3.dist-info/WHEEL +4 -0
@@ -0,0 +1,199 @@
1
+ # -*- coding: utf-8 -*-
2
+ from __future__ import annotations
3
+
4
+ import inspect
5
+ import re
6
+ import traceback
7
+ from contextlib import contextmanager
8
+ from typing import (
9
+ Any,
10
+ Callable,
11
+ Coroutine,
12
+ Iterator,
13
+ MutableMapping,
14
+ Optional,
15
+ Protocol,
16
+ Type,
17
+ TypeVar,
18
+ Union,
19
+ cast,
20
+ )
21
+
22
+ import wrapt
23
+ from opentelemetry.context import Context
24
+ from opentelemetry.trace import Span, SpanKind, Status, StatusCode, Tracer
25
+ from opentelemetry.util.types import AttributeValue
26
+ from typing_extensions import Concatenate, ParamSpec
27
+
28
+ from kurrentdbclient.instrumentation.opentelemetry.attributes import Attributes
29
+
30
+ # Define type variables and type aliases for spanner functions.
31
+ T = TypeVar("T")
32
+ P = ParamSpec("P")
33
+ R = TypeVar("R")
34
+ BoundFunc = Callable[P, R]
35
+ SpannerResponse = Iterator[R]
36
+ SpannerFunc = Callable[Concatenate[Tracer, T, BoundFunc[P, R], P], SpannerResponse[R]]
37
+
38
+
39
+ # Define function type for wrapt-style wrapper functions.
40
+ T_contra = TypeVar("T_contra", contravariant=True)
41
+
42
+
43
+ class WraptWrapperFunc(Protocol[T_contra, P, R]):
44
+ def __call__(
45
+ self,
46
+ original: BoundFunc[P, R],
47
+ instance: T_contra,
48
+ args: P.args,
49
+ kwargs: P.kwargs,
50
+ ) -> R:
51
+ pass # pragma: no cover
52
+
53
+
54
+ # Define type alias for unbound object class methods.
55
+ UnboundFunc = Callable[Concatenate[T, P], R]
56
+
57
+
58
+ # Define type-safe function to apply an instrumenting
59
+ # spanner function to the method of an object class.
60
+ def apply_spanner(
61
+ patched_class: Type[T],
62
+ spanned_func: UnboundFunc[T, P, R],
63
+ spanner_func: SpannerFunc[T, P, R],
64
+ tracer: Tracer,
65
+ ) -> UnboundFunc[T, P, R]:
66
+
67
+ if inspect.iscoroutinefunction(spanned_func):
68
+
69
+ # Make a context manager for the spanner function.
70
+ async_spanner_func = cast(
71
+ SpannerFunc[T, P, Coroutine[Any, Any, R]], spanner_func
72
+ )
73
+ async_spanner = contextmanager(async_spanner_func)
74
+
75
+ # Define wrapt-style instrumentation wrapper.
76
+ async def async_instrumentation_wrapper(
77
+ original: BoundFunc[P, Coroutine[Any, Any, R]],
78
+ instance: T,
79
+ args: P.kwargs,
80
+ kwargs: P.args,
81
+ ) -> R:
82
+ # Use the spanner function to execute the spanned function.
83
+ with async_spanner(tracer, instance, original, *args, **kwargs) as result:
84
+ return await result
85
+
86
+ # Replace spanned function with instrumentation wrapper.
87
+ async_spanned_func = cast(
88
+ UnboundFunc[T, P, Coroutine[Any, Any, R]], spanned_func
89
+ )
90
+ _patch_class(patched_class, async_spanned_func, async_instrumentation_wrapper)
91
+
92
+ else:
93
+
94
+ # Make a context manager for the spanner function.
95
+ spanner = contextmanager(spanner_func)
96
+
97
+ # Define wrapt-style instrumentation wrapper.
98
+ def instrumentation_wrapper(
99
+ original: BoundFunc[P, R],
100
+ instance: T,
101
+ args: P.args,
102
+ kwargs: P.kwargs,
103
+ ) -> R:
104
+ # Use the spanner function to execute the spanned function.
105
+ with spanner(tracer, instance, original, *args, **kwargs) as result:
106
+ return result
107
+
108
+ # Replace spanned function with instrumentation wrapper.
109
+ _patch_class(patched_class, spanned_func, instrumentation_wrapper)
110
+
111
+ # Satisfy the return type (which brings together the typing for mypy).
112
+ return spanned_func
113
+
114
+
115
+ def _patch_class(
116
+ patched_class: Type[T],
117
+ spanned_func: UnboundFunc[T, P, R],
118
+ instrumentation_wrapper_func: WraptWrapperFunc[T, P, R],
119
+ ) -> UnboundFunc[T, P, R]:
120
+
121
+ # Wrap spanned function with instrumentation wrapper function.
122
+ wrapt.wrap_function_wrapper(
123
+ patched_class,
124
+ spanned_func.__name__,
125
+ instrumentation_wrapper_func,
126
+ )
127
+
128
+ # Satisfy the return type (which brings together the typing for mypy).
129
+ return spanned_func
130
+
131
+
132
+ # Define type variables for overloaded spanner functions.
133
+ AsyncSpannerResponse = SpannerResponse[Coroutine[Any, Any, R]]
134
+ S = TypeVar("S")
135
+ OverloadedSpannerResponse = Union[SpannerResponse[R], AsyncSpannerResponse[S]]
136
+
137
+
138
+ @contextmanager
139
+ def _start_span(
140
+ tracer: Tracer,
141
+ span_name: str,
142
+ span_kind: SpanKind = SpanKind.CLIENT,
143
+ context: Optional[Context] = None,
144
+ end_on_exit: bool = True,
145
+ ) -> Iterator[Span]:
146
+ with tracer.start_as_current_span(
147
+ name=span_name,
148
+ kind=span_kind,
149
+ record_exception=False,
150
+ set_status_on_exception=False,
151
+ context=context,
152
+ end_on_exit=end_on_exit,
153
+ ) as span:
154
+ yield span
155
+
156
+
157
+ def _set_span_ok(span: Span) -> None:
158
+ span.set_status(StatusCode.OK)
159
+
160
+
161
+ def _set_span_error(span: Span, error: Exception) -> None:
162
+ # Set span status.
163
+ exc_type = type(error)
164
+ span.set_status(
165
+ Status(
166
+ status_code=StatusCode.ERROR,
167
+ description=f"{exc_type.__name__}: {error}",
168
+ )
169
+ )
170
+ # Log an event for the error.
171
+ exception_type = (
172
+ f"{exc_type.__module__}.{exc_type.__qualname__}"
173
+ if exc_type.__module__ and exc_type.__module__ != "builtins"
174
+ else exc_type.__qualname__
175
+ )
176
+ exception_message = str(error)
177
+ stack = ["Traceback (most recent call last):\n"]
178
+ # stack += traceback.format_stack()
179
+ stack += traceback.format_exception(exc_type, error, error.__traceback__)[1:]
180
+ exception_stacktrace = "".join([line for line in stack if _stack_include(line)])
181
+ exception_escaped = str(True)
182
+ # Gather attributes.
183
+ attributes: MutableMapping[str, AttributeValue] = {
184
+ Attributes.EXCEPTION_TYPE: exception_type,
185
+ Attributes.EXCEPTION_MESSAGE: exception_message,
186
+ Attributes.EXCEPTION_STACKTRACE: exception_stacktrace,
187
+ Attributes.EXCEPTION_ESCAPED: exception_escaped,
188
+ }
189
+ span.add_event(name="exception", attributes=attributes, timestamp=None)
190
+
191
+
192
+ _stack_exclude_patterns = [
193
+ "opentelemetry",
194
+ ]
195
+ _stack_exclude_regex = re.compile(".*(" + "|".join(_stack_exclude_patterns) + ").*")
196
+
197
+
198
+ def _stack_include(line: str) -> bool:
199
+ return _stack_exclude_regex.match(line) is None
@@ -0,0 +1,2 @@
1
+ # -*- coding: utf-8 -*-
2
+ __version__ = "1.1"