kurrentdbclient 1.3.2__tar.gz → 1.3.4__tar.gz

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 (63) hide show
  1. {kurrentdbclient-1.3.2 → kurrentdbclient-1.3.4}/PKG-INFO +6 -5
  2. {kurrentdbclient-1.3.2 → kurrentdbclient-1.3.4}/README.md +4 -4
  3. {kurrentdbclient-1.3.2 → kurrentdbclient-1.3.4}/kurrentdbclient/__init__.py +1 -1
  4. {kurrentdbclient-1.3.2 → kurrentdbclient-1.3.4}/kurrentdbclient/client.py +11 -1
  5. {kurrentdbclient-1.3.2 → kurrentdbclient-1.3.4}/kurrentdbclient/common.py +13 -5
  6. {kurrentdbclient-1.3.2 → kurrentdbclient-1.3.4}/kurrentdbclient/instrumentation/opentelemetry/spanners.py +2 -2
  7. {kurrentdbclient-1.3.2 → kurrentdbclient-1.3.4}/kurrentdbclient/persistent.py +2 -9
  8. {kurrentdbclient-1.3.2 → kurrentdbclient-1.3.4}/kurrentdbclient/streams.py +1 -9
  9. {kurrentdbclient-1.3.2 → kurrentdbclient-1.3.4}/pyproject.toml +2 -1
  10. {kurrentdbclient-1.3.2 → kurrentdbclient-1.3.4}/LICENSE +0 -0
  11. {kurrentdbclient-1.3.2 → kurrentdbclient-1.3.4}/kurrentdbclient/asyncio_client.py +0 -0
  12. {kurrentdbclient-1.3.2 → kurrentdbclient-1.3.4}/kurrentdbclient/connection.py +0 -0
  13. {kurrentdbclient-1.3.2 → kurrentdbclient-1.3.4}/kurrentdbclient/connection_spec.py +0 -0
  14. {kurrentdbclient-1.3.2 → kurrentdbclient-1.3.4}/kurrentdbclient/events.py +0 -0
  15. {kurrentdbclient-1.3.2 → kurrentdbclient-1.3.4}/kurrentdbclient/exceptions.py +0 -0
  16. {kurrentdbclient-1.3.2 → kurrentdbclient-1.3.4}/kurrentdbclient/gossip.py +0 -0
  17. {kurrentdbclient-1.3.2 → kurrentdbclient-1.3.4}/kurrentdbclient/instrumentation/__init__.py +0 -0
  18. {kurrentdbclient-1.3.2 → kurrentdbclient-1.3.4}/kurrentdbclient/instrumentation/opentelemetry/__init__.py +0 -0
  19. {kurrentdbclient-1.3.2 → kurrentdbclient-1.3.4}/kurrentdbclient/instrumentation/opentelemetry/attributes.py +0 -0
  20. {kurrentdbclient-1.3.2 → kurrentdbclient-1.3.4}/kurrentdbclient/instrumentation/opentelemetry/grpc.py +0 -0
  21. {kurrentdbclient-1.3.2 → kurrentdbclient-1.3.4}/kurrentdbclient/instrumentation/opentelemetry/package.py +0 -0
  22. {kurrentdbclient-1.3.2 → kurrentdbclient-1.3.4}/kurrentdbclient/instrumentation/opentelemetry/utils.py +0 -0
  23. {kurrentdbclient-1.3.2 → kurrentdbclient-1.3.4}/kurrentdbclient/instrumentation/opentelemetry/version.py +0 -0
  24. {kurrentdbclient-1.3.2 → kurrentdbclient-1.3.4}/kurrentdbclient/projections.py +0 -0
  25. {kurrentdbclient-1.3.2 → kurrentdbclient-1.3.4}/kurrentdbclient/protos/google/rpc/code_pb2.py +0 -0
  26. {kurrentdbclient-1.3.2 → kurrentdbclient-1.3.4}/kurrentdbclient/protos/google/rpc/code_pb2.pyi +0 -0
  27. {kurrentdbclient-1.3.2 → kurrentdbclient-1.3.4}/kurrentdbclient/protos/google/rpc/code_pb2_grpc.py +0 -0
  28. {kurrentdbclient-1.3.2 → kurrentdbclient-1.3.4}/kurrentdbclient/protos/kurrent/rpc/errors_pb2.py +0 -0
  29. {kurrentdbclient-1.3.2 → kurrentdbclient-1.3.4}/kurrentdbclient/protos/kurrent/rpc/errors_pb2.pyi +0 -0
  30. {kurrentdbclient-1.3.2 → kurrentdbclient-1.3.4}/kurrentdbclient/protos/kurrent/rpc/errors_pb2_grpc.py +0 -0
  31. {kurrentdbclient-1.3.2 → kurrentdbclient-1.3.4}/kurrentdbclient/protos/kurrent/rpc/rpc_pb2.py +0 -0
  32. {kurrentdbclient-1.3.2 → kurrentdbclient-1.3.4}/kurrentdbclient/protos/kurrent/rpc/rpc_pb2.pyi +0 -0
  33. {kurrentdbclient-1.3.2 → kurrentdbclient-1.3.4}/kurrentdbclient/protos/kurrent/rpc/rpc_pb2_grpc.py +0 -0
  34. {kurrentdbclient-1.3.2 → kurrentdbclient-1.3.4}/kurrentdbclient/protos/v1/cluster_pb2.py +0 -0
  35. {kurrentdbclient-1.3.2 → kurrentdbclient-1.3.4}/kurrentdbclient/protos/v1/cluster_pb2.pyi +0 -0
  36. {kurrentdbclient-1.3.2 → kurrentdbclient-1.3.4}/kurrentdbclient/protos/v1/cluster_pb2_grpc.py +0 -0
  37. {kurrentdbclient-1.3.2 → kurrentdbclient-1.3.4}/kurrentdbclient/protos/v1/gossip_pb2.py +0 -0
  38. {kurrentdbclient-1.3.2 → kurrentdbclient-1.3.4}/kurrentdbclient/protos/v1/gossip_pb2.pyi +0 -0
  39. {kurrentdbclient-1.3.2 → kurrentdbclient-1.3.4}/kurrentdbclient/protos/v1/gossip_pb2_grpc.py +0 -0
  40. {kurrentdbclient-1.3.2 → kurrentdbclient-1.3.4}/kurrentdbclient/protos/v1/persistent_pb2.py +0 -0
  41. {kurrentdbclient-1.3.2 → kurrentdbclient-1.3.4}/kurrentdbclient/protos/v1/persistent_pb2.pyi +0 -0
  42. {kurrentdbclient-1.3.2 → kurrentdbclient-1.3.4}/kurrentdbclient/protos/v1/persistent_pb2_grpc.py +0 -0
  43. {kurrentdbclient-1.3.2 → kurrentdbclient-1.3.4}/kurrentdbclient/protos/v1/projections_pb2.py +0 -0
  44. {kurrentdbclient-1.3.2 → kurrentdbclient-1.3.4}/kurrentdbclient/protos/v1/projections_pb2.pyi +0 -0
  45. {kurrentdbclient-1.3.2 → kurrentdbclient-1.3.4}/kurrentdbclient/protos/v1/projections_pb2_grpc.py +0 -0
  46. {kurrentdbclient-1.3.2 → kurrentdbclient-1.3.4}/kurrentdbclient/protos/v1/shared_pb2.py +0 -0
  47. {kurrentdbclient-1.3.2 → kurrentdbclient-1.3.4}/kurrentdbclient/protos/v1/shared_pb2.pyi +0 -0
  48. {kurrentdbclient-1.3.2 → kurrentdbclient-1.3.4}/kurrentdbclient/protos/v1/shared_pb2_grpc.py +0 -0
  49. {kurrentdbclient-1.3.2 → kurrentdbclient-1.3.4}/kurrentdbclient/protos/v1/status_pb2.py +0 -0
  50. {kurrentdbclient-1.3.2 → kurrentdbclient-1.3.4}/kurrentdbclient/protos/v1/status_pb2.pyi +0 -0
  51. {kurrentdbclient-1.3.2 → kurrentdbclient-1.3.4}/kurrentdbclient/protos/v1/status_pb2_grpc.py +0 -0
  52. {kurrentdbclient-1.3.2 → kurrentdbclient-1.3.4}/kurrentdbclient/protos/v1/streams_pb2.py +0 -0
  53. {kurrentdbclient-1.3.2 → kurrentdbclient-1.3.4}/kurrentdbclient/protos/v1/streams_pb2.pyi +0 -0
  54. {kurrentdbclient-1.3.2 → kurrentdbclient-1.3.4}/kurrentdbclient/protos/v1/streams_pb2_grpc.py +0 -0
  55. {kurrentdbclient-1.3.2 → kurrentdbclient-1.3.4}/kurrentdbclient/protos/v2/streams/errors_pb2.py +0 -0
  56. {kurrentdbclient-1.3.2 → kurrentdbclient-1.3.4}/kurrentdbclient/protos/v2/streams/errors_pb2.pyi +0 -0
  57. {kurrentdbclient-1.3.2 → kurrentdbclient-1.3.4}/kurrentdbclient/protos/v2/streams/errors_pb2_grpc.py +0 -0
  58. {kurrentdbclient-1.3.2 → kurrentdbclient-1.3.4}/kurrentdbclient/protos/v2/streams/streams_pb2.py +0 -0
  59. {kurrentdbclient-1.3.2 → kurrentdbclient-1.3.4}/kurrentdbclient/protos/v2/streams/streams_pb2.pyi +0 -0
  60. {kurrentdbclient-1.3.2 → kurrentdbclient-1.3.4}/kurrentdbclient/protos/v2/streams/streams_pb2_grpc.py +0 -0
  61. {kurrentdbclient-1.3.2 → kurrentdbclient-1.3.4}/kurrentdbclient/py.typed +0 -0
  62. {kurrentdbclient-1.3.2 → kurrentdbclient-1.3.4}/kurrentdbclient/unpack_error_status.py +0 -0
  63. {kurrentdbclient-1.3.2 → kurrentdbclient-1.3.4}/kurrentdbclient/v2streams.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kurrentdbclient
