repid 2.1.2__tar.gz → 2.1.3__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 (238) hide show
  1. {repid-2.1.2 → repid-2.1.3}/.github/workflows/codeql.yml +1 -1
  2. {repid-2.1.2 → repid-2.1.3}/.github/workflows/dependency-review.yml +1 -1
  3. {repid-2.1.2 → repid-2.1.3}/.github/workflows/docs.yml +1 -1
  4. {repid-2.1.2 → repid-2.1.3}/.github/workflows/mypy.yml +1 -1
  5. {repid-2.1.2 → repid-2.1.3}/.github/workflows/release.yaml +1 -1
  6. {repid-2.1.2 → repid-2.1.3}/.github/workflows/tests.yaml +2 -2
  7. {repid-2.1.2 → repid-2.1.3}/.pre-commit-config.yaml +2 -2
  8. {repid-2.1.2 → repid-2.1.3}/PKG-INFO +1 -1
  9. repid-2.1.3/docs/cookbook/opentelemetry_middleware.md +281 -0
  10. {repid-2.1.2 → repid-2.1.3}/mkdocs.yml +2 -0
  11. {repid-2.1.2 → repid-2.1.3}/repid/_runner.py +21 -30
  12. {repid-2.1.2 → repid-2.1.3}/repid/_worker.py +5 -10
  13. {repid-2.1.2 → repid-2.1.3}/repid/connections/abc.py +9 -1
  14. {repid-2.1.2 → repid-2.1.3}/repid/converter.py +11 -20
  15. {repid-2.1.2 → repid-2.1.3}/repid/data/__init__.py +1 -0
  16. {repid-2.1.2 → repid-2.1.3}/repid/data/actor.py +9 -1
  17. {repid-2.1.2 → repid-2.1.3}/repid/dependencies/_utils.py +3 -5
  18. {repid-2.1.2 → repid-2.1.3}/repid/dependencies/message_dependency.py +20 -15
  19. {repid-2.1.2 → repid-2.1.3}/repid/main.py +6 -3
  20. {repid-2.1.2 → repid-2.1.3}/repid/test_client.py +10 -5
  21. {repid-2.1.2 → repid-2.1.3}/tests/integration/conftest.py +39 -0
  22. {repid-2.1.2 → repid-2.1.3}/tests/unit/test_converter.py +29 -41
  23. {repid-2.1.2 → repid-2.1.3}/tests/unit/test_dependencies.py +14 -5
  24. {repid-2.1.2 → repid-2.1.3}/tests/unit/test_middleware.py +92 -1
  25. {repid-2.1.2 → repid-2.1.3}/tests/unit/test_runner.py +28 -32
  26. {repid-2.1.2 → repid-2.1.3}/tests/unit/test_worker.py +29 -8
  27. {repid-2.1.2 → repid-2.1.3}/uv.lock +172 -172
  28. {repid-2.1.2 → repid-2.1.3}/.devcontainer/devcontainer.json +0 -0
  29. {repid-2.1.2 → repid-2.1.3}/.github/CODE_OF_CONDUCT.md +0 -0
  30. {repid-2.1.2 → repid-2.1.3}/.github/FUNDING.yml +0 -0
  31. {repid-2.1.2 → repid-2.1.3}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  32. {repid-2.1.2 → repid-2.1.3}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  33. {repid-2.1.2 → repid-2.1.3}/.github/ISSUE_TEMPLATE/other.md +0 -0
  34. {repid-2.1.2 → repid-2.1.3}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  35. {repid-2.1.2 → repid-2.1.3}/.github/dependabot.yml +0 -0
  36. {repid-2.1.2 → repid-2.1.3}/.gitignore +0 -0
  37. {repid-2.1.2 → repid-2.1.3}/LICENSE +0 -0
  38. {repid-2.1.2 → repid-2.1.3}/Makefile +0 -0
  39. {repid-2.1.2 → repid-2.1.3}/README.md +0 -0
  40. {repid-2.1.2 → repid-2.1.3}/SECURITY.md +0 -0
  41. {repid-2.1.2 → repid-2.1.3}/docs/advanced_user_guide/your_own_brokers.md +0 -0
  42. {repid-2.1.2 → repid-2.1.3}/docs/advanced_user_guide/your_own_converter.md +0 -0
  43. {repid-2.1.2 → repid-2.1.3}/docs/advanced_user_guide/your_own_serializer.md +0 -0
  44. {repid-2.1.2 → repid-2.1.3}/docs/benchmarks.md +0 -0
  45. {repid-2.1.2 → repid-2.1.3}/docs/benchmarks_img/.gitignore +0 -0
  46. {repid-2.1.2 → repid-2.1.3}/docs/benchmarks_img/chart.svg +0 -0
  47. {repid-2.1.2 → repid-2.1.3}/docs/contributing.md +0 -0
  48. {repid-2.1.2 → repid-2.1.3}/docs/cookbook/chaining_jobs.md +0 -0
  49. {repid-2.1.2 → repid-2.1.3}/docs/cookbook/large_payloads.md +0 -0
  50. {repid-2.1.2 → repid-2.1.3}/docs/cookbook/middlewares.md +0 -0
  51. {repid-2.1.2 → repid-2.1.3}/docs/cookbook/rabbitmq_retries.md +0 -0
  52. {repid-2.1.2 → repid-2.1.3}/docs/cookbook/sentry_middleware.md +0 -0
  53. {repid-2.1.2 → repid-2.1.3}/docs/cookbook/testing.md +0 -0
  54. {repid-2.1.2 → repid-2.1.3}/docs/features.md +0 -0
  55. {repid-2.1.2 → repid-2.1.3}/docs/getting_started/glossary.md +0 -0
  56. {repid-2.1.2 → repid-2.1.3}/docs/getting_started/quickstart.md +0 -0
  57. {repid-2.1.2 → repid-2.1.3}/docs/getting_started/supported_brokers.md +0 -0
  58. {repid-2.1.2 → repid-2.1.3}/docs/index.md +0 -0
  59. {repid-2.1.2 → repid-2.1.3}/docs/integrations/asyncapi.md +0 -0
  60. {repid-2.1.2 → repid-2.1.3}/docs/integrations/fastapi_and_pydantic.md +0 -0
  61. {repid-2.1.2 → repid-2.1.3}/docs/overrides/partials/integrations/analytics/custom.html +0 -0
  62. {repid-2.1.2 → repid-2.1.3}/docs/playground.md +0 -0
  63. {repid-2.1.2 → repid-2.1.3}/docs/user_guide/actors/confirmation_and_errors.md +0 -0
  64. {repid-2.1.2 → repid-2.1.3}/docs/user_guide/actors/execution.md +0 -0
  65. {repid-2.1.2 → repid-2.1.3}/docs/user_guide/actors/index.md +0 -0
  66. {repid-2.1.2 → repid-2.1.3}/docs/user_guide/actors/parsing.md +0 -0
  67. {repid-2.1.2 → repid-2.1.3}/docs/user_guide/actors/routers.md +0 -0
  68. {repid-2.1.2 → repid-2.1.3}/docs/user_guide/actors/routing.md +0 -0
  69. {repid-2.1.2 → repid-2.1.3}/docs/user_guide/dependency_injection.md +0 -0
  70. {repid-2.1.2 → repid-2.1.3}/docs/user_guide/message_registry.md +0 -0
  71. {repid-2.1.2 → repid-2.1.3}/docs/user_guide/messages.md +0 -0
  72. {repid-2.1.2 → repid-2.1.3}/docs/user_guide/raw_message_and_eager_response.md +0 -0
  73. {repid-2.1.2 → repid-2.1.3}/docs/user_guide/server_registry.md +0 -0
  74. {repid-2.1.2 → repid-2.1.3}/docs/user_guide/server_specific_parameters.md +0 -0
  75. {repid-2.1.2 → repid-2.1.3}/docs/user_guide/workers/built_in_servers.md +0 -0
  76. {repid-2.1.2 → repid-2.1.3}/docs/user_guide/workers/concurrency.md +0 -0
  77. {repid-2.1.2 → repid-2.1.3}/docs/user_guide/workers/index.md +0 -0
  78. {repid-2.1.2 → repid-2.1.3}/docs/user_guide/workers/lifecycle.md +0 -0
  79. {repid-2.1.2 → repid-2.1.3}/pyproject.toml +0 -0
  80. {repid-2.1.2 → repid-2.1.3}/repid/__init__.py +0 -0
  81. {repid-2.1.2 → repid-2.1.3}/repid/_utils/__init__.py +0 -0
  82. {repid-2.1.2 → repid-2.1.3}/repid/_utils/asyncify_.py +0 -0
  83. {repid-2.1.2 → repid-2.1.3}/repid/_utils/is_installed.py +0 -0
  84. {repid-2.1.2 → repid-2.1.3}/repid/_utils/json_encoder.py +0 -0
  85. {repid-2.1.2 → repid-2.1.3}/repid/_utils/not_set.py +0 -0
  86. {repid-2.1.2 → repid-2.1.3}/repid/asyncapi/__init__.py +0 -0
  87. {repid-2.1.2 → repid-2.1.3}/repid/asyncapi/generator.py +0 -0
  88. {repid-2.1.2 → repid-2.1.3}/repid/asyncapi/models/__init__.py +0 -0
  89. {repid-2.1.2 → repid-2.1.3}/repid/asyncapi/models/asyncapi.py +0 -0
  90. {repid-2.1.2 → repid-2.1.3}/repid/asyncapi/models/channels.py +0 -0
  91. {repid-2.1.2 → repid-2.1.3}/repid/asyncapi/models/common/__init__.py +0 -0
  92. {repid-2.1.2 → repid-2.1.3}/repid/asyncapi/models/common/bindings.py +0 -0
  93. {repid-2.1.2 → repid-2.1.3}/repid/asyncapi/models/common/correlation_id.py +0 -0
  94. {repid-2.1.2 → repid-2.1.3}/repid/asyncapi/models/common/external_docs.py +0 -0
  95. {repid-2.1.2 → repid-2.1.3}/repid/asyncapi/models/common/message.py +0 -0
  96. {repid-2.1.2 → repid-2.1.3}/repid/asyncapi/models/common/reference.py +0 -0
  97. {repid-2.1.2 → repid-2.1.3}/repid/asyncapi/models/common/tag.py +0 -0
  98. {repid-2.1.2 → repid-2.1.3}/repid/asyncapi/models/components.py +0 -0
  99. {repid-2.1.2 → repid-2.1.3}/repid/asyncapi/models/info.py +0 -0
  100. {repid-2.1.2 → repid-2.1.3}/repid/asyncapi/models/operations.py +0 -0
  101. {repid-2.1.2 → repid-2.1.3}/repid/asyncapi/models/servers.py +0 -0
  102. {repid-2.1.2 → repid-2.1.3}/repid/asyncapi_server.py +0 -0
  103. {repid-2.1.2 → repid-2.1.3}/repid/connections/__init__.py +0 -0
  104. {repid-2.1.2 → repid-2.1.3}/repid/connections/amqp/__init__.py +0 -0
  105. {repid-2.1.2 → repid-2.1.3}/repid/connections/amqp/_uamqp/LICENSE.txt +0 -0
  106. {repid-2.1.2 → repid-2.1.3}/repid/connections/amqp/_uamqp/_decode.py +0 -0
  107. {repid-2.1.2 → repid-2.1.3}/repid/connections/amqp/_uamqp/_encode.py +0 -0
  108. {repid-2.1.2 → repid-2.1.3}/repid/connections/amqp/_uamqp/amqptypes.py +0 -0
  109. {repid-2.1.2 → repid-2.1.3}/repid/connections/amqp/_uamqp/constants.py +0 -0
  110. {repid-2.1.2 → repid-2.1.3}/repid/connections/amqp/_uamqp/endpoints.py +0 -0
  111. {repid-2.1.2 → repid-2.1.3}/repid/connections/amqp/_uamqp/message.py +0 -0
  112. {repid-2.1.2 → repid-2.1.3}/repid/connections/amqp/_uamqp/outcomes.py +0 -0
  113. {repid-2.1.2 → repid-2.1.3}/repid/connections/amqp/_uamqp/performatives.py +0 -0
  114. {repid-2.1.2 → repid-2.1.3}/repid/connections/amqp/helpers.py +0 -0
  115. {repid-2.1.2 → repid-2.1.3}/repid/connections/amqp/message_broker.py +0 -0
  116. {repid-2.1.2 → repid-2.1.3}/repid/connections/amqp/protocol/__init__.py +0 -0
  117. {repid-2.1.2 → repid-2.1.3}/repid/connections/amqp/protocol/connection.py +0 -0
  118. {repid-2.1.2 → repid-2.1.3}/repid/connections/amqp/protocol/events.py +0 -0
  119. {repid-2.1.2 → repid-2.1.3}/repid/connections/amqp/protocol/links.py +0 -0
  120. {repid-2.1.2 → repid-2.1.3}/repid/connections/amqp/protocol/managed.py +0 -0
  121. {repid-2.1.2 → repid-2.1.3}/repid/connections/amqp/protocol/reconnect.py +0 -0
  122. {repid-2.1.2 → repid-2.1.3}/repid/connections/amqp/protocol/session.py +0 -0
  123. {repid-2.1.2 → repid-2.1.3}/repid/connections/amqp/protocol/states.py +0 -0
  124. {repid-2.1.2 → repid-2.1.3}/repid/connections/amqp/protocol/transport.py +0 -0
  125. {repid-2.1.2 → repid-2.1.3}/repid/connections/amqp/subscriber.py +0 -0
  126. {repid-2.1.2 → repid-2.1.3}/repid/connections/in_memory/__init__.py +0 -0
  127. {repid-2.1.2 → repid-2.1.3}/repid/connections/in_memory/message_broker.py +0 -0
  128. {repid-2.1.2 → repid-2.1.3}/repid/connections/in_memory/utils.py +0 -0
  129. {repid-2.1.2 → repid-2.1.3}/repid/connections/kafka/__init__.py +0 -0
  130. {repid-2.1.2 → repid-2.1.3}/repid/connections/kafka/message.py +0 -0
  131. {repid-2.1.2 → repid-2.1.3}/repid/connections/kafka/message_broker.py +0 -0
  132. {repid-2.1.2 → repid-2.1.3}/repid/connections/kafka/protocols.py +0 -0
  133. {repid-2.1.2 → repid-2.1.3}/repid/connections/kafka/subscriber.py +0 -0
  134. {repid-2.1.2 → repid-2.1.3}/repid/connections/nats/__init__.py +0 -0
  135. {repid-2.1.2 → repid-2.1.3}/repid/connections/nats/message_broker.py +0 -0
  136. {repid-2.1.2 → repid-2.1.3}/repid/connections/pubsub/__init__.py +0 -0
  137. {repid-2.1.2 → repid-2.1.3}/repid/connections/pubsub/helpers.py +0 -0
  138. {repid-2.1.2 → repid-2.1.3}/repid/connections/pubsub/message_broker.py +0 -0
  139. {repid-2.1.2 → repid-2.1.3}/repid/connections/pubsub/protocol/__init__.py +0 -0
  140. {repid-2.1.2 → repid-2.1.3}/repid/connections/pubsub/protocol/_helpers.py +0 -0
  141. {repid-2.1.2 → repid-2.1.3}/repid/connections/pubsub/protocol/channel.py +0 -0
  142. {repid-2.1.2 → repid-2.1.3}/repid/connections/pubsub/protocol/client.py +0 -0
  143. {repid-2.1.2 → repid-2.1.3}/repid/connections/pubsub/protocol/control_batcher.py +0 -0
  144. {repid-2.1.2 → repid-2.1.3}/repid/connections/pubsub/protocol/credentials.py +0 -0
  145. {repid-2.1.2 → repid-2.1.3}/repid/connections/pubsub/protocol/proto.py +0 -0
  146. {repid-2.1.2 → repid-2.1.3}/repid/connections/pubsub/protocol/received_message.py +0 -0
  147. {repid-2.1.2 → repid-2.1.3}/repid/connections/pubsub/protocol/resilience.py +0 -0
  148. {repid-2.1.2 → repid-2.1.3}/repid/connections/pubsub/protocol/subscriber.py +0 -0
  149. {repid-2.1.2 → repid-2.1.3}/repid/connections/redis/__init__.py +0 -0
  150. {repid-2.1.2 → repid-2.1.3}/repid/connections/redis/message_broker.py +0 -0
  151. {repid-2.1.2 → repid-2.1.3}/repid/connections/sqs/__init__.py +0 -0
  152. {repid-2.1.2 → repid-2.1.3}/repid/connections/sqs/constants.py +0 -0
  153. {repid-2.1.2 → repid-2.1.3}/repid/connections/sqs/message.py +0 -0
  154. {repid-2.1.2 → repid-2.1.3}/repid/connections/sqs/message_broker.py +0 -0
  155. {repid-2.1.2 → repid-2.1.3}/repid/connections/sqs/subscriber.py +0 -0
  156. {repid-2.1.2 → repid-2.1.3}/repid/data/channel.py +0 -0
  157. {repid-2.1.2 → repid-2.1.3}/repid/data/contact.py +0 -0
  158. {repid-2.1.2 → repid-2.1.3}/repid/data/converter_input_schema.py +0 -0
  159. {repid-2.1.2 → repid-2.1.3}/repid/data/external_docs.py +0 -0
  160. {repid-2.1.2 → repid-2.1.3}/repid/data/license.py +0 -0
  161. {repid-2.1.2 → repid-2.1.3}/repid/data/message.py +0 -0
  162. {repid-2.1.2 → repid-2.1.3}/repid/data/message_schema.py +0 -0
  163. {repid-2.1.2 → repid-2.1.3}/repid/data/operation.py +0 -0
  164. {repid-2.1.2 → repid-2.1.3}/repid/data/runner_info.py +0 -0
  165. {repid-2.1.2 → repid-2.1.3}/repid/data/tag.py +0 -0
  166. {repid-2.1.2 → repid-2.1.3}/repid/dependencies/__init__.py +0 -0
  167. {repid-2.1.2 → repid-2.1.3}/repid/dependencies/depends.py +0 -0
  168. {repid-2.1.2 → repid-2.1.3}/repid/dependencies/full_payload.py +0 -0
  169. {repid-2.1.2 → repid-2.1.3}/repid/dependencies/header_dependency.py +0 -0
  170. {repid-2.1.2 → repid-2.1.3}/repid/health_check_server.py +0 -0
  171. {repid-2.1.2 → repid-2.1.3}/repid/logger.py +0 -0
  172. {repid-2.1.2 → repid-2.1.3}/repid/message_registry.py +0 -0
  173. {repid-2.1.2 → repid-2.1.3}/repid/middlewares.py +0 -0
  174. {repid-2.1.2 → repid-2.1.3}/repid/py.typed +0 -0
  175. {repid-2.1.2 → repid-2.1.3}/repid/router.py +0 -0
  176. {repid-2.1.2 → repid-2.1.3}/repid/serializer.py +0 -0
  177. {repid-2.1.2 → repid-2.1.3}/repid/server_registry.py +0 -0
  178. {repid-2.1.2 → repid-2.1.3}/tests/__init__.py +0 -0
  179. {repid-2.1.2 → repid-2.1.3}/tests/integration/__init__.py +0 -0
  180. {repid-2.1.2 → repid-2.1.3}/tests/integration/pubsub_proto_helpers.py +0 -0
  181. {repid-2.1.2 → repid-2.1.3}/tests/integration/rabbitmq_definitions.json +0 -0
  182. {repid-2.1.2 → repid-2.1.3}/tests/integration/test_asyncapi_compatibility.py +0 -0
  183. {repid-2.1.2 → repid-2.1.3}/tests/integration/test_default_flow.py +0 -0
  184. {repid-2.1.2 → repid-2.1.3}/tests/integration/test_kafka_specific.py +0 -0
  185. {repid-2.1.2 → repid-2.1.3}/tests/integration/test_nats_specific.py +0 -0
  186. {repid-2.1.2 → repid-2.1.3}/tests/integration/test_rabbitmq_specific.py +0 -0
  187. {repid-2.1.2 → repid-2.1.3}/tests/integration/test_sqs_specific.py +0 -0
  188. {repid-2.1.2 → repid-2.1.3}/tests/integration/test_worker.py +0 -0
  189. {repid-2.1.2 → repid-2.1.3}/tests/unit/__init__.py +0 -0
  190. {repid-2.1.2 → repid-2.1.3}/tests/unit/amqp/__init__.py +0 -0
  191. {repid-2.1.2 → repid-2.1.3}/tests/unit/amqp/conftest.py +0 -0
  192. {repid-2.1.2 → repid-2.1.3}/tests/unit/amqp/test_amqp_transport.py +0 -0
  193. {repid-2.1.2 → repid-2.1.3}/tests/unit/amqp/test_connection.py +0 -0
  194. {repid-2.1.2 → repid-2.1.3}/tests/unit/amqp/test_encoding_decoding.py +0 -0
  195. {repid-2.1.2 → repid-2.1.3}/tests/unit/amqp/test_event_emitter.py +0 -0
  196. {repid-2.1.2 → repid-2.1.3}/tests/unit/amqp/test_frame_buffer.py +0 -0
  197. {repid-2.1.2 → repid-2.1.3}/tests/unit/amqp/test_links.py +0 -0
  198. {repid-2.1.2 → repid-2.1.3}/tests/unit/amqp/test_logging.py +0 -0
  199. {repid-2.1.2 → repid-2.1.3}/tests/unit/amqp/test_managed.py +0 -0
  200. {repid-2.1.2 → repid-2.1.3}/tests/unit/amqp/test_managed_pools.py +0 -0
  201. {repid-2.1.2 → repid-2.1.3}/tests/unit/amqp/test_message.py +0 -0
  202. {repid-2.1.2 → repid-2.1.3}/tests/unit/amqp/test_message_broker.py +0 -0
  203. {repid-2.1.2 → repid-2.1.3}/tests/unit/amqp/test_metrics.py +0 -0
  204. {repid-2.1.2 → repid-2.1.3}/tests/unit/amqp/test_reconnect.py +0 -0
  205. {repid-2.1.2 → repid-2.1.3}/tests/unit/amqp/test_session.py +0 -0
  206. {repid-2.1.2 → repid-2.1.3}/tests/unit/amqp/test_state_machine.py +0 -0
  207. {repid-2.1.2 → repid-2.1.3}/tests/unit/amqp/test_uamqp_types.py +0 -0
  208. {repid-2.1.2 → repid-2.1.3}/tests/unit/amqp/utils.py +0 -0
  209. {repid-2.1.2 → repid-2.1.3}/tests/unit/conftest.py +0 -0
  210. {repid-2.1.2 → repid-2.1.3}/tests/unit/in_memory/__init__.py +0 -0
  211. {repid-2.1.2 → repid-2.1.3}/tests/unit/in_memory/test_message_broker.py +0 -0
  212. {repid-2.1.2 → repid-2.1.3}/tests/unit/in_memory/test_utils.py +0 -0
  213. {repid-2.1.2 → repid-2.1.3}/tests/unit/pubsub/__init__.py +0 -0
  214. {repid-2.1.2 → repid-2.1.3}/tests/unit/pubsub/protocol/test_channel.py +0 -0
  215. {repid-2.1.2 → repid-2.1.3}/tests/unit/pubsub/protocol/test_client.py +0 -0
  216. {repid-2.1.2 → repid-2.1.3}/tests/unit/pubsub/protocol/test_control_batcher.py +0 -0
  217. {repid-2.1.2 → repid-2.1.3}/tests/unit/pubsub/protocol/test_credentials.py +0 -0
  218. {repid-2.1.2 → repid-2.1.3}/tests/unit/pubsub/protocol/test_helpers_internal.py +0 -0
  219. {repid-2.1.2 → repid-2.1.3}/tests/unit/pubsub/protocol/test_proto.py +0 -0
  220. {repid-2.1.2 → repid-2.1.3}/tests/unit/pubsub/protocol/test_received_message.py +0 -0
  221. {repid-2.1.2 → repid-2.1.3}/tests/unit/pubsub/protocol/test_resilience.py +0 -0
  222. {repid-2.1.2 → repid-2.1.3}/tests/unit/pubsub/protocol/test_subscriber.py +0 -0
  223. {repid-2.1.2 → repid-2.1.3}/tests/unit/pubsub/protocol/test_subscriber_execution.py +0 -0
  224. {repid-2.1.2 → repid-2.1.3}/tests/unit/pubsub/test_helpers.py +0 -0
  225. {repid-2.1.2 → repid-2.1.3}/tests/unit/pubsub/test_message_broker.py +0 -0
  226. {repid-2.1.2 → repid-2.1.3}/tests/unit/redis/__init__.py +0 -0
  227. {repid-2.1.2 → repid-2.1.3}/tests/unit/redis/test_message_broker.py +0 -0
  228. {repid-2.1.2 → repid-2.1.3}/tests/unit/redis/test_redis_keep_alive.py +0 -0
  229. {repid-2.1.2 → repid-2.1.3}/tests/unit/test_asyncapi_generator.py +0 -0
  230. {repid-2.1.2 → repid-2.1.3}/tests/unit/test_channel.py +0 -0
  231. {repid-2.1.2 → repid-2.1.3}/tests/unit/test_health_check_server.py +0 -0
  232. {repid-2.1.2 → repid-2.1.3}/tests/unit/test_main.py +0 -0
  233. {repid-2.1.2 → repid-2.1.3}/tests/unit/test_router.py +0 -0
  234. {repid-2.1.2 → repid-2.1.3}/tests/unit/test_runner_manual_explicit.py +0 -0
  235. {repid-2.1.2 → repid-2.1.3}/tests/unit/test_serializer.py +0 -0
  236. {repid-2.1.2 → repid-2.1.3}/tests/unit/test_server_registry.py +0 -0
  237. {repid-2.1.2 → repid-2.1.3}/tests/unit/test_test_client.py +0 -0
  238. {repid-2.1.2 → repid-2.1.3}/tests/unit/test_utils.py +0 -0
