mersal 0.0.2__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 (271) hide show
  1. mersal-0.0.2/.gitignore +203 -0
  2. mersal-0.0.2/.pre-commit-config.yaml +54 -0
  3. mersal-0.0.2/.python-version +1 -0
  4. mersal-0.0.2/CNAME +1 -0
  5. mersal-0.0.2/CONTRIBUTING.rst +82 -0
  6. mersal-0.0.2/LICENSE +21 -0
  7. mersal-0.0.2/PKG-INFO +155 -0
  8. mersal-0.0.2/README.rst +123 -0
  9. mersal-0.0.2/codecov.yml +11 -0
  10. mersal-0.0.2/mersal/__init__.py +13 -0
  11. mersal-0.0.2/mersal/_activation/builtin_handler_activator.py +108 -0
  12. mersal-0.0.2/mersal/_activation/handler_activator.py +78 -0
  13. mersal-0.0.2/mersal/activation/__init__.py +15 -0
  14. mersal-0.0.2/mersal/app.py +386 -0
  15. mersal-0.0.2/mersal/configuration/__init__.py +3 -0
  16. mersal-0.0.2/mersal/configuration/default_plugin.py +167 -0
  17. mersal-0.0.2/mersal/configuration/dependency_resolver.py +55 -0
  18. mersal-0.0.2/mersal/configuration/standard_configurator.py +67 -0
  19. mersal-0.0.2/mersal/exceptions/__init__.py +11 -0
  20. mersal-0.0.2/mersal/exceptions/base_exceptions.py +49 -0
  21. mersal-0.0.2/mersal/handlers/__init__.py +3 -0
  22. mersal-0.0.2/mersal/handlers/message_handler.py +6 -0
  23. mersal-0.0.2/mersal/idempotency/__init__.py +11 -0
  24. mersal-0.0.2/mersal/idempotency/config.py +25 -0
  25. mersal-0.0.2/mersal/idempotency/const.py +4 -0
  26. mersal-0.0.2/mersal/idempotency/idempotency_checker_step.py +45 -0
  27. mersal-0.0.2/mersal/idempotency/message_tracker.py +17 -0
  28. mersal-0.0.2/mersal/idempotency/plugin.py +35 -0
  29. mersal-0.0.2/mersal/lifespan/__init__.py +4 -0
  30. mersal-0.0.2/mersal/lifespan/autosubscribe/__init__.py +3 -0
  31. mersal-0.0.2/mersal/lifespan/autosubscribe/autosubscribe_plugin.py +59 -0
  32. mersal-0.0.2/mersal/lifespan/default_lifespan_handler.py +15 -0
  33. mersal-0.0.2/mersal/lifespan/lifespan_handler.py +15 -0
  34. mersal-0.0.2/mersal/lifespan/lifespan_hooks_registration_plugin.py +48 -0
  35. mersal-0.0.2/mersal/logging/__init__.py +9 -0
  36. mersal-0.0.2/mersal/logging/config.py +34 -0
  37. mersal-0.0.2/mersal/logging/logger.py +22 -0
  38. mersal-0.0.2/mersal/logging/null_logger.py +45 -0
  39. mersal-0.0.2/mersal/logging/standard_plugin.py +325 -0
  40. mersal-0.0.2/mersal/logging/stdlib/config.py +92 -0
  41. mersal-0.0.2/mersal/logging/stdlib/logger.py +91 -0
  42. mersal-0.0.2/mersal/logging/stdlib/queue.py +32 -0
  43. mersal-0.0.2/mersal/messages/__init__.py +7 -0
  44. mersal-0.0.2/mersal/messages/batch_message.py +8 -0
  45. mersal-0.0.2/mersal/messages/logical_message.py +21 -0
  46. mersal-0.0.2/mersal/messages/message_completed_event.py +9 -0
  47. mersal-0.0.2/mersal/messages/message_completed_event_publisher.py +31 -0
  48. mersal-0.0.2/mersal/messages/message_headers.py +32 -0
  49. mersal-0.0.2/mersal/messages/transport_message.py +21 -0
  50. mersal-0.0.2/mersal/outbox/__init__.py +12 -0
  51. mersal-0.0.2/mersal/outbox/config.py +13 -0
  52. mersal-0.0.2/mersal/outbox/in_memory/__init__.py +5 -0
  53. mersal-0.0.2/mersal/outbox/in_memory/in_memory_outbox_storage.py +44 -0
  54. mersal-0.0.2/mersal/outbox/outbox_forwarder.py +87 -0
  55. mersal-0.0.2/mersal/outbox/outbox_incoming_step.py +20 -0
  56. mersal-0.0.2/mersal/outbox/outbox_message.py +32 -0
  57. mersal-0.0.2/mersal/outbox/outbox_message_batch.py +38 -0
  58. mersal-0.0.2/mersal/outbox/outbox_storage.py +44 -0
  59. mersal-0.0.2/mersal/outbox/outbox_transport_decorator.py +53 -0
  60. mersal-0.0.2/mersal/outbox/plugin.py +80 -0
  61. mersal-0.0.2/mersal/persistence/file_system/__init__.py +11 -0
  62. mersal-0.0.2/mersal/persistence/file_system/file_system_message_tracker.py +25 -0
  63. mersal-0.0.2/mersal/persistence/file_system/file_system_saga_storage.py +160 -0
  64. mersal-0.0.2/mersal/persistence/file_system/file_system_subscription_storage.py +67 -0
  65. mersal-0.0.2/mersal/persistence/in_memory/__init__.py +15 -0
  66. mersal-0.0.2/mersal/persistence/in_memory/in_memory_message_tracker.py +22 -0
  67. mersal-0.0.2/mersal/persistence/in_memory/in_memory_saga_storage.py +99 -0
  68. mersal-0.0.2/mersal/persistence/in_memory/in_memory_subscription_storage.py +59 -0
  69. mersal-0.0.2/mersal/persistence/not_implemented/__init__.py +3 -0
  70. mersal-0.0.2/mersal/persistence/not_implemented/not_implemented_subscription_storage.py +21 -0
  71. mersal-0.0.2/mersal/pipeline/__init__.py +42 -0
  72. mersal-0.0.2/mersal/pipeline/default_pipeline.py +39 -0
  73. mersal-0.0.2/mersal/pipeline/incoming_step.py +11 -0
  74. mersal-0.0.2/mersal/pipeline/incoming_step_context.py +20 -0
  75. mersal-0.0.2/mersal/pipeline/iterative_pipeline_invoker.py +52 -0
  76. mersal-0.0.2/mersal/pipeline/message_context.py +49 -0
  77. mersal-0.0.2/mersal/pipeline/outgoing_step.py +11 -0
  78. mersal-0.0.2/mersal/pipeline/outgoing_step_context.py +20 -0
  79. mersal-0.0.2/mersal/pipeline/pipeline.py +23 -0
  80. mersal-0.0.2/mersal/pipeline/pipeline_injector.py +68 -0
  81. mersal-0.0.2/mersal/pipeline/pipeline_invoker.py +10 -0
  82. mersal-0.0.2/mersal/pipeline/receive/activate_handlers_step.py +70 -0
  83. mersal-0.0.2/mersal/pipeline/receive/deserialize_incoming_message_step.py +21 -0
  84. mersal-0.0.2/mersal/pipeline/receive/dispatch_incoming_message_step.py +24 -0
  85. mersal-0.0.2/mersal/pipeline/receive/handler_invoker.py +32 -0
  86. mersal-0.0.2/mersal/pipeline/receive/handler_invokers.py +24 -0
  87. mersal-0.0.2/mersal/pipeline/receive/saga_handler_invoker.py +26 -0
  88. mersal-0.0.2/mersal/pipeline/recursive_pipeline_invoker.py +47 -0
  89. mersal-0.0.2/mersal/pipeline/send/destination_addresses.py +12 -0
  90. mersal-0.0.2/mersal/pipeline/send/flow_correlation_step.py +71 -0
  91. mersal-0.0.2/mersal/pipeline/send/send_outgoing_message_step.py +23 -0
  92. mersal-0.0.2/mersal/pipeline/send/serialize_outgoing_message_step.py +19 -0
  93. mersal-0.0.2/mersal/pipeline/send/set_default_headers_step.py +37 -0
  94. mersal-0.0.2/mersal/pipeline/step_context.py +29 -0
  95. mersal-0.0.2/mersal/plugins/__init__.py +7 -0
  96. mersal-0.0.2/mersal/plugins/generic_registration_plugin.py +13 -0
  97. mersal-0.0.2/mersal/plugins/plugin.py +9 -0
  98. mersal-0.0.2/mersal/py.typed +0 -0
  99. mersal-0.0.2/mersal/retry/__init__.py +27 -0
  100. mersal-0.0.2/mersal/retry/default_retry_step.py +85 -0
  101. mersal-0.0.2/mersal/retry/default_retry_strategy.py +34 -0
  102. mersal-0.0.2/mersal/retry/error_handling/deadletter_queue_error_handler.py +20 -0
  103. mersal-0.0.2/mersal/retry/error_handling/error_handler.py +15 -0
  104. mersal-0.0.2/mersal/retry/error_tracking/error_tracker.py +16 -0
  105. mersal-0.0.2/mersal/retry/error_tracking/in_memory_error_tracker.py +29 -0
  106. mersal-0.0.2/mersal/retry/fail_fast/default_fail_fast_checker.py +23 -0
  107. mersal-0.0.2/mersal/retry/fail_fast/fail_fast_checker.py +8 -0
  108. mersal-0.0.2/mersal/retry/retry_step.py +8 -0
  109. mersal-0.0.2/mersal/retry/retry_strategy.py +9 -0
  110. mersal-0.0.2/mersal/retry/retry_strategy_settings.py +9 -0
  111. mersal-0.0.2/mersal/routing/__init__.py +7 -0
  112. mersal-0.0.2/mersal/routing/default/__init__.py +9 -0
  113. mersal-0.0.2/mersal/routing/default/config.py +15 -0
  114. mersal-0.0.2/mersal/routing/default/default_router.py +31 -0
  115. mersal-0.0.2/mersal/routing/default/plugin.py +29 -0
  116. mersal-0.0.2/mersal/routing/router.py +9 -0
  117. mersal-0.0.2/mersal/sagas/__init__.py +13 -0
  118. mersal-0.0.2/mersal/sagas/config.py +17 -0
  119. mersal-0.0.2/mersal/sagas/correlation_error_handler.py +21 -0
  120. mersal-0.0.2/mersal/sagas/correlation_property.py +15 -0
  121. mersal-0.0.2/mersal/sagas/correlator.py +32 -0
  122. mersal-0.0.2/mersal/sagas/default_correlation_error_handler.py +29 -0
  123. mersal-0.0.2/mersal/sagas/load_saga_data_step.py +133 -0
  124. mersal-0.0.2/mersal/sagas/plugin.py +56 -0
  125. mersal-0.0.2/mersal/sagas/saga.py +61 -0
  126. mersal-0.0.2/mersal/sagas/saga_data.py +15 -0
  127. mersal-0.0.2/mersal/sagas/saga_storage.py +41 -0
  128. mersal-0.0.2/mersal/serialization/__init__.py +9 -0
  129. mersal-0.0.2/mersal/serialization/dataclass_serializer/__init__.py +3 -0
  130. mersal-0.0.2/mersal/serialization/dataclass_serializer/dataclass_serializer.py +17 -0
  131. mersal-0.0.2/mersal/serialization/identity_serializer/__init__.py +3 -0
  132. mersal-0.0.2/mersal/serialization/identity_serializer/identity_object_serializer.py +13 -0
  133. mersal-0.0.2/mersal/serialization/message_serializer.py +17 -0
  134. mersal-0.0.2/mersal/serialization/serializers.py +13 -0
  135. mersal-0.0.2/mersal/subscription/__init__.py +3 -0
  136. mersal-0.0.2/mersal/subscription/subscription_storage.py +39 -0
  137. mersal-0.0.2/mersal/threading/__init__.py +13 -0
  138. mersal-0.0.2/mersal/threading/anyio/anyio_periodic_async_task.py +49 -0
  139. mersal-0.0.2/mersal/threading/anyio/anyio_periodic_async_task_factory.py +21 -0
  140. mersal-0.0.2/mersal/threading/periodic_async_task.py +9 -0
  141. mersal-0.0.2/mersal/threading/periodic_async_task_factory.py +11 -0
  142. mersal-0.0.2/mersal/topic/__init__.py +4 -0
  143. mersal-0.0.2/mersal/topic/default_topic_name_convention.py +6 -0
  144. mersal-0.0.2/mersal/topic/topic_name_convention.py +9 -0
  145. mersal-0.0.2/mersal/transport/__init__.py +19 -0
  146. mersal-0.0.2/mersal/transport/ambient_context.py +20 -0
  147. mersal-0.0.2/mersal/transport/base_transport.py +41 -0
  148. mersal-0.0.2/mersal/transport/default_transaction_context.py +160 -0
  149. mersal-0.0.2/mersal/transport/default_transaction_context_with_app.py +16 -0
  150. mersal-0.0.2/mersal/transport/file_system/__init__.py +11 -0
  151. mersal-0.0.2/mersal/transport/file_system/file_system_transport.py +127 -0
  152. mersal-0.0.2/mersal/transport/file_system/file_system_transport_plugin.py +48 -0
  153. mersal-0.0.2/mersal/transport/in_memory/__init__.py +10 -0
  154. mersal-0.0.2/mersal/transport/in_memory/in_memory_network.py +32 -0
  155. mersal-0.0.2/mersal/transport/in_memory/in_memory_transport.py +62 -0
  156. mersal-0.0.2/mersal/transport/in_memory/in_memory_transport_plugin.py +59 -0
  157. mersal-0.0.2/mersal/transport/outgoing_message.py +15 -0
  158. mersal-0.0.2/mersal/transport/transaction_context.py +42 -0
  159. mersal-0.0.2/mersal/transport/transaction_scope.py +52 -0
  160. mersal-0.0.2/mersal/transport/transport.py +22 -0
  161. mersal-0.0.2/mersal/transport/transport_bridge.py +49 -0
  162. mersal-0.0.2/mersal/transport/transport_decorator_plugin.py +23 -0
  163. mersal-0.0.2/mersal/types/__init__.py +22 -0
  164. mersal-0.0.2/mersal/types/callable_types.py +14 -0
  165. mersal-0.0.2/mersal/types/helper_types.py +6 -0
  166. mersal-0.0.2/mersal/unit_of_work/__init__.py +17 -0
  167. mersal-0.0.2/mersal/unit_of_work/config.py +49 -0
  168. mersal-0.0.2/mersal/unit_of_work/plugin.py +37 -0
  169. mersal-0.0.2/mersal/unit_of_work/unit_of_work_step.py +88 -0
  170. mersal-0.0.2/mersal/utils/__init__.py +9 -0
  171. mersal-0.0.2/mersal/utils/predicates.py +28 -0
  172. mersal-0.0.2/mersal/utils/retrier.py +24 -0
  173. mersal-0.0.2/mersal/utils/singleton.py +16 -0
  174. mersal-0.0.2/mersal/utils/sync.py +73 -0
  175. mersal-0.0.2/mersal/workers/__init__.py +4 -0
  176. mersal-0.0.2/mersal/workers/anyio/__init__.py +4 -0
  177. mersal-0.0.2/mersal/workers/anyio/anyio_worker.py +138 -0
  178. mersal-0.0.2/mersal/workers/anyio/anyio_worker_factory.py +42 -0
  179. mersal-0.0.2/mersal/workers/worker.py +24 -0
  180. mersal-0.0.2/mersal/workers/worker_factory.py +16 -0
  181. mersal-0.0.2/mise.toml +289 -0
  182. mersal-0.0.2/pyproject.toml +226 -0
  183. mersal-0.0.2/testing/mersal_testing/_internal/conftest.py +70 -0
  184. mersal-0.0.2/testing/mersal_testing/_internal/docker-compose.yml +17 -0
  185. mersal-0.0.2/testing/mersal_testing/app_runner_helper.py +22 -0
  186. mersal-0.0.2/testing/mersal_testing/counter.py +45 -0
  187. mersal-0.0.2/testing/mersal_testing/message_handlers/__init__.py +9 -0
  188. mersal-0.0.2/testing/mersal_testing/message_handlers/message_handler_that_counts.py +14 -0
  189. mersal-0.0.2/testing/mersal_testing/message_handlers/message_handler_that_sends_local_messages.py +32 -0
  190. mersal-0.0.2/testing/mersal_testing/message_handlers/message_handler_that_stores_the_message.py +15 -0
  191. mersal-0.0.2/testing/mersal_testing/message_handlers/message_handler_that_throws.py +13 -0
  192. mersal-0.0.2/testing/mersal_testing/message_handlers/null_message_handler.py +10 -0
  193. mersal-0.0.2/testing/mersal_testing/messages.py +12 -0
  194. mersal-0.0.2/testing/mersal_testing/pipeline/pipeline_invoker_tests.py +138 -0
  195. mersal-0.0.2/testing/mersal_testing/py.typed +2 -0
  196. mersal-0.0.2/testing/mersal_testing/retry/error_tracker_base_tests.py +89 -0
  197. mersal-0.0.2/testing/mersal_testing/test_doubles/__init__.py +31 -0
  198. mersal-0.0.2/testing/mersal_testing/test_doubles/messages/__init__.py +0 -0
  199. mersal-0.0.2/testing/mersal_testing/test_doubles/messages/logical_message_builder.py +52 -0
  200. mersal-0.0.2/testing/mersal_testing/test_doubles/messages/transport_message_builder.py +19 -0
  201. mersal-0.0.2/testing/mersal_testing/test_doubles/outbox/outbox_storage_test_double.py +61 -0
  202. mersal-0.0.2/testing/mersal_testing/test_doubles/retry/error_handler_spy.py +20 -0
  203. mersal-0.0.2/testing/mersal_testing/test_doubles/retry/error_tracker_test_double.py +28 -0
  204. mersal-0.0.2/testing/mersal_testing/test_doubles/serialization/serializer_test_double.py +21 -0
  205. mersal-0.0.2/testing/mersal_testing/test_doubles/transport/outgoing_message_builder.py +10 -0
  206. mersal-0.0.2/testing/mersal_testing/test_doubles/transport/transaction_context_test_double.py +50 -0
  207. mersal-0.0.2/testing/mersal_testing/test_doubles/transport/transport_spy.py +26 -0
  208. mersal-0.0.2/testing/mersal_testing/test_doubles/transport/transport_test_double.py +25 -0
  209. mersal-0.0.2/testing/mersal_testing/test_doubles/unit_of_work/unit_of_work_test_helper.py +24 -0
  210. mersal-0.0.2/testing/mersal_testing/testing_utils.py +11 -0
  211. mersal-0.0.2/testing/mersal_testing/transport/basic_transport_tests.py +173 -0
  212. mersal-0.0.2/testing/mersal_testing/transport/transport_decorator_helper.py +39 -0
  213. mersal-0.0.2/tests/__init__.py +0 -0
  214. mersal-0.0.2/tests/activation/test_builtin_handler_activator.py +88 -0
  215. mersal-0.0.2/tests/conftest.py +30 -0
  216. mersal-0.0.2/tests/idempotency/test_idempotency_checker_step.py +208 -0
  217. mersal-0.0.2/tests/integration/test_app.py +64 -0
  218. mersal-0.0.2/tests/integration/test_basic_receive.py +0 -0
  219. mersal-0.0.2/tests/integration/test_basic_send.py +115 -0
  220. mersal-0.0.2/tests/integration/test_basic_send_and_receive.py +204 -0
  221. mersal-0.0.2/tests/integration/test_idempotency_plugin.py +88 -0
  222. mersal-0.0.2/tests/integration/test_lifespan_plugin.py +86 -0
  223. mersal-0.0.2/tests/integration/test_pub_sub.py +253 -0
  224. mersal-0.0.2/tests/integration/test_receive_with_unit_of_work.py +137 -0
  225. mersal-0.0.2/tests/integration/test_with_autosubscribe_plugin.py +140 -0
  226. mersal-0.0.2/tests/integration/test_with_outbox.py +80 -0
  227. mersal-0.0.2/tests/integration/test_with_saga.py +157 -0
  228. mersal-0.0.2/tests/outbox/test_outbox_forwader.py +130 -0
  229. mersal-0.0.2/tests/outbox/test_outbox_step.py +41 -0
  230. mersal-0.0.2/tests/outbox/test_outbox_transport_decorator.py +118 -0
  231. mersal-0.0.2/tests/persistence/file_system/__init__.py +0 -0
  232. mersal-0.0.2/tests/persistence/file_system/test_file_system_message_tracker.py +48 -0
  233. mersal-0.0.2/tests/persistence/file_system/test_file_system_saga_storage.py +173 -0
  234. mersal-0.0.2/tests/persistence/file_system/test_file_system_subscription_storage.py +47 -0
  235. mersal-0.0.2/tests/persistence/test_in_memory_subscription_storage.py +34 -0
  236. mersal-0.0.2/tests/pipeline/test_activate_handlers_step.py +120 -0
  237. mersal-0.0.2/tests/pipeline/test_deserialize_incoming_message_step.py +38 -0
  238. mersal-0.0.2/tests/pipeline/test_dispatch_incoming_message_step.py +79 -0
  239. mersal-0.0.2/tests/pipeline/test_flow_correlation_step.py +137 -0
  240. mersal-0.0.2/tests/pipeline/test_iterative_pipeline_invoker.py +28 -0
  241. mersal-0.0.2/tests/pipeline/test_pipeline_injector.py +112 -0
  242. mersal-0.0.2/tests/pipeline/test_recursive_pipeline_invoker.py +31 -0
  243. mersal-0.0.2/tests/pipeline/test_send_outgoing_message_step.py +58 -0
  244. mersal-0.0.2/tests/pipeline/test_serialize_outgoing_message_step.py +41 -0
  245. mersal-0.0.2/tests/pipeline/test_set_default_headers_step.py +111 -0
  246. mersal-0.0.2/tests/pipeline/test_stop_invocation.py +46 -0
  247. mersal-0.0.2/tests/profile.py +44 -0
  248. mersal-0.0.2/tests/profile_results +0 -0
  249. mersal-0.0.2/tests/retry/test_deadletter_queue_error_handler.py +37 -0
  250. mersal-0.0.2/tests/retry/test_default_fail_fast_checker.py +26 -0
  251. mersal-0.0.2/tests/retry/test_default_retry_strategy.py +298 -0
  252. mersal-0.0.2/tests/retry/test_in_memory_error_tracker.py +28 -0
  253. mersal-0.0.2/tests/routing/test_default_router.py +37 -0
  254. mersal-0.0.2/tests/sagas/test_default_correlation_handler.py +35 -0
  255. mersal-0.0.2/tests/sagas/test_load_saga_data_step.py +467 -0
  256. mersal-0.0.2/tests/test_default_configurator.py +109 -0
  257. mersal-0.0.2/tests/test_dependency_resolver.py +120 -0
  258. mersal-0.0.2/tests/threading/test_anyio_async_periodic_task_factory.py +28 -0
  259. mersal-0.0.2/tests/transport/file_system/__init__.py +0 -0
  260. mersal-0.0.2/tests/transport/file_system/test_file_system_transport.py +70 -0
  261. mersal-0.0.2/tests/transport/in_memory/test_in_memory_network.py +31 -0
  262. mersal-0.0.2/tests/transport/in_memory/test_in_memory_transport.py +34 -0
  263. mersal-0.0.2/tests/transport/test_ambient_context.py +38 -0
  264. mersal-0.0.2/tests/transport/test_default_transaction_context.py +321 -0
  265. mersal-0.0.2/tests/transport/test_transaction_scope.py +49 -0
  266. mersal-0.0.2/tests/transport/test_transport_bridge.py +60 -0
  267. mersal-0.0.2/tests/unit_of_work/test_unit_of_work_step.py +126 -0
  268. mersal-0.0.2/tests/utils/test_async_retrier.py +67 -0
  269. mersal-0.0.2/tests/workers/test_anyio_worker.py +322 -0
  270. mersal-0.0.2/tools/build_docs.py +87 -0
  271. mersal-0.0.2/uv.lock +2372 -0