3
- Version: 1.3.2
3
+ Version: 1.3.4
4
4
  Summary: Python gRPC Client for KurrentDB
5
5
  License: BSD-3-Clause
6
6
  License-File: LICENSE
@@ -16,6 +16,7 @@ Classifier: Programming Language :: Python :: 3.11
16
16
  Classifier: Programming Language :: Python :: 3.12
17
17
  Classifier: Programming Language :: Python :: 3.13
18
18
  Classifier: Programming Language :: Python :: 3.14
19
+ Classifier: Programming Language :: Python :: 3.15
19
20
  Classifier: Programming Language :: Python
20
21
  Classifier: Topic :: Database
21
22
  Classifier: Topic :: Database :: Front-Ends
@@ -32,7 +33,7 @@ Project-URL: Repository, https://github.com/pyeventsourcing/kurrentdbclient
32
33
  Project-URL: issues, https://github.com/pyeventsourcing/kurrentdbclient/issues
33
34
  Description-Content-Type: text/markdown
34
35
 
35
- from uuid import uuid4<a href="https://kurrent.io">
36
+ <a href="https://kurrent.io">
36
37
  <picture>
37
38
  <source media="(prefers-color-scheme: dark)" srcset="https://github.com/pyeventsourcing/kurrentdbclient/raw/1.0/KurrentLogo-White.png.png">