@@ -38,7 +38,7 @@ jobs:
38
38
 
39
39
  steps:
40
40
  - name: Checkout repository
41
- uses: actions/checkout@v6
41
+ uses: actions/checkout@v7
42
42
 
43
43
  # Initializes the CodeQL tools for scanning.
44
44
  - name: Initialize CodeQL
@@ -16,7 +16,7 @@ jobs:
16
16
  runs-on: ubuntu-latest
17
17
  steps:
18
18
  - name: Checkout Repository
19
- uses: actions/checkout@v6
19
+ uses: actions/checkout@v7
20
20
 
21
21
  - name: Setup uv
22
22
  uses: astral-sh/setup-uv@v7
@@ -11,7 +11,7 @@ jobs:
11
11
  runs-on: ubuntu-latest
12
12
  steps:
13
13
  - name: Checkout repository
14
- uses: actions/checkout@v6
14
+ uses: actions/checkout@v7
15
15
  with:
16
16
  fetch-depth: 0
17
17
 
@@ -12,7 +12,7 @@ jobs:
12
12
 
13
13
  steps:
14
14
  - name: Checkout repository
15
- uses: actions/checkout@v6
15
+ uses: actions/checkout@v7
16
16
 
17
17
  - name: Setup uv
18
18
  uses: astral-sh/setup-uv@v7