@@ -0,0 +1,203 @@
1
+
2
+ # Created by https://www.toptal.com/developers/gitignore/api/python,emacs
3
+ # Edit at https://www.toptal.com/developers/gitignore?templates=python,emacs
4
+
5
+ *.DS_Store
6
+ ### Emacs ###
7
+ # -*- mode: gitignore; -*-
8
+ *~
9
+ \#*\#
10
+ /.emacs.desktop
11
+ /.emacs.desktop.lock
12
+ *.elc
13
+ auto-save-list
14
+ tramp
15
+ .\#*
16
+
17
+ # Org-mode
18
+ .org-id-locations
19
+ *_archive
20
+
21
+ # flymake-mode
22
+ *_flymake.*
23
+
24
+ # eshell files
25
+ /eshell/history
26
+ /eshell/lastdir
27
+
28
+ # elpa packages
29
+ /elpa/
30
+
31
+ # reftex files
32
+ *.rel
33
+
34
+ # AUCTeX auto folder
35
+ /auto/
36
+
37
+ # cask packages
38
+ .cask/
39
+ dist/
40
+
41
+ # Flycheck
42
+ flycheck_*.el
43
+
44
+ # server auth directory
45
+ /server/
46
+
47
+ # projectiles files
48
+ .projectile
49
+
50
+ # directory configuration
51
+ .dir-locals.el
52
+
53
+ # network security
54
+ /network-security.data
55
+
56
+
57
+ ### Python ###
58
+ # Byte-compiled / optimized / DLL files
59
+ __pycache__/
60
+ *.py[cod]
61
+ *$py.class
62
+
63
+ # C extensions
64
+ *.so
65
+
66
+ # Distribution / packaging
67
+ .Python
68
+ build/
69
+ develop-eggs/
70
+ downloads/
71
+ eggs/
72
+ .eggs/
73
+ lib/
74
+ lib64/
75
+ parts/
76
+ sdist/
77
+ var/
78
+ wheels/
79
+ share/python-wheels/
80
+ *.egg-info/
81
+ .installed.cfg
82
+ *.egg
83
+ MANIFEST
84
+
85
+ # PyInstaller
86
+ # Usually these files are written by a python script from a template
87
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
88
+ *.manifest
89
+ *.spec
90
+
91
+ # Installer logs
92
+ pip-log.txt
93
+ pip-delete-this-directory.txt
94
+
95
+ # Unit test / coverage reports
96
+ htmlcov/
97
+ .tox/
98
+ .nox/
99
+ .coverage
100
+ .coverage.*
101
+ .cache
102
+ nosetests.xml
103
+ coverage.xml
104
+ *.cover
105
+ *.py,cover
106
+ .hypothesis/
107
+ .pytest_cache/
108
+ cover/
109
+
110
+ # Translations
111
+ *.mo
112
+ *.pot
113
+
114
+ # Django stuff:
115
+ *.log
116
+ local_settings.py
117
+ db.sqlite3
118
+ db.sqlite3-journal
119
+
120
+ # Flask stuff:
121
+ instance/
122
+ .webassets-cache
123
+
124
+ # Scrapy stuff:
125
+ .scrapy
126
+
127
+ # Sphinx documentation
128
+ docs/_build/
129
+ docs-build/
130
+
131
+ # PyBuilder
132
+ .pybuilder/
133
+ target/
134
+
135
+ # Jupyter Notebook
136
+ .ipynb_checkpoints
137
+
138
+ # IPython
139
+ profile_default/
140
+ ipython_config.py
141
+
142
+ # pyenv
143
+ # For a library or package, you might want to ignore these files since the code is
144
+ # intended to run in multiple environments; otherwise, check them in:
145
+ # .python-version
146
+
147
+ # pipenv
148
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
149
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
150
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
151
+ # install all needed dependencies.
152
+ #Pipfile.lock
153
+
154
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow
155
+ __pypackages__/
156
+
157
+ # Celery stuff
158
+ celerybeat-schedule
159
+ celerybeat.pid
160
+
161
+ # SageMath parsed files
162
+ *.sage.py
163
+
164
+ # Environments
165
+ .env
166
+ .venv
167
+ env/
168
+ venv/
169
+ ENV/
170
+ env.bak/
171
+ venv.bak/
172
+
173
+ # Spyder project settings
174
+ .spyderproject
175
+ .spyproject
176
+
177
+ # Rope project settings
178
+ .ropeproject
179
+
180
+ # mkdocs documentation
181
+ /site
182
+
183
+ # mypy
184
+ .mypy_cache/
185
+ .dmypy.json
186
+ dmypy.json
187
+
188
+ # Pyre type checker
189
+ .pyre/
190
+
191
+ # pytype static type analyzer
192
+ .pytype/
193
+
194
+ # Cython debug symbols
195
+ cython_debug/
196
+
197
+ # End of https://www.toptal.com/developers/gitignore/api/python,emacs
198
+ #
199
+ .projectile-cache.eld
200
+ DOCUMENTATION_STRATEGY.md
201
+ SPACE_MISSION_CONTROL_THEME.md
202
+ LOGO_USAGE_GUIDE.md
203
+ mersal-*.svg
@@ -0,0 +1,54 @@
1
+ ---
2
+ ci:
3
+ autoupdate_schedule: monthly
4
+
5
+ default_language_version:
6
+ python: "3.13"
7
+ repos:
8
+ - repo: https://github.com/compilerla/conventional-pre-commit
9
+ rev: v4.4.0
10
+ hooks:
11
+ - id: conventional-pre-commit
12
+ stages: [commit-msg]
13
+ - repo: https://github.com/pre-commit/pre-commit-hooks
14
+ rev: v6.0.0
15
+ hooks:
16
+ - id: check-ast
17
+ - id: check-case-conflict
18
+ - id: check-toml
19
+ - id: debug-statements
20
+ exclude: ^(mersal/retry/default_retry_step\.py)$
21
+ - id: end-of-file-fixer
22
+ - id: mixed-line-ending
23
+ - id: trailing-whitespace
24
+ - repo: https://github.com/astral-sh/ruff-pre-commit
25
+ rev: v0.16.0
26
+ hooks:
27
+ - id: ruff-check
28
+ args: [--fix, --exit-non-zero-on-fix]
29
+ - id: ruff-format
30
+ - repo: https://github.com/crate-ci/typos
31
+ rev: "v1"
32
+ hooks:
33
+ - id: typos
34
+ - repo: https://github.com/python-formate/flake8-dunder-all
35
+ rev: v0.6.0
36
+ hooks:
37
+ - id: ensure-dunder-all
38
+ exclude: "tools"
39
+ args: ["--use-tuple"]
40
+ - repo: https://github.com/sphinx-contrib/sphinx-lint
41
+ rev: "v1.0.2"
42
+ hooks:
43
+ - id: sphinx-lint
44
+ - repo: https://github.com/abravalheri/validate-pyproject
45
+ rev: v0.25
46
+ hooks:
47
+ - id: validate-pyproject
48
+ # Optional extra validations from SchemaStore:
49
+ additional_dependencies: ["validate-pyproject-schema-store[all]"]
50
+ - repo: https://github.com/econchick/interrogate
51
+ rev: 1.7.0
52
+ hooks:
53
+ - id: interrogate
54
+ args: [tests]
@@ -0,0 +1 @@
1
+ 3.13
mersal-0.0.2/CNAME ADDED
@@ -0,0 +1 @@
1
+ docs.mersal.dev
@@ -0,0 +1,82 @@
1
+ Contributing
2
+ =============
3
+
4
+ Development setup
5
+ ------------------
6
+
7
+ Mersal uses `uv <https://docs.astral.sh/uv/>`_ for dependency management and
8
+ `mise <https://mise.jdx.dev/>`_ to run project tasks.
9
+
10
+ .. code-block:: shell
11
+
12
+ mise run install # create the venv, install deps, install pre-commit hooks
13
+ mise run test # run the test suite
14
+ mise run lint # format + run pre-commit
15
+ mise run type-check # ty + basedpyright + mypy
16
+ mise run docs:serve # live-reloading docs server
17
+
18
+ Run ``mise tasks`` to see everything available.
19
+
20
+ Versioning
21
+ ----------
22
+
23
+ Mersal follows `Semantic Versioning <https://semver.org/>`_.
24
+
25
+ The version number is **never** hand-edited in ``pyproject.toml``. It is
26
+ derived entirely from git tags via `hatch-vcs
27
+ <https://github.com/ofek/hatch-vcs>`_:
28
+
29
+ - On a commit that is exactly a tag (e.g. ``v1.2.3``), the package version is
30
+ ``1.2.3``.
31
+ - On any other commit, the version is a development version derived from the
32
+ most recent tag, e.g. ``1.2.4.dev3`` for the 3rd commit after ``v1.2.3``.
33
+
34
+ This means making a release is just a matter of pushing a tag -- there is no
35
+ version-bump commit or changelog-file merge conflict to manage.
36
+
37
+ Making a release
38
+ -----------------
39
+
40
+ 1. Make sure ``main`` is green (CI passing) and contains everything you want
41
+ to ship.
42
+ 2. Decide the next version per SemVer:
43
+
44
+ - **patch** (``1.2.3`` -> ``1.2.4``): bug fixes only, no API changes.
45
+ - **minor** (``1.2.3`` -> ``1.3.0``): new, backwards-compatible functionality.
46
+ - **major** (``1.2.3`` -> ``2.0.0``): breaking changes.
47
+
48
+ 3. Tag the release and push the tag:
49
+
50
+ .. code-block:: shell
51
+
52
+ git tag v1.2.4
53
+ git push origin v1.2.4
54
+
55
+ 4. Go to `GitHub Releases
56
+ <https://github.com/mersal-org/mersal/releases/new>`_, pick the tag you
57
+ just pushed, click **Generate release notes** (GitHub builds these from
58
+ merged PR titles -- keep PR titles/commits following `Conventional
59
+ Commits <https://www.conventionalcommits.org/>`_, which is already
60
+ enforced by pre-commit), review, and click **Publish release**.
61
+
62
+ 5. Publishing the release triggers `.github/workflows/publish.yml
63
+ <.github/workflows/publish.yml>`_, which builds the package with the
64
+ version baked in from the tag and uploads it to PyPI using `Trusted
65
+ Publishing <https://docs.pypi.org/trusted-publishers/>`_ -- no API tokens
66
+ involved.
67
+
68
+ Continuous pre-releases on Test PyPI
69
+ -------------------------------------
70
+
71
+ Every push to ``main`` (i.e. every merged PR) automatically builds the
72
+ package and uploads it to `Test PyPI
73
+ <https://test.pypi.org/project/mersal/>`_ under its dev version
74
+ (e.g. ``1.2.4.dev3``). This lets you or early adopters install and sanity
75
+ check the very latest ``main`` before it's ever cut into a real release:
76
+
77
+ .. code-block:: shell
78
+
79
+ pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple mersal
80
+
81
+ This mirrors the workflow used by projects like `structlog
82
+ <https://github.com/hynek/structlog/blob/main/.github/workflows/pypi-package.yml>`_.
mersal-0.0.2/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023-present Abdulhaq Emhemmed
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
mersal-0.0.2/PKG-INFO ADDED
@@ -0,0 +1,155 @@
1
+ Metadata-Version: 2.4
2
+ Name: mersal
3
+ Version: 0.0.2
4
+ Summary: A service bus library.
5
+ Project-URL: Homepage, https://github.com/mersal-org/mersal
6
+ Project-URL: Documentation, https://docs.mersal.dev
7
+ Project-URL: Repository, https://github.com/mersal-org/mersal
8
+ Project-URL: Changelog, https://github.com/mersal-org/mersal/releases
9
+ Project-URL: Issue Tracker, https://github.com/mersal-org/mersal/issues
10
+ Author-email: Abdulhaq Emhemmed <abdulhaq.emhemmed@gmail.com>
11
+ License-Expression: MIT
12
+ License-File: LICENSE
13
+ Keywords: async,asyncio,message bus,messaging,sagas,service bus
14
+ Classifier: Development Status :: 5 - Production/Stable
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: Intended Audience :: Information Technology
17
+ Classifier: Intended Audience :: System Administrators
18
+ Classifier: Natural Language :: English
19
+ Classifier: Operating System :: OS Independent
20
+ Classifier: Programming Language :: Python
21
+ Classifier: Programming Language :: Python :: 3.11
22
+ Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Programming Language :: Python :: 3.13
24
+ Classifier: Topic :: Internet
25
+ Classifier: Topic :: Software Development
26
+ Classifier: Topic :: Software Development :: Libraries
27
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
28
+ Classifier: Typing :: Typed
29
+ Requires-Python: >=3.11
30
+ Requires-Dist: anyio>=4.8.0
31
+ Description-Content-Type: text/x-rst
32
+
33
+ Mersal
34
+ =======
35
+
36
+ .. list-table::
37
+ :header-rows: 1
38
+
39
+ * - Project
40
+ - Status
41
+ * - CI/CD
42
+ - .. image:: https://github.com/mersal-org/mersal/actions/workflows/publish.yml/badge.svg
43
+ :target: https://github.com/mersal-org/mersal/actions/workflows/publish.yml
44
+ :alt: Latest Release
45
+ .. image:: https://github.com/mersal-org/mersal/actions/workflows/ci.yml/badge.svg
46
+ :target: https://github.com/mersal-org/mersal/actions/workflows/ci.yml
47
+ :alt: CI
48
+ .. image:: https://github.com/mersal-org/mersal/actions/workflows/docs.yml/badge.svg?branch=main
49
+ :target: https://github.com/mersal-org/mersal/actions/workflows/docs.yml
50
+ :alt: Documentation Building
51
+ * - Quality
52
+ - .. image:: https://codecov.io/github/mersal-org/mersal/graph/badge.svg?token=3219SZABYN
53
+ :target: https://codecov.io/github/mersal-org/mersal
54
+ * - Package
55
+ - .. image:: https://img.shields.io/pypi/v/mersal?labelColor=202235&color=1e4b94&logo=python&logoColor=white
56
+ :target: https://badge.fury.io/py/mersal
57
+ :alt: PyPI - Version
58
+ .. image:: https://img.shields.io/pypi/pyversions/mersal?labelColor=202235&color=1e4b94&logo=python&logoColor=white
59
+ :alt: PyPI - Support Python Versions
60
+ .. image:: https://img.shields.io/pypi/dm/mersal?logo=python&label=package%20downloads&labelColor=202235&color=1e4b94&logoColor=white
61
+ :alt: Mersal PyPI - Downloads
62
+ * - Meta
63
+ - .. image:: https://img.shields.io/badge/license-MIT-202235.svg?logo=python&labelColor=202235&color=1e4b94&logoColor=white
64
+ :target: https://spdx.org/licenses/
65
+ :alt: License - MIT
66
+ .. image:: https://img.shields.io/badge/types-ty-202235.svg?logo=python&labelColor=202235&color=1e4b94&logoColor=white
67
+ :target: https://github.com/astral-sh/ty
68
+ :alt: types - ty
69
+ .. image:: https://img.shields.io/badge/types-Basedpyright-202235.svg?logo=python&labelColor=202235&color=1e4b94&logoColor=white
70
+ :target: https://github.com/DetachHead/basedpyright
71
+ :alt: types - Basedpyright
72
+ .. image:: https://img.shields.io/badge/types-Mypy-202235.svg?logo=python&labelColor=202235&color=1e4b94&logoColor=white
73
+ :target: https://github.com/python/mypy
74
+ :alt: types - Mypy
75
+ .. image:: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/badge/v2.json&labelColor=202235&color=1e4b94
76
+ :target: https://github.com/astral-sh/ruff
77
+ :alt: linting - Ruff
78
+
79
+ **Mersal** is a service bus library for Python. It helps you build message driven systems (a.k.a event driven architecture).
80
+
81
+ There will be more here eventually but here is an LLM summary of core features in Mersal:
82
+
83
+ * **Transport agnostic**: AWS SNS/SQS, GCP Pub/Sub, RabbitMQ, Azure Servicebus, it's your choice!
84
+ * **Pub/sub** - subscribe to events across independently running apps, with
85
+ autosubscribe support so wiring stays out of your way.
86
+ * **Sagas** - coordinate a business process that spans multiple messages
87
+ over time, with pluggable storage for the saga's state.
88
+ * **The outbox pattern** - persist outgoing messages in the same transaction
89
+ as your business data, so a handler's side effects and its database write
90
+ succeed or fail together.
91
+ * **Idempotent handling** - process the same message more than once without
92
+ corrupting state.
93
+ * **Retries and error handling** - configurable retry strategies with
94
+ dead-lettering to an error queue once a message keeps failing, so nothing
95
+ is silently dropped.
96
+ * **A transport bridge** - route messages to specific destinations through a
97
+ different transport than the rest of the system, useful for migrations,
98
+ cost/efficiency tradeoffs, or testing.
99
+ * **Pluggable persistence, and serialization**
100
+ * **Unit of work and a request/response-style pipeline** - hook into message
101
+ handling to add your own cross-cutting behavior, the same way middleware
102
+ works in a web framework.
103
+
104
+ Head to the `quick start <https://docs.mersal.dev/latest/quickstart.html>`_ to
105
+ build a small message-driven system in a few minutes, or the full
106
+ `documentation <https://docs.mersal.dev>`_ for everything else.
107
+
108
+ Acknowledgments ♥
109
+ -------------------
110
+
111
+ This is a personal acknowledgment from myself (@abdulhaq-e), the main author of Mersal.
112
+
113
+ First, to the book `Architecture Patterns with Python
114
+ <https://www.cosmicpython.com/>`_ ("Cosmic Python") and its two authors,
115
+ Harry Percival (@hjwp) and Bob Gregory (@bobthemighty). Its
116
+ impact on my career is substantial and cannot be compared to any other material
117
+ I came by. In addition, the book is why we have Mersal.
118
+
119
+ I was following the book before its official release via its git repository. I
120
+ completed every example, studied all patterns, read all the side material and
121
+ years later, I still go back to it. It is like watching and rewatching a
122
+ favourite TV show! I really recommend anyone who is building systems using
123
+ Python (or any other language actually) to study from this book, especially if
124
+ someone wants to adopt Domain Driven Design (DDD).
125
+
126
+ In Part 2 of the book, the authors introduce the concept of Event Driven
127
+ Architecture and the idea of a "message bus". Once I started building a system
128
+ and applying my learnings, the system message bus was more or less the message
129
+ bus from the book. From one system to the next, the bus was extracted into a
130
+ reusable package and for years it was "pyservicebus". This now brings me to the
131
+ second acknowledgment. Before that, thank you, Harry and Bob, for writing the
132
+ book, and for putting so much effort into it and for writing/releasing it as an
133
+ open book. ♥
134
+
135
+ The current state of Mersal is significantly different than how `pyservicebus`
136
+ looked like. I still have the commits stored somewhere with all the cursing and
137
+ trials. Building a service bus that abstracts transport mechanism isn't an easy
138
+ job. So why not build on the shoulder of giants. While learning more about the
139
+ concept of a message bus, I did come by NServiceBus and they have great learning
140
+ materials regarding the topic and message driven architecture in general.
141
+ NServicebus is OSS but their product is what you can consider as a gigantic
142
+ framework with all batteries included. When looking for inspiration for Mersal,
143
+ I wanted something lighter and that's when I found `Rebus
144
+ <https://github.com/rebus-org>`_, it's a .NET service bus designed to provide a
145
+ "lean" offering. While Mersal might have drifted since, I'd still agree to
146
+ call it the "Python replica of Rebus". Huge thanks to Mogens Heller Grabe
147
+ (@mookid8000), Rebus's core developer, for building and maintaining it so
148
+ well for so long that it was worth learning from and borrowing this much
149
+ from. ♥
150
+
151
+ Finally, a shout out to `Litestar <https://github.com/litestar-org>`_. A
152
+ number of things in Mersal, from small utilities to bigger design decisions,
153
+ were copied or heavily inspired by code in the Litestar organization's
154
+ repositories. Thanks to everyone there for building something worth learning
155
+ from and borrowing from as well.
@@ -0,0 +1,123 @@
1
+ Mersal
2
+ =======
3
+
4
+ .. list-table::
5
+ :header-rows: 1
6
+
7
+ * - Project
8
+ - Status
9
+ * - CI/CD
10
+ - .. image:: https://github.com/mersal-org/mersal/actions/workflows/publish.yml/badge.svg
11
+ :target: https://github.com/mersal-org/mersal/actions/workflows/publish.yml
12
+ :alt: Latest Release
13
+ .. image:: https://github.com/mersal-org/mersal/actions/workflows/ci.yml/badge.svg
14
+ :target: https://github.com/mersal-org/mersal/actions/workflows/ci.yml
15
+ :alt: CI
16
+ .. image:: https://github.com/mersal-org/mersal/actions/workflows/docs.yml/badge.svg?branch=main
17
+ :target: https://github.com/mersal-org/mersal/actions/workflows/docs.yml
18
+ :alt: Documentation Building
19
+ * - Quality
20
+ - .. image:: https://codecov.io/github/mersal-org/mersal/graph/badge.svg?token=3219SZABYN
21
+ :target: https://codecov.io/github/mersal-org/mersal
22
+ * - Package
23
+ - .. image:: https://img.shields.io/pypi/v/mersal?labelColor=202235&color=1e4b94&logo=python&logoColor=white
24
+ :target: https://badge.fury.io/py/mersal
25
+ :alt: PyPI - Version
26
+ .. image:: https://img.shields.io/pypi/pyversions/mersal?labelColor=202235&color=1e4b94&logo=python&logoColor=white
27
+ :alt: PyPI - Support Python Versions
28
+ .. image:: https://img.shields.io/pypi/dm/mersal?logo=python&label=package%20downloads&labelColor=202235&color=1e4b94&logoColor=white
29
+ :alt: Mersal PyPI - Downloads
30
+ * - Meta
31
+ - .. image:: https://img.shields.io/badge/license-MIT-202235.svg?logo=python&labelColor=202235&color=1e4b94&logoColor=white
32
+ :target: https://spdx.org/licenses/
33
+ :alt: License - MIT
34
+ .. image:: https://img.shields.io/badge/types-ty-202235.svg?logo=python&labelColor=202235&color=1e4b94&logoColor=white
35
+ :target: https://github.com/astral-sh/ty
36
+ :alt: types - ty
37
+ .. image:: https://img.shields.io/badge/types-Basedpyright-202235.svg?logo=python&labelColor=202235&color=1e4b94&logoColor=white
38
+ :target: https://github.com/DetachHead/basedpyright
39
+ :alt: types - Basedpyright
40
+ .. image:: https://img.shields.io/badge/types-Mypy-202235.svg?logo=python&labelColor=202235&color=1e4b94&logoColor=white
41
+ :target: https://github.com/python/mypy
42
+ :alt: types - Mypy
43
+ .. image:: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/badge/v2.json&labelColor=202235&color=1e4b94
44
+ :target: https://github.com/astral-sh/ruff
45
+ :alt: linting - Ruff
46
+
47
+ **Mersal** is a service bus library for Python. It helps you build message driven systems (a.k.a event driven architecture).
48
+
49
+ There will be more here eventually but here is an LLM summary of core features in Mersal:
50
+
51
+ * **Transport agnostic**: AWS SNS/SQS, GCP Pub/Sub, RabbitMQ, Azure Servicebus, it's your choice!
52
+ * **Pub/sub** - subscribe to events across independently running apps, with
53
+ autosubscribe support so wiring stays out of your way.
54
+ * **Sagas** - coordinate a business process that spans multiple messages
55
+ over time, with pluggable storage for the saga's state.
56
+ * **The outbox pattern** - persist outgoing messages in the same transaction
57
+ as your business data, so a handler's side effects and its database write
58
+ succeed or fail together.
59
+ * **Idempotent handling** - process the same message more than once without
60
+ corrupting state.
61
+ * **Retries and error handling** - configurable retry strategies with
62
+ dead-lettering to an error queue once a message keeps failing, so nothing
63
+ is silently dropped.
64
+ * **A transport bridge** - route messages to specific destinations through a
65
+ different transport than the rest of the system, useful for migrations,
66
+ cost/efficiency tradeoffs, or testing.
67
+ * **Pluggable persistence, and serialization**
68
+ * **Unit of work and a request/response-style pipeline** - hook into message
69
+ handling to add your own cross-cutting behavior, the same way middleware
70
+ works in a web framework.
71
+
72
+ Head to the `quick start <https://docs.mersal.dev/latest/quickstart.html>`_ to
73
+ build a small message-driven system in a few minutes, or the full
74
+ `documentation <https://docs.mersal.dev>`_ for everything else.
75
+
76
+ Acknowledgments ♥
77
+ -------------------
78
+
79
+ This is a personal acknowledgment from myself (@abdulhaq-e), the main author of Mersal.
80
+
81
+ First, to the book `Architecture Patterns with Python
82
+ <https://www.cosmicpython.com/>`_ ("Cosmic Python") and its two authors,
83
+ Harry Percival (@hjwp) and Bob Gregory (@bobthemighty). Its
84
+ impact on my career is substantial and cannot be compared to any other material
85
+ I came by. In addition, the book is why we have Mersal.
86
+
87
+ I was following the book before its official release via its git repository. I
88
+ completed every example, studied all patterns, read all the side material and
89
+ years later, I still go back to it. It is like watching and rewatching a
90
+ favourite TV show! I really recommend anyone who is building systems using
91
+ Python (or any other language actually) to study from this book, especially if
92
+ someone wants to adopt Domain Driven Design (DDD).
93
+
94
+ In Part 2 of the book, the authors introduce the concept of Event Driven
95
+ Architecture and the idea of a "message bus". Once I started building a system
96
+ and applying my learnings, the system message bus was more or less the message
97
+ bus from the book. From one system to the next, the bus was extracted into a
98
+ reusable package and for years it was "pyservicebus". This now brings me to the
99
+ second acknowledgment. Before that, thank you, Harry and Bob, for writing the
100
+ book, and for putting so much effort into it and for writing/releasing it as an
101
+ open book. ♥
102
+
103
+ The current state of Mersal is significantly different than how `pyservicebus`
104
+ looked like. I still have the commits stored somewhere with all the cursing and
105
+ trials. Building a service bus that abstracts transport mechanism isn't an easy
106
+ job. So why not build on the shoulder of giants. While learning more about the
107
+ concept of a message bus, I did come by NServiceBus and they have great learning
108
+ materials regarding the topic and message driven architecture in general.
109
+ NServicebus is OSS but their product is what you can consider as a gigantic
110
+ framework with all batteries included. When looking for inspiration for Mersal,
111
+ I wanted something lighter and that's when I found `Rebus
112
+ <https://github.com/rebus-org>`_, it's a .NET service bus designed to provide a
113
+ "lean" offering. While Mersal might have drifted since, I'd still agree to
114
+ call it the "Python replica of Rebus". Huge thanks to Mogens Heller Grabe
115
+ (@mookid8000), Rebus's core developer, for building and maintaining it so
116
+ well for so long that it was worth learning from and borrowing this much
117
+ from. ♥
118
+
119
+ Finally, a shout out to `Litestar <https://github.com/litestar-org>`_. A
120
+ number of things in Mersal, from small utilities to bigger design decisions,
121
+ were copied or heavily inspired by code in the Litestar organization's
122
+ repositories. Thanks to everyone there for building something worth learning
123
+ from and borrowing from as well.
@@ -0,0 +1,11 @@
1
+ coverage:
2
+ status:
3
+ project:
4
+ default:
5
+ target: auto
6
+ threshold: 0.1%
7
+ patch:
8
+ default:
9
+ target: auto
10
+ comment:
11
+ require_changes: true
@@ -0,0 +1,13 @@
1
+ from importlib.metadata import version
2
+
3
+ from mersal.logging import Logger, LoggingConfig
4
+
5
+ __all__ = ["Logger", "LoggingConfig"]
6
+
7
+
8
+ def __getattr__(name: str) -> str:
9
+ if name != "__version__":
10
+ msg = f"module {__name__!r} has no attribute {name!r}"
11
+ raise AttributeError(msg)
12
+
13
+ return version("mersal")