38
39
  <source media="(prefers-color-scheme: light)" srcset="https://github.com/pyeventsourcing/kurrentdbclient/raw/1.0/KurrentLogo-Black.png">
@@ -59,7 +60,7 @@ features are presented in an easy-to-use interface.
59
60
  These clients have been tested to work with KurrentDB versions 25.0, 25.1, 26.0,
60
61
  and 26.1, and EventStoreDB versions 23.10 and 24.10, with and without SSL/TLS,
61
62
  in both single-server and cluster modes, across Python versions 3.10, 3.11, 3.12,
62
- 3.13, and 3.14.
63
+ 3.13, 3.14, and 3.15.
63
64
 
64
65
  The test suite has 100% line and branch coverage. The code has typing annotations
65
66
  checked strictly with mypy. The code is formatted with black and isort, and checked
@@ -572,8 +573,8 @@ The table below describes the query string field-values supported by this client
572
573
  | GossipTimeout | integer (default: 5) | The default value (in seconds) of the `timeout` argument of gossip read methods, such as `read_gossip()`. |
573
574
  | MaxDiscoverAttempts | integer (default: 10) | The number of attempts to read gossip when connecting or reconnecting to a cluster member. |
574
575
  | DiscoveryInterval | integer (default: 100) | How long to wait (in milliseconds) between gossip retries. |