@@ -15,7 +15,7 @@ jobs:
15
15
  id-token: write
16
16
  steps:
17
17
  - name: Checkout repository
18
- uses: actions/checkout@v6
18
+ uses: actions/checkout@v7
19
19
  with:
20
20
  fetch-depth: 0
21
21
 
@@ -26,7 +26,7 @@ jobs:
26
26
 
27
27
  steps:
28
28
  - name: Checkout repository
29
- uses: actions/checkout@v6
29
+ uses: actions/checkout@v7
30
30
 
31
31
  - name: Setup uv
32
32
  uses: astral-sh/setup-uv@v7
@@ -60,7 +60,7 @@ jobs:
60
60
  contents: write
61
61
 
62
62
  steps:
63
- - uses: actions/checkout@v6
63
+ - uses: actions/checkout@v7
64
64
 
65
65
  - name: Setup uv
66
66
  uses: astral-sh/setup-uv@v7
@@ -19,14 +19,14 @@ repos:
19
19
  - id: end-of-file-fixer
20
20
 
21
21
  - repo: https://github.com/astral-sh/ruff-pre-commit
22
- rev: v0.15.15
22
+ rev: v0.15.18
23
23
  hooks:
24
24
  - id: ruff-check
25
25
  args: [--fix, --exit-non-zero-on-fix]