575
- | KeepAliveInterval | integer (default: `None`) | The value (in milliseconds) of the "grpc.keepalive_ms" gRPC channel option. |
576
- | KeepAliveTimeout | integer (default: `None`) | The value (in milliseconds) of the "grpc.keepalive_timeout_ms" gRPC channel option. |
576
+ | KeepAliveInterval | integer (default: `None`) | The value (in milliseconds) of the "grpc.keepalive_time_ms" gRPC channel option. |
577
+ | KeepAliveTimeout | integer (default: `None`) | The value (in milliseconds) of the "grpc.keepalive_timeout_ms" and "grpc.http2.ping_timeout_ms" gRPC channel options. |
577
578
  | TlsCaFile | string (default: `None`) | Absolute filesystem path to file containing the CA certicate in PEM format. This will be used to verify the server's certificate. |
578
579
  | UserCertFile | string (default: `None`) | Absolute filesystem path to file containing the X.509 user certificate in PEM format. |
579
580
  | UserKeyFile | string (default: `None`) | Absolute filesystem path to file containing the X.509 user certificate's private key in PEM format. |
@@ -1,4 +1,4 @@
1
- from uuid import uuid4<a href="https://kurrent.io">
1
+ <a href="https://kurrent.io">
2
2
  <picture>
3
3
  <source media="(prefers-color-scheme: dark)" srcset="https://github.com/pyeventsourcing/kurrentdbclient/raw/1.0/KurrentLogo-White.png.png">
4
4
  <source media="(prefers-color-scheme: light)" srcset="https://github.com/pyeventsourcing/kurrentdbclient/raw/1.0/KurrentLogo-Black.png">
@@ -25,7 +25,7 @@ features are presented in an easy-to-use interface.
25
25
  These clients have been tested to work with KurrentDB versions 25.0, 25.1, 26.0,
26
26
  and 26.1, and EventStoreDB versions 23.10 and 24.10, with and without SSL/TLS,
27
27
  in both single-server and cluster modes, across Python versions 3.10, 3.11, 3.12,
28
- 3.13, and 3.14.
28
+ 3.13, 3.14, and 3.15.
29
29
 
30
30
  The test suite has 100% line and branch coverage. The code has typing annotations
31
31
  checked strictly with mypy. The code is formatted with black and isort, and checked
@@ -538,8 +538,8 @@ The table below describes the query string field-values supported by this client
538
538
  | GossipTimeout | integer (default: 5) | The default value (in seconds) of the `timeout` argument of gossip read methods, such as `read_gossip()`. |
539
539
  | MaxDiscoverAttempts | integer (default: 10) | The number of attempts to read gossip when connecting or reconnecting to a cluster member. |
540
540
  | DiscoveryInterval | integer (default: 100) | How long to wait (in milliseconds) between gossip retries. |