26
26
  - id: ruff-format
27
27
 
28
28
  - repo: https://github.com/igorshubovych/markdownlint-cli
29
- rev: v0.48.0
29
+ rev: v0.49.0
30
30
  hooks:
31
31
  - id: markdownlint-fix
32
32
  args: [--config=pyproject.toml, --configPointer=/tool/markdownlint]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: repid
3
- Version: 2.1.2
3
+ Version: 2.1.3
4
4
  Summary: Repid is a simple, fast, and extensible async task queue framework, with built-in AsyncAPI 3.0 schema generation.
5
5
  Project-URL: documentation, https://repid.aleksul.space
6
6
  Project-URL: funding, https://github.com/sponsors/aleksul
@@ -0,0 +1,281 @@
1
+ # OpenTelemetry Middleware
2
+
3
+ [OpenTelemetry](https://opentelemetry.io/) gives you vendor-neutral traces and metrics for your
4
+ Repid producers and actors. This cookbook shows how to configure Repid middlewares that propagate
5
+ trace context through message headers and record message processing and publishing metrics.
6
+
7
+ ## Prerequisites
8
+
9
+ Install the OpenTelemetry API, SDK, and an exporter. This example uses the OTLP gRPC exporter,
10
+ which works with OpenTelemetry Collector and many observability vendors.
11
+
12
+ ```bash
13
+ pip install repid opentelemetry-api opentelemetry-sdk opentelemetry-exporter-otlp-proto-grpc
14
+ ```
15
+
16
+ If your application already configures OpenTelemetry, keep that setup and only add the Repid
17
+ middlewares below.
18
+
19
+ ## OpenTelemetry Setup
20
+
21
+ Configure the OpenTelemetry SDK once when your process starts. A worker process and any process that
22
+ publishes Repid messages should both initialize OpenTelemetry. The exact exporter, endpoint,
23
+ resource attributes, sampling, and authentication settings are up to your application and depend
24
+ heavily on your observability infrastructure.
25
+
26
+ Below is a minimal OTLP gRPC example, not a required Repid configuration.
27
+
28
+ ```python
29
+ from opentelemetry import metrics, trace
30
+ from opentelemetry.exporter.otlp.proto.grpc.metric_exporter import OTLPMetricExporter
31
+ from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
32
+ from opentelemetry.sdk.metrics import MeterProvider
33
+ from opentelemetry.sdk.metrics.export import PeriodicExportingMetricReader
34
+ from opentelemetry.sdk.resources import Resource
35
+ from opentelemetry.sdk.trace import TracerProvider
36
+ from opentelemetry.sdk.trace.export import BatchSpanProcessor
37
+
38
+
39
+ def configure_opentelemetry(service_name: str = "repid-worker") -> None:
40
+ resource = Resource.create({"service.name": service_name})
41
+
42
+ tracer_provider = TracerProvider(resource=resource)
43
+ tracer_provider.add_span_processor(BatchSpanProcessor(OTLPSpanExporter()))
44
+ trace.set_tracer_provider(tracer_provider)
45
+
46
+ metric_reader = PeriodicExportingMetricReader(OTLPMetricExporter())
47
+ meter_provider = MeterProvider(resource=resource, metric_readers=[metric_reader])
48
+ metrics.set_meter_provider(meter_provider)
49
+ ```
50
+
51
+ ## The Middlewares
52
+
53
+ In total, we will create 4 middlewares: 2 metric reporting middlewares, and
54
+ 2 tracing middlewares - each for producer and consumer parts.
55
+
56
+ When a producer sends a Repid message, the active `traceparent` and `tracestate` headers
57
+ are injected into the message. When a worker consumes that message,
58
+ the actor span continues the same distributed trace.
59
+
60
+ The span names and attributes follow the
61
+ [OpenTelemetry messaging semantic conventions](https://opentelemetry.io/docs/specs/semconv/messaging/messaging-spans/#messaging-attributes).
62
+
63
+ ```python
64
+ from collections.abc import Callable, Coroutine
65
+ from dataclasses import replace
66
+ from time import perf_counter
67
+ from typing import Any, TypeVar
68
+
69
+ from opentelemetry import context as context_api
70
+ from opentelemetry import metrics, trace
71
+ from opentelemetry.propagate import extract, inject
72
+ from repid import ActorData, MessageData, ReceivedMessageT
73
+
74
+ T = TypeVar("T")
75
+
76
+ TRACER = trace.get_tracer(__name__)
77
+ METER = metrics.get_meter(__name__)
78
+
79
+ # Pick the semantic-convention value for your broker, for example
80
+ # "rabbitmq", "kafka", "aws_sqs", or "gcp_pubsub". If none applies, use a
81
+ # stable low-cardinality custom value.
82
+ MESSAGING_SYSTEM = "rabbitmq"
83
+
84
+ # Use operation names that match your broker or client terminology.
85
+ PRODUCER_OPERATION_NAME = "send"
86
+ CONSUMER_OPERATION_NAME = "process"
87
+
88
+ REPID_CONSUMER_MESSAGES = METER.create_counter(
89
+ name="repid.consumer.messages",
90
+ unit="{message}",
91
+ description="The number of messages consumed by Repid actors.",
92
+ )
93
+ REPID_CONSUMER_FAILURES = METER.create_counter(
94
+ name="repid.consumer.failures",
95
+ unit="{message}",
96
+ description="The number of Repid actor message handling failures.",
97
+ )
98
+ REPID_CONSUMER_DURATION = METER.create_histogram(
99
+ name="repid.consumer.processing.duration",
100
+ unit="s",
101
+ description="The time spent handling a consumed Repid message.",
102
+ )
103
+
104
+ REPID_PRODUCER_MESSAGES = METER.create_counter(
105
+ name="repid.producer.messages",
106
+ unit="{message}",
107
+ description="The number of messages published by Repid producers.",
108
+ )
109
+ REPID_PRODUCER_FAILURES = METER.create_counter(
110
+ name="repid.producer.failures",
111
+ unit="{message}",
112
+ description="The number of Repid producer publish failures.",
113
+ )
114
+ REPID_PRODUCER_DURATION = METER.create_histogram(
115
+ name="repid.producer.publish.duration",
116
+ unit="s",
117
+ description="The time spent publishing a Repid message.",
118
+ )
119
+
120
+
121
+ async def consumer_tracing_middleware(
122
+ call_next: Callable[[ReceivedMessageT, ActorData], Coroutine[Any, Any, T]],
123
+ message: ReceivedMessageT,
124
+ actor: ActorData,
125
+ ) -> T:
126
+ span_attributes = {
127
+ "messaging.system": MESSAGING_SYSTEM,
128
+ "messaging.destination.name": message.channel,
129
+ "messaging.operation.type": "process",
130
+ "messaging.operation.name": CONSUMER_OPERATION_NAME,
131
+ "repid.actor.name": actor.name,
132
+ "repid.actor.channel_address": actor.channel_address,
133
+ }
134
+ if message.message_id:
135
+ span_attributes["messaging.message.id"] = message.message_id
136
+
137
+ ctx = extract(message.headers or {})
138
+ token = context_api.attach(ctx)
139
+ try:
140
+ with TRACER.start_as_current_span(
141
+ f"{CONSUMER_OPERATION_NAME} {message.channel}",
142
+ kind=trace.SpanKind.CONSUMER,
143
+ attributes=span_attributes,
144
+ ) as span:
145
+ try:
146
+ return await call_next(message, actor)
147
+ except Exception as exc:
148
+ span.set_attribute("error.type", type(exc).__name__)
149
+ raise
150
+ finally:
151
+ context_api.detach(token)
152
+
153
+
154
+ async def consumer_metrics_middleware(
155
+ call_next: Callable[[ReceivedMessageT, ActorData], Coroutine[Any, Any, T]],
156
+ message: ReceivedMessageT,
157
+ actor: ActorData,
158
+ ) -> T:
159
+ metric_attributes = {
160
+ "messaging.system": MESSAGING_SYSTEM,
161
+ "messaging.destination.name": message.channel,
162
+ "repid.actor.name": actor.name,
163
+ "repid.actor.channel_address": actor.channel_address,
164
+ }
165
+ started_at = perf_counter()
166
+ REPID_CONSUMER_MESSAGES.add(1, attributes=metric_attributes)
167
+
168
+ try:
169
+ return await call_next(message, actor)
170
+ except Exception as exc:
171
+ REPID_CONSUMER_FAILURES.add(
172
+ 1,
173
+ attributes={**metric_attributes, "error.type": type(exc).__name__},
174
+ )
175
+ raise
176
+ finally:
177
+ REPID_CONSUMER_DURATION.record(
178
+ perf_counter() - started_at,
179
+ attributes=metric_attributes,
180
+ )
181
+
182
+
183
+ async def producer_tracing_middleware(
184
+ call_next: Callable[
185
+ [str, MessageData, dict[str, Any] | None],
186
+ Coroutine[Any, Any, T],
187
+ ],
188
+ channel: str,
189
+ message: MessageData,
190
+ server_specific_parameters: dict[str, Any] | None,
191
+ ) -> T:
192
+ span_attributes = {
193
+ "messaging.system": MESSAGING_SYSTEM,
194
+ "messaging.destination.name": channel,
195
+ "messaging.operation.type": "send",
196
+ "messaging.operation.name": PRODUCER_OPERATION_NAME,
197
+ }
198
+
199
+ with TRACER.start_as_current_span(
200
+ f"{PRODUCER_OPERATION_NAME} {channel}",
201
+ kind=trace.SpanKind.PRODUCER,
202
+ attributes=span_attributes,
203
+ ) as span:
204
+ headers = dict(message.headers or {})
205
+ inject(headers)
206
+ replaced_message = replace(message, headers=headers)
207
+
208
+ try:
209
+ return await call_next(channel, replaced_message, server_specific_parameters)
210
+ except Exception as exc:
211
+ span.set_attribute("error.type", type(exc).__name__)
212
+ raise
213
+
214
+
215
+ async def producer_metrics_middleware(
216
+ call_next: Callable[
217
+ [str, MessageData, dict[str, Any] | None],
218
+ Coroutine[Any, Any, T],
219
+ ],
220
+ channel: str,
221
+ message: MessageData,
222
+ server_specific_parameters: dict[str, Any] | None,
223
+ ) -> T:
224
+ metric_attributes = {
225
+ "messaging.system": MESSAGING_SYSTEM,
226
+ "messaging.destination.name": channel,
227
+ }
228
+ started_at = perf_counter()
229
+ REPID_PRODUCER_MESSAGES.add(1, attributes=metric_attributes)
230
+
231
+ try:
232
+ return await call_next(channel, message, server_specific_parameters)
233
+ except Exception as exc:
234
+ REPID_PRODUCER_FAILURES.add(
235
+ 1,
236
+ attributes={**metric_attributes, "error.type": type(exc).__name__},
237
+ )
238
+ raise
239
+ finally:
240
+ REPID_PRODUCER_DURATION.record(
241
+ perf_counter() - started_at,
242
+ attributes=metric_attributes,
243
+ )
244
+ ```
245
+
246
+ !!! note
247
+ Keep metric attributes low-cardinality. Channel names, actor names, and error types are usually
248
+ safe. Message IDs are useful on spans, but should not be added to metrics.
249
+
250
+ ## Registering the Middlewares
251
+
252
+ Lastly, you need to register those middlewares:
253
+
254
+ ```python
255
+ from repid import Repid, Router
256
+
257
+ from my_project.observability import configure_opentelemetry
258
+ from my_project.repid_otel import (
259
+ consumer_metrics_middleware,
260
+ consumer_tracing_middleware,
261
+ producer_metrics_middleware,
262
+ producer_tracing_middleware,
263
+ )
264
+
265
+ configure_opentelemetry(service_name="repid-worker")
266
+
267
+ app = Repid(
268
+ actor_middlewares=[consumer_tracing_middleware, consumer_metrics_middleware],
269
+ producer_middlewares=[producer_tracing_middleware, producer_metrics_middleware],
270
+ )
271
+
272
+ router = Router()
273
+
274
+
275
+ @router.actor(channel="charge_customer")
276
+ async def charge_customer(customer_id: str) -> None:
277
+ print(f"Charging {customer_id}")
278
+
279
+
280
+ app.include_router(router)
281
+ ```
@@ -43,6 +43,7 @@ nav:
43
43
  - Middlewares: cookbook/middlewares.md
44
44
  - Cookbook:
45
45
  - Sentry Middleware: cookbook/sentry_middleware.md
46
+ - OpenTelemetry Middleware: cookbook/opentelemetry_middleware.md
46
47
  - RabbitMQ Retries: cookbook/rabbitmq_retries.md
47
48
  - Large Payloads: cookbook/large_payloads.md
48
49
  - Extending Repid:
@@ -124,6 +125,7 @@ plugins:
124
125
  - cookbook/middlewares.md
125
126
  Cookbook:
126
127
  - cookbook/sentry_middleware.md
128
+ - cookbook/opentelemetry_middleware.md
127
129
  - cookbook/rabbitmq_retries.md
128
130
  - cookbook/large_payloads.md
129
131
  Extending Repid:
@@ -8,7 +8,8 @@ from contextlib import suppress
8
8
  from functools import partial
9
9
  from typing import TYPE_CHECKING, Any
10
10
 
11
- from repid.connections.abc import ServerT, SubscriberT
11
+ from repid.connections.abc import SubscriberT
12
+ from repid.data.actor import ActorExecutionContext
12
13
  from repid.health_check_server import HealthCheckStatus
13
14
 
14
15
  logger = logging.getLogger("repid")
@@ -17,7 +18,6 @@ if TYPE_CHECKING:
17
18
  from repid.connections.abc import ReceivedMessageT
18
19
  from repid.data.actor import ActorData
19
20
  from repid.health_check_server import HealthCheckServer
20
- from repid.serializer import SerializerT
21
21
 
22
22
 
23
23
  ActorResultT = Any
@@ -26,14 +26,12 @@ ActorResultT = Any
26
26
  async def _actor_execution(
27
27
  message: ReceivedMessageT,
28
28
  actor: ActorData,
29
- server: ServerT,
30
- default_serializer: SerializerT,
29
+ actor_context: ActorExecutionContext,
31
30
  ) -> ActorResultT:
32
31
  args, kwargs = await actor.converter.convert_inputs(
33
32
  message=message,
34
33
  actor=actor,
35
- server=server,
36
- default_serializer=default_serializer,
34
+ actor_context=actor_context,
37
35
  )
38
36
  return await actor.fn(*args, **kwargs)
39
37
 
@@ -52,23 +50,22 @@ async def _keep_alive_loop(message: ReceivedMessageT, interval: float) -> None:
52
50
  async def _run_with_keepalive(
53
51
  message: ReceivedMessageT,
54
52
  actor: ActorData,
55
- server: ServerT,
56
- default_serializer: SerializerT,
53
+ actor_context: ActorExecutionContext,
57
54
  ) -> ActorResultT:
58
55
  if actor.keep_alive is False:
59
- return await _actor_execution(message, actor, server, default_serializer)
56
+ return await _actor_execution(message, actor, actor_context)
60
57
 
61
58
  interval = (
62
59
  actor.keep_alive
63
60
  if isinstance(actor.keep_alive, (int, float)) and not isinstance(actor.keep_alive, bool)
64
61
  else message.keep_alive_interval
65
62
  )
66
- if not server.capabilities["supports_keep_alive"] or interval is None:
67
- return await _actor_execution(message, actor, server, default_serializer)
63
+ if not actor_context.server.capabilities["supports_keep_alive"] or interval is None:
64
+ return await _actor_execution(message, actor, actor_context)
68
65
 
69
66
  keepalive_task = asyncio.create_task(_keep_alive_loop(message, interval))
70
67
  try:
71
- return await _actor_execution(message, actor, server, default_serializer)
68
+ return await _actor_execution(message, actor, actor_context)
72
69
  finally:
73
70
  keepalive_task.cancel()
74
71
  with suppress(asyncio.CancelledError):
@@ -78,17 +75,16 @@ async def _run_with_keepalive(
78
75
  async def _actor_execution_with_confirmation( # noqa: C901, PLR0912
79
76
  message: ReceivedMessageT,
80
77
  actor: ActorData,
81
- server: ServerT,
82
- default_serializer: SerializerT,
78
+ actor_context: ActorExecutionContext,
83
79
  ) -> ActorResultT:
84
80
  """Wraps `_actor_execution` to ack/nack the message immediately after the actor fn runs,
85
81
  so middlewares unwinding above this leaf can observe `message.action`."""
86
82
  try:
87
83
  if actor.timeout is None or actor.timeout <= 0 or actor.timeout == float("inf"):
88
- result = await _run_with_keepalive(message, actor, server, default_serializer)
84
+ result = await _run_with_keepalive(message, actor, actor_context)
89
85
  else:
90
86
  result = await asyncio.wait_for(
91
- _run_with_keepalive(message, actor, server, default_serializer),
87
+ _run_with_keepalive(message, actor, actor_context),
92
88
  timeout=actor.timeout,
93
89
  )
94
90
  except Exception as exc:
@@ -131,8 +127,7 @@ async def _actor_execution_with_confirmation( # noqa: C901, PLR0912
131
127
  async def _actor_run(
132
128
  actor: ActorData,
133
129
  message: ReceivedMessageT,
134
- server: ServerT,
135
- default_serializer: SerializerT,
130
+ actor_context: ActorExecutionContext,
136
131
  ) -> ActorResultT | Exception:
137
132
  if (
138
133
  not message.is_acted_on # theoretically a server can automatically ack the message on receive
@@ -151,8 +146,7 @@ async def _actor_run(
151
146
 
152
147
  leaf = partial(
153
148
  _actor_execution_with_confirmation,
154
- server=server,
155
- default_serializer=default_serializer,
149
+ actor_context=actor_context,
156
150
  )
157
151
 
158
152
  try:
@@ -172,13 +166,12 @@ async def _actor_run(
172
166
  async def _actor_run_with_cancel_event_and_callback(
173
167
  actor: ActorData,
174
168
  message: ReceivedMessageT,
175
- server: ServerT,
176
- default_serializer: SerializerT,
169
+ actor_context: ActorExecutionContext,
177
170
  cancel_event: asyncio.Event,
178
171
  cancel_event_task: asyncio.Task,
179
172
  callback: Callable[[], Awaitable],
180
173
  ) -> None:
181
- process_task = asyncio.create_task(_actor_run(actor, message, server, default_serializer))
174
+ process_task = asyncio.create_task(_actor_run(actor, message, actor_context))
182
175
  await asyncio.wait(
183
176
  {cancel_event_task, process_task},
184
177
  return_when=asyncio.FIRST_COMPLETED,
@@ -212,8 +205,8 @@ class _Runner:
212
205
  "_tasks",
213
206
  "_tasks_concurrency_limit",
214
207
  "_unrouted_seen_counts",
208
+ "actor_context",
215
209
  "cancel_event",
216
- "default_serializer",
217
210
  "max_tasks",
218
211
  "max_unrouted_retries",
219
212
  "server",
@@ -223,15 +216,14 @@ class _Runner:
223
216
  def __init__(
224
217
  self,
225
218
  *,
226
- server: ServerT,
219
+ actor_context: ActorExecutionContext,
227
220
  max_tasks: int = float("inf"), # type: ignore[assignment]
228
221
  tasks_concurrency_limit: int = 1000,
229
222
  concurrency_unpause_percent: float = 0.1, # 10 percent
230
223
  health_check_server: HealthCheckServer | None = None,
231
- default_serializer: SerializerT,
232
224
  max_unrouted_retries: int = 10,
233
225
  ):
234
- self.server = server
226
+ self.server = actor_context.server
235
227
  self._server_subscriber: SubscriberT | None = None
236
228
  self._server_subscriber_concurrency_unpause_threshold = max(
237
229
  math.ceil(tasks_concurrency_limit * concurrency_unpause_percent),
@@ -259,7 +251,7 @@ class _Runner:
259
251
 
260
252
  self._health_check_server = health_check_server
261
253
 
262
- self.default_serializer = default_serializer
254
+ self.actor_context = actor_context
263
255
 
264
256
  @property
265
257
  def processed(self) -> int:
@@ -343,8 +335,7 @@ class _Runner:
343
335
  _actor_run_with_cancel_event_and_callback(
344
336
  actor,
345
337
  message,
346
- self.server,
347
- self.default_serializer,
338
+ self.actor_context,
348
339
  self.cancel_event,
349
340
  self.cancel_event_task,
350
341
  self._actor_run_callback,
@@ -9,24 +9,22 @@ from typing import TYPE_CHECKING
9
9
 
10
10
  from repid._runner import _Runner
11
11
  from repid.asyncapi_server import AsyncAPIServer
12
+ from repid.data.actor import ActorExecutionContext
12
13
  from repid.health_check_server import HealthCheckServer
13
14
  from repid.router import Router
14
- from repid.serializer import default_serializer as repid_default_serializer
15
15
 
16
16
  logger = logging.getLogger("repid")
17
17
 
18
18
  if TYPE_CHECKING:
19
19
  from repid.asyncapi import AsyncAPI3Schema
20
20
  from repid.asyncapi_server import AsyncAPIServerSettings
21
- from repid.connections.abc import ServerT
22
21
  from repid.health_check_server import HealthCheckServerSettings
23
- from repid.serializer import SerializerT
24
22
 
25
23
 
26
24
  class _Worker:
27
25
  def __init__(
28
26
  self,
29
- server: ServerT,
27
+ actor_context: ActorExecutionContext,
30
28
  router: Router,
31
29
  graceful_shutdown_time: float = 25.0,
32
30
  messages_limit: int = float("inf"), # type: ignore[assignment]
@@ -35,9 +33,9 @@ class _Worker:
35
33
  health_check_server: HealthCheckServerSettings | None = None,
36
34
  asyncapi_server: AsyncAPIServerSettings | None = None,
37
35
  asyncapi_schema: AsyncAPI3Schema | None = None,
38
- default_serializer: SerializerT | None = None,
39
36
  ):
40
- self.server: ServerT = server
37
+ self.actor_context = actor_context
38
+ self.server = actor_context.server
41
39
  self.centralized_router = router
42
40
 
43
41
  self.tasks_limit: int = tasks_limit
@@ -66,8 +64,6 @@ class _Worker:
66
64
  raise ValueError("AsyncAPI schema is required if AsyncAPI server is enabled.")
67
65
  self.asyncapi_server = AsyncAPIServer(asyncapi_schema, asyncapi_server)
68
66
 
69
- self.default_serializer = default_serializer or repid_default_serializer
70
-
71
67
  async def run(self) -> _Runner:
72
68
  logger.info(
73
69
  "worker.run.start",
@@ -85,11 +81,10 @@ class _Worker:
85
81
  await self.asyncapi_server.start()
86
82
 
87
83
  runner = _Runner(
88
- server=self.server,
84
+ actor_context=self.actor_context,
89
85
  max_tasks=self.messages_limit,
90
86
  tasks_concurrency_limit=self.tasks_limit,
91
87
  health_check_server=self.health_check_server,
92
- default_serializer=self.default_serializer,
93
88
  )
94
89
 
95
90
  if not self.centralized_router.actors:
@@ -4,7 +4,9 @@ import asyncio
4
4
  from collections.abc import Callable, Coroutine, Mapping, Sequence
5
5
  from contextlib import AbstractAsyncContextManager
6
6
  from enum import Enum
7
- from typing import TYPE_CHECKING, Any, Protocol, TypedDict
7
+ from typing import TYPE_CHECKING, Any, Protocol, TypeAlias, TypedDict
8
+
9
+ from repid.data.message import MessageData
8
10
 
9
11
  if TYPE_CHECKING:
10
12
  from repid.asyncapi.models.common import ServerBindingsObject
@@ -37,6 +39,12 @@ class SentMessageT(BaseMessageT, Protocol):
37
39
  pass
38
40
 
39
41
 
42
+ MessagePublisherT: TypeAlias = Callable[
43
+ [str, MessageData, dict[str, Any] | None],
44
+ Coroutine[Any, Any, Any],
45
+ ]
46
+
47
+
40
48
  class ReceivedMessageT(BaseMessageT, Protocol):
41
49
  @property
42
50
  def channel(self) -> str: ...