541
- | KeepAliveInterval | integer (default: `None`) | The value (in milliseconds) of the "grpc.keepalive_ms" gRPC channel option. |
542
- | KeepAliveTimeout | integer (default: `None`) | The value (in milliseconds) of the "grpc.keepalive_timeout_ms" gRPC channel option. |
541
+ | KeepAliveInterval | integer (default: `None`) | The value (in milliseconds) of the "grpc.keepalive_time_ms" gRPC channel option. |
542
+ | KeepAliveTimeout | integer (default: `None`) | The value (in milliseconds) of the "grpc.keepalive_timeout_ms" and "grpc.http2.ping_timeout_ms" gRPC channel options. |
543
543
  | TlsCaFile | string (default: `None`) | Absolute filesystem path to file containing the CA certicate in PEM format. This will be used to verify the server's certificate. |
544
544
  | UserCertFile | string (default: `None`) | Absolute filesystem path to file containing the X.509 user certificate in PEM format. |
545
545
  | UserKeyFile | string (default: `None`) | Absolute filesystem path to file containing the X.509 user certificate's private key in PEM format. |
@@ -28,7 +28,7 @@ from kurrentdbclient.streams import (
28
28
  ReadResponse,
29
29
  )
30
30
 
31
- __version__ = "1.3.2"
31
+ __version__ = "1.3.4"
32
32
 
33
33
  __all__ = [
34
34
  "DEFAULT_EXCLUDE_FILTER",
@@ -208,12 +208,16 @@ class BaseKurrentDBClient(ABC):
208
208
 
209
209
  self._default_deadline = self.connection_spec.options.default_deadline
210
210
 
211
+ # GRPC options ref: https://grpc.github.io/grpc/core/group__grpc__arg__keys.html
211
212
  self.grpc_options: GrpcOptions = (
212
213
  ("grpc.max_receive_message_length", 17 * 1024 * 1024),
213
214
  )
214
215
  if self.connection_spec.options.keep_alive_interval is not None:
215
216
  self.grpc_options += (
216
- ("grpc.keepalive_ms", self.connection_spec.options.keep_alive_interval),
217
+ (
218
+ "grpc.keepalive_time_ms",
219
+ self.connection_spec.options.keep_alive_interval,
220
+ ),
217
221
  )
218
222
  if self.connection_spec.options.keep_alive_timeout is not None:
219
223
  self.grpc_options += (
@@ -221,6 +225,12 @@ class BaseKurrentDBClient(ABC):
221
225
  "grpc.keepalive_timeout_ms",
222
226
  self.connection_spec.options.keep_alive_timeout,
223
227
  ),
228
+ # gRPC closes a connection whose ping is not answered after
229
+ # this time (default 60s), not after keepalive_timeout_ms.
230
+ (
231
+ "grpc.http2.ping_timeout_ms",
232
+ self.connection_spec.options.keep_alive_timeout,
233
+ ),
224
234
  )
225
235
 
226
236
  self._call_metadata = (
@@ -21,6 +21,7 @@ from weakref import WeakValueDictionary
21
21
 
22
22
  import grpc
23
23
  import grpc.aio
24
+ from grpc.aio import AioRpcError
24
25
  from grpc_status import rpc_status
25
26
  from typing_extensions import Self
26
27
 
@@ -627,16 +628,23 @@ class AsyncRecordedEventIterator(
627
628
  self._is_context_manager_active = False
628
629
  await self.stop(timeout=5)
629
630
 
630
- def _set_iter_error_for_testing(self) -> None:
631
+ def _set_iter_error_for_testing(self, msg: str) -> None:
631
632
  # This, because I can't find a good way to inspire an error during iterating
632
633
  # with catchup and persistent subscriptions after successfully
633
634
  # receiving confirmation response, tried closing the channel
634
635
  # but the async streaming response continues (unlike with sync call). Needed
635
636
  # to inspire this error to test instrumentation span error during iteration.
636
- self._iter_error_for_testing = True
637
-
638
- def _has_iter_error_for_testing(self) -> bool:
639
- return getattr(self, "_iter_error_for_testing", False)
637
+ self._iter_error_for_testing = msg
638
+
639
+ def _check_iter_error_for_testing(self) -> None:
640
+ if msg := getattr(self, "_iter_error_for_testing", ""):
641
+ raise AioRpcError(
642
+ grpc.StatusCode.INTERNAL,
643
+ grpc.aio.Metadata(),
644
+ grpc.aio.Metadata(),
645
+ msg,
646
+ "",
647
+ )
640
648
 
641
649
 
642
650
  class AbstractAsyncReadResponse(AsyncRecordedEventIterator):
@@ -966,8 +966,8 @@ class TracedAsyncRecordedEventIterator(
966
966
  async def __aexit__(self, *args: object, **kwargs: Any) -> None:
967
967
  return await self.response.__aexit__(*args, **kwargs)
968
968
 
969
- def _set_iter_error_for_testing(self) -> None:
970
- self.response._set_iter_error_for_testing()
969
+ def _set_iter_error_for_testing(self, msg: str) -> None:
970
+ self.response._set_iter_error_for_testing(msg)
971
971
 
972
972
  def __del__(self) -> None:
973
973
  current_span = self._current_span
@@ -18,7 +18,7 @@ from typing import (
18
18
  from uuid import UUID
19
19
 
20
20
  import grpc
21
- from grpc.aio import AioRpcError, StreamStreamCall
21
+ from grpc.aio import StreamStreamCall
22
22
  from typing_extensions import Protocol, Self, TypedDict
23
23
 
24
24
  from kurrentdbclient.common import (
@@ -523,14 +523,7 @@ class AsyncPersistentSubscription(
523
523
  while True:
524
524
  read_resp = await self._read_resp_iter.__anext__()
525
525
  await self._read_resp_queue.put(read_resp)
526
- if self._has_iter_error_for_testing():
527
- raise AioRpcError(
528
- grpc.StatusCode.INTERNAL,
529
- grpc.aio.Metadata(),
530
- grpc.aio.Metadata(),
531
- "",
532
- "",
533
- )
526
+ self._check_iter_error_for_testing()
534
527
  except BaseException:
535
528
  # Drain the queue (to avoid blocking on put).
536
529
  try:
@@ -14,7 +14,6 @@ from uuid import UUID, uuid4
14
14
  import grpc
15
15
  import grpc.aio
16
16
  from google.protobuf import any_pb2, duration_pb2, empty_pb2
17
- from grpc.aio import AioRpcError
18
17
  from typing_extensions import Protocol
19
18
 
20
19
  from kurrentdbclient.common import (
@@ -186,14 +185,7 @@ class AsyncReadResponse(BaseReadResponse, AsyncGrpcStreamer, AbstractAsyncReadRe
186
185
  while True:
187
186
  read_resp = await self._read_resp_iter.__anext__()
188
187
  await self._read_resp_queue.put(read_resp)
189
- if self._has_iter_error_for_testing():
190
- raise AioRpcError(
191
- grpc.StatusCode.INTERNAL,
192
- grpc.aio.Metadata(),
193
- grpc.aio.Metadata(),
194
- "",
195
- "",
196
- )
188
+ self._check_iter_error_for_testing()
197
189
  except StopAsyncIteration:
198
190
  # End of the stream, signal to end the iteration.
199
191
  await self._read_resp_queue.put(None)
@@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api"
4
4
 
5
5
  [project]
6
6
  name = "kurrentdbclient"
7
- version = "1.3.2"
7
+ version = "1.3.4"
8
8
  description = "Python gRPC Client for KurrentDB"
9
9
  license = { text = "BSD-3-Clause" }
10
10
  readme = "README.md"
@@ -24,6 +24,7 @@ classifiers = [
24
24
  "Programming Language :: Python :: 3.12",
25
25
  "Programming Language :: Python :: 3.13",
26
26
  "Programming Language :: Python :: 3.14",
27
+ "Programming Language :: Python :: 3.15",
27
28
  "Programming Language :: Python",
28
29
  "Topic :: Database",
29
30
  "Topic :: Database :: Front-Ends",]
File without changes