eventsource-py 0.2.0__tar.gz → 0.3.0__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 (445) hide show
  1. eventsource_py-0.3.0/CHANGELOG.md +372 -0
  2. eventsource_py-0.3.0/PKG-INFO +273 -0
  3. eventsource_py-0.3.0/README.md +203 -0
  4. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/docs/adrs/0004-projection-error-handling.md +55 -56
  5. eventsource_py-0.3.0/docs/api/aggregates.md +548 -0
  6. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/docs/api/bus.md +109 -26
  7. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/docs/api/index.md +104 -1
  8. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/docs/api/observability.md +30 -0
  9. eventsource_py-0.3.0/docs/api/projections.md +777 -0
  10. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/docs/api/snapshots.md +127 -15
  11. eventsource_py-0.3.0/docs/api/stores.md +1252 -0
  12. eventsource_py-0.3.0/docs/api/subscriptions.md +2155 -0
  13. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/docs/architecture.md +30 -11
  14. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/docs/development/code-structure.md +1 -1
  15. eventsource_py-0.3.0/docs/examples/projections.md +407 -0
  16. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/docs/examples/sqlite-usage.md +35 -8
  17. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/docs/faq.md +138 -9
  18. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/docs/getting-started.md +64 -27
  19. eventsource_py-0.3.0/docs/guides/event-bus.md +391 -0
  20. eventsource_py-0.3.0/docs/guides/kubernetes-deployment.md +1065 -0
  21. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/docs/guides/observability.md +267 -48
  22. eventsource_py-0.3.0/docs/guides/repository-pattern.md +633 -0
  23. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/docs/guides/snapshotting-migration.md +21 -13
  24. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/docs/guides/snapshotting.md +12 -4
  25. eventsource_py-0.3.0/docs/guides/subscription-migration.md +433 -0
  26. eventsource_py-0.3.0/docs/guides/subscriptions.md +683 -0
  27. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/docs/index.md +4 -0
  28. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/docs/installation.md +1 -0
  29. eventsource_py-0.3.0/docs/migration/README.md +123 -0
  30. eventsource_py-0.3.0/docs/migration/api-reference.md +712 -0
  31. eventsource_py-0.3.0/docs/migration/architecture.md +311 -0
  32. eventsource_py-0.3.0/docs/migration/migration-guide.md +488 -0
  33. eventsource_py-0.3.0/docs/migration/monitoring.md +596 -0
  34. eventsource_py-0.3.0/docs/migration/runbook.md +610 -0
  35. eventsource_py-0.3.0/docs/migration/troubleshooting.md +603 -0
  36. eventsource_py-0.3.0/docs/tutorials/01-introduction.md +149 -0
  37. eventsource_py-0.3.0/docs/tutorials/02-first-event.md +243 -0
  38. eventsource_py-0.3.0/docs/tutorials/03-first-aggregate.md +425 -0
  39. eventsource_py-0.3.0/docs/tutorials/04-event-stores.md +263 -0
  40. eventsource_py-0.3.0/docs/tutorials/05-repositories.md +315 -0
  41. eventsource_py-0.3.0/docs/tutorials/06-projections.md +291 -0
  42. eventsource_py-0.3.0/docs/tutorials/07-event-bus.md +296 -0
  43. eventsource_py-0.3.0/docs/tutorials/08-testing.md +487 -0
  44. eventsource_py-0.3.0/docs/tutorials/09-error-handling.md +344 -0
  45. eventsource_py-0.3.0/docs/tutorials/10-checkpoints.md +127 -0
  46. eventsource_py-0.3.0/docs/tutorials/11-postgresql.md +456 -0
  47. eventsource_py-0.3.0/docs/tutorials/12-sqlite.md +545 -0
  48. eventsource_py-0.3.0/docs/tutorials/13-subscriptions.md +659 -0
  49. eventsource_py-0.3.0/docs/tutorials/14-snapshotting.md +340 -0
  50. eventsource_py-0.3.0/docs/tutorials/15-production.md +770 -0
  51. eventsource_py-0.3.0/docs/tutorials/16-multi-tenancy.md +502 -0
  52. eventsource_py-0.3.0/docs/tutorials/17-redis.md +642 -0
  53. eventsource_py-0.3.0/docs/tutorials/18-kafka.md +601 -0
  54. eventsource_py-0.3.0/docs/tutorials/19-rabbitmq.md +865 -0
  55. eventsource_py-0.3.0/docs/tutorials/20-observability.md +680 -0
  56. eventsource_py-0.3.0/docs/tutorials/21-advanced-aggregates.md +2323 -0
  57. eventsource_py-0.3.0/docs/tutorials/exercises/solutions/04-1.py +144 -0
  58. eventsource_py-0.3.0/docs/tutorials/exercises/solutions/05-1.py +188 -0
  59. eventsource_py-0.3.0/docs/tutorials/exercises/solutions/06-1.py +309 -0
  60. eventsource_py-0.3.0/docs/tutorials/exercises/solutions/07-1.py +206 -0
  61. eventsource_py-0.3.0/docs/tutorials/exercises/solutions/08-1.py +515 -0
  62. eventsource_py-0.3.0/docs/tutorials/exercises/solutions/09-1.py +199 -0
  63. eventsource_py-0.3.0/docs/tutorials/exercises/solutions/10-1.py +257 -0
  64. eventsource_py-0.3.0/docs/tutorials/exercises/solutions/11-1.py +325 -0
  65. eventsource_py-0.3.0/docs/tutorials/exercises/solutions/12-1.py +340 -0
  66. eventsource_py-0.3.0/docs/tutorials/exercises/solutions/13-1.py +337 -0
  67. eventsource_py-0.3.0/docs/tutorials/exercises/solutions/14-1.py +144 -0
  68. eventsource_py-0.3.0/docs/tutorials/exercises/solutions/16-1.py +477 -0
  69. eventsource_py-0.3.0/docs/tutorials/exercises/solutions/18-1.py +270 -0
  70. eventsource_py-0.3.0/docs/tutorials/exercises/solutions/19-1.py +336 -0
  71. eventsource_py-0.3.0/docs/tutorials/exercises/solutions/20-1.py +350 -0
  72. eventsource_py-0.3.0/docs/tutorials/exercises/solutions/21-1.py +1022 -0
  73. eventsource_py-0.3.0/docs/tutorials/index.md +216 -0
  74. eventsource_py-0.3.0/examples/projection_example.py +600 -0
  75. eventsource_py-0.3.0/examples/subscriptions/README.md +331 -0
  76. eventsource_py-0.3.0/examples/subscriptions/__init__.py +14 -0
  77. eventsource_py-0.3.0/examples/subscriptions/basic_projection.py +450 -0
  78. eventsource_py-0.3.0/examples/subscriptions/multi_subscriber.py +766 -0
  79. eventsource_py-0.3.0/examples/subscriptions/resilient_projection.py +539 -0
  80. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/mkdocs.yml +28 -2
  81. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/pyproject.toml +4 -2
  82. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/__init__.py +5 -0
  83. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/aggregates/repository.py +41 -237
  84. eventsource_py-0.3.0/src/eventsource/aggregates/snapshot_manager.py +320 -0
  85. eventsource_py-0.3.0/src/eventsource/aggregates/task_manager.py +210 -0
  86. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/bus/kafka.py +640 -207
  87. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/bus/memory.py +41 -103
  88. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/bus/rabbitmq.py +120 -142
  89. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/bus/redis.py +37 -99
  90. eventsource_py-0.3.0/src/eventsource/handlers/__init__.py +48 -0
  91. eventsource_py-0.3.0/src/eventsource/handlers/adapter.py +205 -0
  92. eventsource_py-0.3.0/src/eventsource/handlers/registry.py +419 -0
  93. eventsource_py-0.3.0/src/eventsource/locks/__init__.py +48 -0
  94. eventsource_py-0.3.0/src/eventsource/locks/postgresql.py +520 -0
  95. eventsource_py-0.3.0/src/eventsource/migration/__init__.py +201 -0
  96. eventsource_py-0.3.0/src/eventsource/migration/bulk_copier.py +591 -0
  97. eventsource_py-0.3.0/src/eventsource/migration/consistency.py +850 -0
  98. eventsource_py-0.3.0/src/eventsource/migration/coordinator.py +1692 -0
  99. eventsource_py-0.3.0/src/eventsource/migration/cutover.py +596 -0
  100. eventsource_py-0.3.0/src/eventsource/migration/dual_write.py +532 -0
  101. eventsource_py-0.3.0/src/eventsource/migration/exceptions.py +1516 -0
  102. eventsource_py-0.3.0/src/eventsource/migration/metrics.py +818 -0
  103. eventsource_py-0.3.0/src/eventsource/migration/models.py +1144 -0
  104. eventsource_py-0.3.0/src/eventsource/migration/position_mapper.py +639 -0
  105. eventsource_py-0.3.0/src/eventsource/migration/repositories/__init__.py +73 -0
  106. eventsource_py-0.3.0/src/eventsource/migration/repositories/audit_log.py +510 -0
  107. eventsource_py-0.3.0/src/eventsource/migration/repositories/migration.py +831 -0
  108. eventsource_py-0.3.0/src/eventsource/migration/repositories/position_mapping.py +899 -0
  109. eventsource_py-0.3.0/src/eventsource/migration/repositories/routing.py +683 -0
  110. eventsource_py-0.3.0/src/eventsource/migration/router.py +772 -0
  111. eventsource_py-0.3.0/src/eventsource/migration/status_streamer.py +525 -0
  112. eventsource_py-0.3.0/src/eventsource/migration/subscription_migrator.py +875 -0
  113. eventsource_py-0.3.0/src/eventsource/migration/sync_lag_tracker.py +526 -0
  114. eventsource_py-0.3.0/src/eventsource/migration/write_pause.py +533 -0
  115. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/migrations/__init__.py +3 -0
  116. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/migrations/schemas/all.sql +2 -0
  117. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/migrations/schemas/sqlite_all.sql +1 -0
  118. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/migrations/templates/checkpoints.sql +11 -0
  119. eventsource_py-0.3.0/src/eventsource/migrations/templates/migration.sql +320 -0
  120. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/migrations/templates/sqlite/checkpoints.sql +4 -0
  121. eventsource_py-0.3.0/src/eventsource/migrations/updates/001_add_global_position.sql +38 -0
  122. eventsource_py-0.3.0/src/eventsource/migrations/updates/001_add_global_position_sqlite.sql +18 -0
  123. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/observability/__init__.py +56 -0
  124. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/observability/attributes.py +136 -0
  125. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/projections/base.py +133 -256
  126. eventsource_py-0.3.0/src/eventsource/projections/checkpoint_manager.py +227 -0
  127. eventsource_py-0.3.0/src/eventsource/projections/dlq_manager.py +214 -0
  128. eventsource_py-0.3.0/src/eventsource/projections/retry.py +288 -0
  129. eventsource_py-0.3.0/src/eventsource/readmodels/__init__.py +113 -0
  130. eventsource_py-0.3.0/src/eventsource/readmodels/base.py +251 -0
  131. eventsource_py-0.3.0/src/eventsource/readmodels/exceptions.py +123 -0
  132. eventsource_py-0.3.0/src/eventsource/readmodels/in_memory.py +537 -0
  133. eventsource_py-0.3.0/src/eventsource/readmodels/postgresql.py +781 -0
  134. eventsource_py-0.3.0/src/eventsource/readmodels/projection.py +351 -0
  135. eventsource_py-0.3.0/src/eventsource/readmodels/query.py +362 -0
  136. eventsource_py-0.3.0/src/eventsource/readmodels/repository.py +402 -0
  137. eventsource_py-0.3.0/src/eventsource/readmodels/schema.py +462 -0
  138. eventsource_py-0.3.0/src/eventsource/readmodels/sqlite.py +852 -0
  139. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/repositories/checkpoint.py +272 -2
  140. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/repositories/dlq.py +116 -97
  141. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/repositories/outbox.py +110 -73
  142. eventsource_py-0.3.0/src/eventsource/snapshots/strategies.py +450 -0
  143. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/stores/__init__.py +11 -0
  144. eventsource_py-0.3.0/src/eventsource/stores/_type_converter.py +317 -0
  145. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/stores/in_memory.py +18 -1
  146. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/stores/interface.py +35 -1
  147. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/stores/postgresql.py +54 -124
  148. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/stores/sqlite.py +111 -66
  149. eventsource_py-0.3.0/src/eventsource/subscriptions/__init__.py +345 -0
  150. eventsource_py-0.3.0/src/eventsource/subscriptions/config.py +285 -0
  151. eventsource_py-0.3.0/src/eventsource/subscriptions/coordination.py +1419 -0
  152. eventsource_py-0.3.0/src/eventsource/subscriptions/error_handling.py +1043 -0
  153. eventsource_py-0.3.0/src/eventsource/subscriptions/exceptions.py +62 -0
  154. eventsource_py-0.3.0/src/eventsource/subscriptions/filtering.py +484 -0
  155. eventsource_py-0.3.0/src/eventsource/subscriptions/flow_control.py +438 -0
  156. eventsource_py-0.3.0/src/eventsource/subscriptions/health.py +872 -0
  157. eventsource_py-0.3.0/src/eventsource/subscriptions/health_provider.py +551 -0
  158. eventsource_py-0.3.0/src/eventsource/subscriptions/lifecycle.py +364 -0
  159. eventsource_py-0.3.0/src/eventsource/subscriptions/manager.py +1283 -0
  160. eventsource_py-0.3.0/src/eventsource/subscriptions/metrics.py +571 -0
  161. eventsource_py-0.3.0/src/eventsource/subscriptions/pause_resume.py +278 -0
  162. eventsource_py-0.3.0/src/eventsource/subscriptions/registry.py +186 -0
  163. eventsource_py-0.3.0/src/eventsource/subscriptions/retry.py +643 -0
  164. eventsource_py-0.3.0/src/eventsource/subscriptions/runners/__init__.py +19 -0
  165. eventsource_py-0.3.0/src/eventsource/subscriptions/runners/catchup.py +648 -0
  166. eventsource_py-0.3.0/src/eventsource/subscriptions/runners/live.py +783 -0
  167. eventsource_py-0.3.0/src/eventsource/subscriptions/shutdown.py +1535 -0
  168. eventsource_py-0.3.0/src/eventsource/subscriptions/subscriber.py +468 -0
  169. eventsource_py-0.3.0/src/eventsource/subscriptions/subscription.py +754 -0
  170. eventsource_py-0.3.0/src/eventsource/subscriptions/transition.py +555 -0
  171. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/conftest.py +2 -1
  172. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/integration/bus/test_kafka.py +5 -0
  173. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/integration/bus/test_rabbitmq.py +10 -0
  174. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/integration/conftest.py +1 -0
  175. eventsource_py-0.3.0/tests/integration/locks/__init__.py +1 -0
  176. eventsource_py-0.3.0/tests/integration/locks/test_postgresql_locks_integration.py +450 -0
  177. eventsource_py-0.3.0/tests/integration/migrations/__init__.py +1 -0
  178. eventsource_py-0.3.0/tests/integration/migrations/test_migration_schema_postgresql.py +830 -0
  179. eventsource_py-0.3.0/tests/integration/readmodels/__init__.py +6 -0
  180. eventsource_py-0.3.0/tests/integration/readmodels/conftest.py +190 -0
  181. eventsource_py-0.3.0/tests/integration/readmodels/test_enhanced_features.py +851 -0
  182. eventsource_py-0.3.0/tests/integration/readmodels/test_projection.py +1242 -0
  183. eventsource_py-0.3.0/tests/integration/readmodels/test_repositories.py +914 -0
  184. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/integration/repositories/test_dlq.py +14 -14
  185. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/integration/repositories/test_outbox.py +10 -10
  186. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/integration/stores/test_postgresql.py +154 -0
  187. eventsource_py-0.3.0/tests/integration/subscriptions/__init__.py +11 -0
  188. eventsource_py-0.3.0/tests/integration/subscriptions/conftest.py +371 -0
  189. eventsource_py-0.3.0/tests/integration/subscriptions/test_advanced_features.py +1505 -0
  190. eventsource_py-0.3.0/tests/integration/subscriptions/test_catchup.py +368 -0
  191. eventsource_py-0.3.0/tests/integration/subscriptions/test_full_flow.py +664 -0
  192. eventsource_py-0.3.0/tests/integration/subscriptions/test_live.py +395 -0
  193. eventsource_py-0.3.0/tests/integration/subscriptions/test_resilience.py +1459 -0
  194. eventsource_py-0.3.0/tests/integration/subscriptions/test_transition.py +377 -0
  195. eventsource_py-0.3.0/tests/locks/__init__.py +1 -0
  196. eventsource_py-0.3.0/tests/locks/test_postgresql_locks.py +188 -0
  197. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/repositories/test_sqlite_repos.py +66 -66
  198. eventsource_py-0.3.0/tests/stores/test_read_all_tenant_filter.py +437 -0
  199. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/unit/aggregates/test_repository_snapshot.py +34 -58
  200. eventsource_py-0.3.0/tests/unit/migration/__init__.py +1 -0
  201. eventsource_py-0.3.0/tests/unit/migration/test_audit_log_repository.py +885 -0
  202. eventsource_py-0.3.0/tests/unit/migration/test_bulk_copier.py +945 -0
  203. eventsource_py-0.3.0/tests/unit/migration/test_chaos.py +1812 -0
  204. eventsource_py-0.3.0/tests/unit/migration/test_consistency_verifier.py +1077 -0
  205. eventsource_py-0.3.0/tests/unit/migration/test_coordinator.py +1140 -0
  206. eventsource_py-0.3.0/tests/unit/migration/test_coordinator_dual_write.py +986 -0
  207. eventsource_py-0.3.0/tests/unit/migration/test_coordinator_subscriptions.py +986 -0
  208. eventsource_py-0.3.0/tests/unit/migration/test_cutover_manager.py +1340 -0
  209. eventsource_py-0.3.0/tests/unit/migration/test_dual_write.py +888 -0
  210. eventsource_py-0.3.0/tests/unit/migration/test_error_classification.py +874 -0
  211. eventsource_py-0.3.0/tests/unit/migration/test_exceptions.py +480 -0
  212. eventsource_py-0.3.0/tests/unit/migration/test_final_integration.py +2302 -0
  213. eventsource_py-0.3.0/tests/unit/migration/test_load_benchmarks.py +1484 -0
  214. eventsource_py-0.3.0/tests/unit/migration/test_migration_metrics.py +964 -0
  215. eventsource_py-0.3.0/tests/unit/migration/test_migration_repository.py +1044 -0
  216. eventsource_py-0.3.0/tests/unit/migration/test_models.py +1071 -0
  217. eventsource_py-0.3.0/tests/unit/migration/test_phase2_integration.py +1771 -0
  218. eventsource_py-0.3.0/tests/unit/migration/test_phase3_integration.py +2193 -0
  219. eventsource_py-0.3.0/tests/unit/migration/test_position_mapper.py +904 -0
  220. eventsource_py-0.3.0/tests/unit/migration/test_position_mapping_repository.py +1102 -0
  221. eventsource_py-0.3.0/tests/unit/migration/test_router.py +1350 -0
  222. eventsource_py-0.3.0/tests/unit/migration/test_routing_repository.py +1023 -0
  223. eventsource_py-0.3.0/tests/unit/migration/test_status_streamer.py +963 -0
  224. eventsource_py-0.3.0/tests/unit/migration/test_subscription_migrator.py +1108 -0
  225. eventsource_py-0.3.0/tests/unit/migration/test_sync_lag_tracker.py +1027 -0
  226. eventsource_py-0.3.0/tests/unit/migration/test_write_pause.py +876 -0
  227. eventsource_py-0.3.0/tests/unit/migrations/test_migration_schema.py +427 -0
  228. eventsource_py-0.3.0/tests/unit/readmodels/__init__.py +1 -0
  229. eventsource_py-0.3.0/tests/unit/readmodels/test_base.py +324 -0
  230. eventsource_py-0.3.0/tests/unit/readmodels/test_exports.py +90 -0
  231. eventsource_py-0.3.0/tests/unit/readmodels/test_handler_integration.py +445 -0
  232. eventsource_py-0.3.0/tests/unit/readmodels/test_in_memory.py +948 -0
  233. eventsource_py-0.3.0/tests/unit/readmodels/test_optimistic_locking.py +346 -0
  234. eventsource_py-0.3.0/tests/unit/readmodels/test_postgresql.py +531 -0
  235. eventsource_py-0.3.0/tests/unit/readmodels/test_projection.py +856 -0
  236. eventsource_py-0.3.0/tests/unit/readmodels/test_query.py +317 -0
  237. eventsource_py-0.3.0/tests/unit/readmodels/test_repository_protocol.py +108 -0
  238. eventsource_py-0.3.0/tests/unit/readmodels/test_schema.py +631 -0
  239. eventsource_py-0.3.0/tests/unit/readmodels/test_soft_delete.py +525 -0
  240. eventsource_py-0.3.0/tests/unit/readmodels/test_sqlite.py +698 -0
  241. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/unit/repositories/test_checkpoint_tracing.py +3 -0
  242. eventsource_py-0.3.0/tests/unit/stores/test_type_converter.py +333 -0
  243. eventsource_py-0.3.0/tests/unit/subscriptions/__init__.py +1 -0
  244. eventsource_py-0.3.0/tests/unit/subscriptions/test_backpressure.py +670 -0
  245. eventsource_py-0.3.0/tests/unit/subscriptions/test_coordination.py +1629 -0
  246. eventsource_py-0.3.0/tests/unit/subscriptions/test_drain.py +744 -0
  247. eventsource_py-0.3.0/tests/unit/subscriptions/test_error_handling.py +840 -0
  248. eventsource_py-0.3.0/tests/unit/subscriptions/test_filtering.py +713 -0
  249. eventsource_py-0.3.0/tests/unit/subscriptions/test_health.py +981 -0
  250. eventsource_py-0.3.0/tests/unit/subscriptions/test_health_api.py +472 -0
  251. eventsource_py-0.3.0/tests/unit/subscriptions/test_manager_pause_resume.py +678 -0
  252. eventsource_py-0.3.0/tests/unit/subscriptions/test_metrics.py +689 -0
  253. eventsource_py-0.3.0/tests/unit/subscriptions/test_pause_resume.py +557 -0
  254. eventsource_py-0.3.0/tests/unit/subscriptions/test_retry.py +889 -0
  255. eventsource_py-0.3.0/tests/unit/subscriptions/test_shutdown.py +2720 -0
  256. eventsource_py-0.3.0/tests/unit/subscriptions/test_subscriber.py +832 -0
  257. eventsource_py-0.3.0/tests/unit/subscriptions/test_subscription_state.py +1105 -0
  258. eventsource_py-0.3.0/tests/unit/subscriptions/test_tenant_filtering.py +459 -0
  259. eventsource_py-0.3.0/tests/unit/test_catchup_runner.py +831 -0
  260. eventsource_py-0.3.0/tests/unit/test_checkpoint_position.py +484 -0
  261. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/unit/test_checkpoint_repository.py +2 -0
  262. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/unit/test_dlq_repository.py +64 -64
  263. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/unit/test_edge_cases.py +6 -6
  264. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/unit/test_event_store_interface.py +3 -0
  265. eventsource_py-0.3.0/tests/unit/test_eventstore_global_position.py +299 -0
  266. eventsource_py-0.3.0/tests/unit/test_live_runner.py +855 -0
  267. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/unit/test_outbox_repository.py +64 -64
  268. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/unit/test_postgresql_event_store.py +56 -54
  269. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/unit/test_rabbitmq_event_bus.py +155 -115
  270. eventsource_py-0.3.0/tests/unit/test_subscription_config.py +539 -0
  271. eventsource_py-0.3.0/tests/unit/test_subscription_manager.py +1490 -0
  272. eventsource_py-0.3.0/tests/unit/test_transition.py +971 -0
  273. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/uv.lock +1 -1
  274. eventsource_py-0.2.0/CHANGELOG.md +0 -135
  275. eventsource_py-0.2.0/PKG-INFO +0 -340
  276. eventsource_py-0.2.0/README.md +0 -270
  277. eventsource_py-0.2.0/docs/api/aggregates.md +0 -576
  278. eventsource_py-0.2.0/docs/api/projections.md +0 -514
  279. eventsource_py-0.2.0/docs/api/stores.md +0 -666
  280. eventsource_py-0.2.0/docs/examples/projections.md +0 -682
  281. eventsource_py-0.2.0/examples/projection_example.py +0 -511
  282. eventsource_py-0.2.0/tests/integration/observability/test_tracing_performance.py +0 -713
  283. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  284. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  285. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  286. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  287. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/.github/workflows/ci.yml +0 -0
  288. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/.github/workflows/docs.yml +0 -0
  289. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/.github/workflows/release.yml +0 -0
  290. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/.gitignore +0 -0
  291. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/.pre-commit-config.yaml +0 -0
  292. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/LICENSE +0 -0
  293. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/RELEASING.md +0 -0
  294. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/docker-compose.test.yml +0 -0
  295. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/docs/adrs/0000-template.md +0 -0
  296. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/docs/adrs/0001-async-first-design.md +0 -0
  297. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/docs/adrs/0002-pydantic-event-models.md +0 -0
  298. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/docs/adrs/0003-optimistic-locking.md +0 -0
  299. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/docs/adrs/0005-api-design-patterns.md +0 -0
  300. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/docs/adrs/0006-event-registry-serialization.md +0 -0
  301. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/docs/adrs/0007-remove-sync-event-store.md +0 -0
  302. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/docs/adrs/0008-kafka-event-bus-integration.md +0 -0
  303. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/docs/adrs/index.md +0 -0
  304. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/docs/api/events.md +0 -0
  305. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/docs/development/testing.md +0 -0
  306. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/docs/examples/basic-order.md +0 -0
  307. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/docs/examples/multi-tenant.md +0 -0
  308. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/docs/examples/snapshotting.md +0 -0
  309. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/docs/examples/testing.md +0 -0
  310. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/docs/guides/authentication.md +0 -0
  311. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/docs/guides/error-handling.md +0 -0
  312. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/docs/guides/fanout-exchange.md +0 -0
  313. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/docs/guides/kafka-event-bus.md +0 -0
  314. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/docs/guides/kafka-metrics.md +0 -0
  315. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/docs/guides/multi-tenant.md +0 -0
  316. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/docs/guides/production.md +0 -0
  317. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/docs/guides/sqlite-backend.md +0 -0
  318. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/docs/infrastructure-tracking.md +0 -0
  319. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/examples/__init__.py +0 -0
  320. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/examples/aggregate_example.py +0 -0
  321. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/examples/basic_usage.py +0 -0
  322. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/py.typed +0 -0
  323. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/scripts/validate_examples.py +0 -0
  324. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/aggregates/__init__.py +0 -0
  325. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/aggregates/base.py +0 -0
  326. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/bus/__init__.py +0 -0
  327. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/bus/interface.py +0 -0
  328. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/config.py +0 -0
  329. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/events/__init__.py +0 -0
  330. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/events/base.py +0 -0
  331. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/events/registry.py +0 -0
  332. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/exceptions.py +0 -0
  333. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/migrations/SCHEMA_DESIGN.md +0 -0
  334. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/migrations/schemas/checkpoints.sql +0 -0
  335. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/migrations/schemas/dlq.sql +0 -0
  336. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/migrations/schemas/events.sql +0 -0
  337. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/migrations/schemas/events_partitioned.sql +0 -0
  338. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/migrations/schemas/outbox.sql +0 -0
  339. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/migrations/schemas/snapshots.sql +0 -0
  340. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/migrations/templates/alembic/all_tables.py.template +0 -0
  341. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/migrations/templates/alembic/checkpoints.py.template +0 -0
  342. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/migrations/templates/alembic/dlq.py.template +0 -0
  343. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/migrations/templates/alembic/events.py.template +0 -0
  344. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/migrations/templates/alembic/outbox.py.template +0 -0
  345. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/migrations/templates/dlq.sql +0 -0
  346. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/migrations/templates/events.sql +0 -0
  347. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/migrations/templates/events_partitioned.sql +0 -0
  348. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/migrations/templates/outbox.sql +0 -0
  349. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/migrations/templates/snapshots.sql +0 -0
  350. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/migrations/templates/sqlite/dlq.sql +0 -0
  351. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/migrations/templates/sqlite/events.sql +0 -0
  352. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/migrations/templates/sqlite/outbox.sql +0 -0
  353. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/migrations/templates/sqlite/snapshots.sql +0 -0
  354. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/observability/tracing.py +0 -0
  355. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/projections/__init__.py +0 -0
  356. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/projections/coordinator.py +0 -0
  357. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/projections/decorators.py +0 -0
  358. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/projections/protocols.py +0 -0
  359. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/protocols.py +0 -0
  360. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/py.typed +0 -0
  361. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/repositories/__init__.py +0 -0
  362. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/repositories/_connection.py +0 -0
  363. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/repositories/_json.py +0 -0
  364. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/snapshots/__init__.py +0 -0
  365. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/snapshots/exceptions.py +0 -0
  366. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/snapshots/in_memory.py +0 -0
  367. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/snapshots/interface.py +0 -0
  368. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/snapshots/postgresql.py +0 -0
  369. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/snapshots/sqlite.py +0 -0
  370. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/stores/_compat.py +0 -0
  371. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/src/eventsource/types.py +0 -0
  372. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/__init__.py +0 -0
  373. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/benchmarks/__init__.py +0 -0
  374. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/benchmarks/conftest.py +0 -0
  375. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/benchmarks/test_event_store.py +0 -0
  376. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/benchmarks/test_projections.py +0 -0
  377. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/benchmarks/test_repositories.py +0 -0
  378. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/benchmarks/test_serialization.py +0 -0
  379. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/fixtures/__init__.py +0 -0
  380. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/fixtures/aggregates.py +0 -0
  381. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/fixtures/events.py +0 -0
  382. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/integration/__init__.py +0 -0
  383. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/integration/bus/__init__.py +0 -0
  384. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/integration/bus/test_redis.py +0 -0
  385. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/integration/e2e/__init__.py +0 -0
  386. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/integration/e2e/test_full_flow.py +0 -0
  387. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/integration/observability/__init__.py +0 -0
  388. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/integration/observability/conftest.py +0 -0
  389. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/integration/observability/test_distributed_tracing.py +0 -0
  390. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/integration/observability/test_tracing_integration.py +0 -0
  391. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/integration/projections/__init__.py +0 -0
  392. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/integration/projections/test_database_projection.py +0 -0
  393. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/integration/repositories/__init__.py +0 -0
  394. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/integration/repositories/test_checkpoint.py +0 -0
  395. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/integration/stores/__init__.py +0 -0
  396. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/repositories/__init__.py +0 -0
  397. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/stores/__init__.py +0 -0
  398. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/stores/test_sqlite_event_store.py +0 -0
  399. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/unit/__init__.py +0 -0
  400. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/unit/aggregates/__init__.py +0 -0
  401. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/unit/aggregates/test_aggregate_snapshot_methods.py +0 -0
  402. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/unit/aggregates/test_repository_tracing.py +0 -0
  403. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/unit/bus/__init__.py +0 -0
  404. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/unit/bus/test_eventbus_tracing_patterns.py +0 -0
  405. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/unit/bus/test_rabbitmq_tracing.py +0 -0
  406. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/unit/migrations/__init__.py +0 -0
  407. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/unit/migrations/test_sqlite_snapshot_schema.py +0 -0
  408. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/unit/observability/__init__.py +0 -0
  409. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/unit/observability/test_attributes.py +0 -0
  410. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/unit/observability/test_projection_tracing.py +0 -0
  411. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/unit/observability/test_tracing.py +0 -0
  412. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/unit/snapshots/__init__.py +0 -0
  413. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/unit/snapshots/test_in_memory_snapshot_store.py +0 -0
  414. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/unit/snapshots/test_postgresql_snapshot_store.py +0 -0
  415. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/unit/snapshots/test_snapshot.py +0 -0
  416. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/unit/snapshots/test_snapshot_exceptions.py +0 -0
  417. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/unit/snapshots/test_snapshot_store_interface.py +0 -0
  418. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/unit/snapshots/test_snapshot_store_tracing.py +0 -0
  419. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/unit/snapshots/test_snapshots_module.py +0 -0
  420. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/unit/snapshots/test_sqlite_snapshot_store.py +0 -0
  421. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/unit/stores/__init__.py +0 -0
  422. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/unit/stores/test_memory_tracing.py +0 -0
  423. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/unit/stores/test_postgresql_tracing.py +0 -0
  424. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/unit/stores/test_sqlite_tracing.py +0 -0
  425. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/unit/test_additional_coverage.py +0 -0
  426. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/unit/test_aggregate_repository.py +0 -0
  427. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/unit/test_aggregate_root.py +0 -0
  428. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/unit/test_connection_helper.py +0 -0
  429. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/unit/test_domain_event.py +0 -0
  430. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/unit/test_event_bus.py +0 -0
  431. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/unit/test_event_registry.py +0 -0
  432. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/unit/test_exceptions.py +0 -0
  433. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/unit/test_fixtures.py +0 -0
  434. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/unit/test_in_memory_event_store.py +0 -0
  435. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/unit/test_json_encoder.py +0 -0
  436. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/unit/test_kafka_event_bus.py +0 -0
  437. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/unit/test_projection_base.py +0 -0
  438. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/unit/test_projection_coordinator.py +0 -0
  439. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/unit/test_projection_decorators.py +0 -0
  440. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/unit/test_projection_protocols.py +0 -0
  441. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/unit/test_protocols.py +0 -0
  442. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/unit/test_rabbitmq_exports.py +0 -0
  443. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/unit/test_redis_event_bus.py +0 -0
  444. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/unit/test_redis_event_bus_tracing.py +0 -0
  445. {eventsource_py-0.2.0 → eventsource_py-0.3.0}/tests/unit/test_timestamp_types.py +0 -0
@@ -0,0 +1,372 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [0.3.0] - 2025-12-12
11
+
12
+ ### Added
13
+
14
+ - **ReadModel Persistence Tooling** - Standardized read model persistence infrastructure (`eventsource.readmodels`)
15
+ - **Phase 1 - Core Components**:
16
+ - `ReadModel` base class with standard fields (id, timestamps, version, deleted_at)
17
+ - `ReadModelRepository` protocol with 13 methods for CRUD, querying, and lifecycle management
18
+ - `Query` and `Filter` classes for flexible, type-safe querying with operators (eq, ne, lt, gt, le, ge, in_, contains, startswith)
19
+ - `InMemoryReadModelRepository` implementation for testing and development
20
+ - **Phase 2 - SQL Backends**:
21
+ - `PostgreSQLReadModelRepository` with full async support via asyncpg
22
+ - `SQLiteReadModelRepository` with async support via aiosqlite
23
+ - Schema generation utilities (`generate_postgresql_schema()`, `generate_sqlite_schema()`) for automatic table creation from ReadModel classes
24
+ - **Phase 3 - Projection Integration**:
25
+ - `ReadModelProjection` base class integrating with `DatabaseProjection`
26
+ - `HandlerRegistry` integration with `@handles` decorator for event-driven updates
27
+ - Automatic repository injection into event handlers
28
+ - **Phase 4 - Enhanced Features**:
29
+ - Soft delete support with `get_deleted()` and `find_deleted()` methods
30
+ - Optimistic locking via `save_with_version_check()` for concurrent update safety
31
+ - `OptimisticLockError` and `ReadModelNotFoundError` exceptions
32
+ - Public exports from `eventsource.readmodels`: `ReadModel`, `ReadModelRepository`, `ReadModelProjection`, `Query`, `Filter`, `InMemoryReadModelRepository`, `PostgreSQLReadModelRepository`, `SQLiteReadModelRepository`
33
+ - New observability attributes: `ATTR_READ_MODEL_TYPE`, `ATTR_READ_MODEL_ID`
34
+ - **Multi-Tenant Live Migration** - Zero-downtime tenant migration between event stores (`eventsource.migration`)
35
+ - `MigrationCoordinator` orchestrating full migration lifecycle with pause/resume/abort controls
36
+ - `BulkCopier` for streaming historical event migration with checkpointing and configurable batch sizes
37
+ - `DualWriteInterceptor` for simultaneous writes to source and target stores during migration
38
+ - `CutoverManager` for sub-100ms atomic tenant routing switch with rollback capability
39
+ - `ConsistencyVerifier` for data integrity validation with COUNT, HASH, and FULL verification modes
40
+ - `SubscriptionMigrator` for checkpoint position translation between stores
41
+ - `TenantStoreRouter` for tenant-aware read/write routing during and after migration
42
+ - `WritePauseManager` for coordinated write pausing during cutover
43
+ - `SyncLagTracker` for monitoring replication lag between stores
44
+ - Real-time status streaming via `StatusStreamer` for migration monitoring
45
+ - Position mapping for checkpoint translation between source and target stores
46
+ - Comprehensive error classification with retry policies and circuit breaker pattern
47
+ - Audit logging for all migration operations
48
+ - OpenTelemetry metrics integration (`eventsource.migration.metrics`)
49
+ - **PostgreSQL Advisory Locks** - Distributed locking for migration coordination (`eventsource.locks`)
50
+ - `PostgreSQLAdvisoryLock` for session-level and transaction-level advisory locks
51
+ - Lock context managers for safe acquisition and release
52
+ - Lock timeout and retry configuration
53
+ - **Migration Exceptions** - Comprehensive exception hierarchy (`eventsource.migration.exceptions`)
54
+ - `MigrationError`, `MigrationStateError`, `MigrationNotFoundError`
55
+ - `BulkCopyError`, `DualWriteError`, `CutoverError`
56
+ - `ConsistencyError`, `RoutingError`, `LockError`
57
+ - Error classification with `ErrorCategory` and `ErrorSeverity` enums
58
+ - **Migration Documentation** - Comprehensive guides in `docs/migration/`:
59
+ - Architecture overview and component documentation
60
+ - Step-by-step migration guide
61
+ - API reference for all migration components
62
+ - Operational runbooks and troubleshooting guides
63
+ - Monitoring and alerting setup
64
+
65
+ - **Subscription Tracing** - OpenTelemetry tracing for all subscription components
66
+ - `SubscriptionManager` tracing for subscription lifecycle operations:
67
+ - `subscribe`, `unsubscribe`, `start_subscription`, `stop`, `stop_subscription`
68
+ - `pause_subscription`, `resume_subscription`
69
+ - `TransitionCoordinator` tracing for catch-up to live transitions:
70
+ - `execute` span with phase tracking (initial_catchup → live_subscribed → final_catchup → processing_buffer → live)
71
+ - Watermark and buffer size attributes
72
+ - `CatchUpRunner` tracing for historical event processing:
73
+ - `run_until_position` span with batch progress
74
+ - `deliver_event` span for individual event delivery
75
+ - `LiveRunner` tracing for real-time event processing:
76
+ - `start`, `stop`, `process_event` spans
77
+ - `process_buffer`, `process_pause_buffer` for transition buffers
78
+ - New subscription trace attributes in `eventsource.observability.attributes`:
79
+ - `ATTR_SUBSCRIPTION_NAME`, `ATTR_SUBSCRIPTION_STATE`, `ATTR_SUBSCRIPTION_PHASE`
80
+ - `ATTR_FROM_POSITION`, `ATTR_TO_POSITION`, `ATTR_BATCH_SIZE`
81
+ - `ATTR_BUFFER_SIZE`, `ATTR_EVENTS_PROCESSED`, `ATTR_EVENTS_SKIPPED`, `ATTR_WATERMARK`
82
+ - All components support `enable_tracing` parameter (default: `True`)
83
+ - Graceful degradation when OpenTelemetry is not installed
84
+
85
+ - **Subscription Manager** - New `eventsource.subscriptions` module for building event-driven projections with catch-up subscriptions and live event streaming
86
+ - `SubscriptionManager` class for coordinating subscriptions with unified lifecycle management
87
+ - Automatic catch-up from event store historical data
88
+ - Seamless transition to live event streaming via event bus
89
+ - Multiple subscriber support with concurrent processing
90
+ - Graceful shutdown with SIGTERM/SIGINT signal handling (`run_until_shutdown()`)
91
+ - Pause/resume functionality for individual subscriptions
92
+ - `Subscription` class with state machine for subscription lifecycle (idle → starting → catching_up → live → pausing → paused → resuming → stopping → stopped → failed)
93
+ - `SubscriptionConfig` for configurable subscription behavior:
94
+ - `batch_size`: Events per batch during catch-up (default: 100)
95
+ - `checkpoint_interval`: Events between checkpoints (default: 100)
96
+ - `checkpoint_strategy`: "batch" or "interval" checkpointing
97
+ - `start_from`: Start position ("beginning", "end", or specific position)
98
+ - `filter_event_types`: Optional event type filtering
99
+ - Subscriber protocols and base classes:
100
+ - `Subscriber` and `SyncSubscriber` protocols for event handlers
101
+ - `BatchSubscriber` protocol for batch event processing
102
+ - `BaseSubscriber`, `BatchAwareSubscriber`, and `FilteringSubscriber` base classes
103
+ - Catch-up and live runner implementations:
104
+ - `CatchupRunner` for reading historical events from event store with batching
105
+ - `LiveRunner` for streaming real-time events from event bus
106
+ - `TransitionCoordinator` for seamless handoff between modes
107
+ - Comprehensive error handling (`eventsource.subscriptions.error_handling`):
108
+ - `SubscriptionErrorHandler` with configurable retry policies
109
+ - `ErrorSeverity` levels: low, medium, high, critical
110
+ - `ErrorCategory` classification: event_processing, checkpoint, transition, infrastructure
111
+ - Error callbacks: `on_error()` and `on_critical_error()` hooks
112
+ - Circuit breaker pattern for failing subscriptions
113
+ - Retry system (`eventsource.subscriptions.retry`):
114
+ - Configurable retry with exponential backoff
115
+ - Jitter support for distributed systems
116
+ - Max retries and timeout limits
117
+ - Health monitoring (`eventsource.subscriptions.health`):
118
+ - `ManagerHealthChecker` for overall system health
119
+ - `SubscriptionHealthChecker` for per-subscription health
120
+ - Kubernetes-compatible liveness/readiness probes
121
+ - `HealthStatus`, `LivenessStatus`, `ReadinessStatus` enums
122
+ - Configurable health check thresholds
123
+ - Metrics collection (`eventsource.subscriptions.metrics`):
124
+ - Events processed, errors, lag, and processing duration metrics
125
+ - Per-subscription and aggregate statistics
126
+ - Flow control (`eventsource.subscriptions.flow_control`):
127
+ - Backpressure handling for slow consumers
128
+ - Rate limiting support
129
+ - Graceful shutdown (`eventsource.subscriptions.shutdown`):
130
+ - `ShutdownCoordinator` with phased shutdown sequence
131
+ - Configurable shutdown timeout
132
+ - In-flight event completion before shutdown
133
+ - `FlowController.wait_for_drain()` for tracking in-flight events during shutdown
134
+ - `ShutdownReason` enum for tracking shutdown triggers (SIGNAL_SIGTERM, SIGNAL_SIGINT, PROGRAMMATIC, HEALTH_CHECK, TIMEOUT, DOUBLE_SIGNAL)
135
+ - Pre-shutdown hooks (`on_pre_shutdown()`) for cleanup before shutdown (e.g., load balancer deregistration)
136
+ - Post-shutdown hooks (`on_post_shutdown()`) for actions after shutdown completes
137
+ - Shutdown deadline support (`set_shutdown_deadline()`) for Kubernetes `terminationGracePeriodSeconds` compliance
138
+ - Periodic checkpoint saves during drain phase (`checkpoint_interval` parameter)
139
+ - Shutdown metrics with OpenTelemetry integration (`ShutdownMetricsSnapshot`)
140
+ - Multi-instance coordination (`eventsource.subscriptions.coordination`):
141
+ - `LeaderElector` protocol for distributed leadership election
142
+ - `LeaderElectorWithLease` extended protocol for lease-based leadership
143
+ - `InMemoryLeaderElector` implementation for single-instance and testing scenarios
144
+ - `WorkRedistributionCoordinator` for coordinating work handoff during shutdown
145
+ - `ShutdownNotification` and `HeartbeatMessage` for peer-to-peer coordination
146
+ - Support for graceful work redistribution when instances shut down
147
+ - Event filtering (`eventsource.subscriptions.filtering`):
148
+ - Filter events by type, aggregate, or custom predicates
149
+ - Global position support in event stores:
150
+ - `PostgreSQLEventStore.subscribe_all_from_position()` for ordered event streaming
151
+ - `SQLiteEventStore.subscribe_all_from_position()` for ordered event streaming
152
+ - `global_position` field in stored events for total ordering
153
+ - Database migrations for `checkpoints` table with position tracking
154
+ - Comprehensive documentation: API reference, user guide, migration guide, and examples
155
+ - Exception hierarchy: `SubscriptionError`, `SubscriptionConfigError`, `SubscriptionStateError`, `SubscriptionAlreadyExistsError`, `CheckpointNotFoundError`
156
+ - **TypeConverter Extraction** - Refactored serialization logic from event stores into a dedicated component
157
+ - New `TypeConverter` protocol defining the contract for type conversion during event deserialization
158
+ - `DefaultTypeConverter` implementation with configurable UUID and datetime field detection
159
+ - `DEFAULT_UUID_FIELDS` and `DEFAULT_STRING_ID_FIELDS` constants for common field patterns
160
+ - `DefaultTypeConverter.strict()` factory method for explicit-only UUID field configuration
161
+ - SQLiteEventStore now has full configuration parity with PostgreSQLEventStore:
162
+ - Added `uuid_fields`, `string_id_fields`, and `auto_detect_uuid` constructor parameters
163
+ - Added `with_strict_uuid_detection()` factory method
164
+ - Public exports from `eventsource.stores`: `TypeConverter`, `DefaultTypeConverter`, `DEFAULT_UUID_FIELDS`, `DEFAULT_STRING_ID_FIELDS`
165
+ - 37 unit tests for comprehensive TypeConverter coverage
166
+
167
+ ### Changed
168
+
169
+ - Removed ~120 lines of duplicate serialization code from PostgreSQL and SQLite event stores by extracting to shared `TypeConverter`
170
+
171
+ ### Fixed
172
+
173
+ - **SQLiteOutboxRepository**: `get_pending_events()` now returns `list[OutboxEntry]` instead of `list[dict]`, matching the protocol specification
174
+ - **SQLiteOutboxRepository**: `add_event()` now properly stores and returns a UUID as the outbox ID, matching PostgreSQL behavior
175
+ - **SQLiteDLQRepository**: `get_failed_events()` now properly parses timestamp fields (`first_failed_at`, `last_failed_at`) from ISO 8601 strings to `datetime` objects
176
+ - **SQLiteDLQRepository**: `get_failed_event_by_id()` now properly parses timestamp fields (`first_failed_at`, `last_failed_at`, `resolved_at`) to `datetime` objects
177
+ - **SQLite schema**: Event outbox table now uses `TEXT PRIMARY KEY` for the `id` column (UUID as string) instead of `INTEGER PRIMARY KEY AUTOINCREMENT` to match PostgreSQL schema
178
+
179
+ ### Breaking Changes (Internal)
180
+
181
+ - Internal methods `_is_uuid_field()` and `_convert_types()` on event stores have been removed
182
+ - Users who were calling these internal methods directly should migrate to `store._type_converter.is_uuid_field()` and `store._type_converter.convert_types()`
183
+
184
+ ### Documentation
185
+
186
+ - Added subscription manager user guide (`docs/guides/subscriptions.md`) covering:
187
+ - Getting started with catch-up and live subscriptions
188
+ - Basic usage patterns and configuration
189
+ - Resilience patterns and error handling
190
+ - Advanced patterns for production deployments
191
+ - Troubleshooting guide
192
+ - Added subscription API reference (`docs/api/subscriptions.md`) with complete class and method documentation
193
+ - Added subscription migration guide (`docs/guides/subscription-migration.md`) for migrating from manual projection processing
194
+ - Added subscription examples (`examples/subscriptions/`) with:
195
+ - Basic projection example
196
+ - Multi-subscriber example
197
+ - Resilient projection with error handling
198
+ - **Updated all projection examples to use SubscriptionManager pattern**:
199
+ - `examples/projection_example.py` now demonstrates SubscriptionManager with catch-up, live subscriptions, and checkpoint tracking
200
+ - `docs/getting-started.md` updated with SubscriptionManager as the recommended approach
201
+ - `docs/examples/projections.md` now recommends SubscriptionManager over direct `event_bus.subscribe_all()`
202
+ - `docs/examples/sqlite-usage.md` integration tests updated to use SubscriptionManager
203
+ - Added comparison table showing benefits of SubscriptionManager vs direct EventBus subscription
204
+ - Added Kubernetes deployment guide (`docs/guides/kubernetes-deployment.md`) covering:
205
+ - Pod lifecycle integration and graceful shutdown
206
+ - Health probe configuration (liveness, readiness, startup)
207
+ - `terminationGracePeriodSeconds` configuration with shutdown deadline
208
+ - Example Deployment, Service, and PodDisruptionBudget manifests
209
+ - Spot instance and preemptible VM considerations (AWS, GCP, Azure)
210
+ - Shutdown metrics and observability
211
+ - Troubleshooting guide for common Kubernetes issues
212
+
213
+ ### Tests
214
+
215
+ - Added comprehensive ReadModel persistence test suite:
216
+ - Unit tests for all ReadModel components (`tests/unit/readmodels/`)
217
+ - Base class and field validation tests
218
+ - Query and Filter class tests
219
+ - Repository protocol compliance tests
220
+ - In-memory repository tests
221
+ - PostgreSQL and SQLite repository tests
222
+ - Schema generation tests
223
+ - Projection integration tests
224
+ - Handler registry integration tests
225
+ - Integration tests (`tests/integration/readmodels/`)
226
+ - Repository CRUD operations across all backends
227
+ - Projection event handling flows
228
+ - Enhanced features (soft delete, optimistic locking)
229
+ - Added comprehensive migration test suite (~950 new tests):
230
+ - Unit tests for all migration components (`tests/unit/migration/`)
231
+ - Integration tests for PostgreSQL locks and migration schema
232
+ - Chaos tests for failure scenarios and recovery
233
+ - Load testing benchmarks for performance validation
234
+ - Phase integration tests for bulk copy, dual write, and cutover
235
+ - Added comprehensive subscription manager test suite:
236
+ - Unit tests for all subscription components (`tests/unit/subscriptions/`)
237
+ - Integration tests for catch-up, live, and transition flows (`tests/integration/subscriptions/`)
238
+ - Resilience tests for error handling, retries, and recovery
239
+ - Health check and metrics tests
240
+ - Pause/resume functionality tests
241
+ - Backpressure and flow control tests
242
+ - Drain functionality tests (`test_drain.py`) for shutdown coordination
243
+ - Coordination protocol tests (`test_coordination.py`) for leader election and work redistribution
244
+ - Shutdown tests for pre/post hooks, deadline, metrics, and reason tracking
245
+
246
+ ## [0.2.0] - 2025-12-08
247
+
248
+ ### Added
249
+
250
+ #### Observability & Telemetry
251
+
252
+ - **Observability Module** (`eventsource.observability`) - Reusable OpenTelemetry utilities
253
+ - `OTEL_AVAILABLE` constant for checking OpenTelemetry availability
254
+ - `get_tracer()` and `should_trace()` helper functions
255
+ - `@traced` decorator for method-level tracing
256
+ - `TracingMixin` class for consistent tracing across components
257
+ - **Kafka Event Bus Metrics** - Comprehensive OpenTelemetry metrics
258
+ - Counters: `messages.published`, `messages.consumed`, `handler.invocations`, `handler.errors`, `messages.dlq`, `connection.errors`, `reconnections`, `rebalances`, `publish.errors`
259
+ - Histograms: `publish.duration`, `consume.duration`, `handler.duration`, `batch.size`
260
+ - Gauges: `connections.active`, `consumer.lag` (per partition)
261
+ - New `KafkaEventBusMetrics` class with `enable_metrics` config option
262
+ - Less than 5% performance overhead
263
+ - **SQLiteEventStore Tracing** - `enable_tracing` parameter for `append_events` and `get_events` operations
264
+ - **InMemoryEventBus Tracing** - `enable_tracing` parameter for event dispatch and handler execution
265
+
266
+ #### Aggregate Snapshotting
267
+
268
+ - `Snapshot` dataclass for point-in-time aggregate state capture
269
+ - `SnapshotStore` interface with `InMemorySnapshotStore`, `PostgreSQLSnapshotStore`, and `SQLiteSnapshotStore` implementations
270
+ - `AggregateRepository` snapshot support: `snapshot_store`, `snapshot_threshold`, and `snapshot_mode` parameters
271
+ - `AggregateRoot.schema_version` for snapshot schema evolution with automatic invalidation
272
+ - `create_snapshot()` and `await_pending_snapshots()` methods
273
+ - Snapshot exceptions: `SnapshotError`, `SnapshotDeserializationError`, `SnapshotSchemaVersionError`, `SnapshotNotFoundError`
274
+ - Database migrations for `snapshots` table (PostgreSQL and SQLite)
275
+
276
+ #### Event Handling & Validation
277
+
278
+ - `EventVersionError` exception and configurable version validation via `AggregateRoot.validate_versions`
279
+ - `UnhandledEventError` exception with configurable handling via `unregistered_event_handling` attribute ("ignore", "warn", "error")
280
+ - `FlexibleEventHandler` and `FlexibleEventSubscriber` protocols for sync/async handler signatures
281
+ - Consolidated `eventsource.protocols` module as canonical location for protocol definitions
282
+
283
+ #### Database & Repository
284
+
285
+ - `DatabaseProjection` class for projections requiring raw database connection access
286
+ - `execute_with_connection` helper for consistent connection handling
287
+ - Configurable UUID field detection in `PostgreSQLEventStore` via `uuid_fields`, `string_id_fields`, and `auto_detect_uuid` parameters
288
+ - `PostgreSQLEventStore.with_strict_uuid_detection()` class method
289
+
290
+ #### Developer Experience
291
+
292
+ - Pre-commit hooks with ruff, mypy, and bandit
293
+ - GitHub Actions workflow for performance benchmarks with baseline tracking and PR comparison
294
+ - Shared test fixtures module (`tests/fixtures/`) with reusable components
295
+
296
+ ### Changed
297
+
298
+ - Improved type annotations for better mypy compatibility
299
+ - Consolidated `@handles` decorator to `eventsource.projections.decorators` (old location deprecated)
300
+ - Consolidated protocol definitions to `eventsource.protocols` (old locations deprecated)
301
+ - Repository methods `get_pending_events`, `get_failed_events`, `get_failed_event_by_id` now return typed dataclasses (`OutboxEntry`, `DLQEntry`) instead of dicts
302
+ - Unified `get_events_by_type()` timestamp parameters to use `datetime` instead of `float`
303
+ - Refactored repositories to use `execute_with_connection` helper
304
+ - In-memory repositories now use `asyncio.Lock` for proper async concurrency
305
+
306
+ ### Removed
307
+
308
+ - `SyncEventStore` abstract class (use `asyncio.run()` for sync access; see ADR-0007)
309
+
310
+ ### Fixed
311
+
312
+ - Broken documentation links in ADRs and guides
313
+ - Mypy type errors in projections, repositories, and event bus modules
314
+ - `DeclarativeProjection` connection handling for proper transaction sharing
315
+
316
+ ## [0.1.3] - 2025-12-07
317
+
318
+ ### Documentation
319
+
320
+ - Added documentation badge linking to GitHub Pages
321
+ - Updated all documentation URLs to point to https://tyevans.github.io/eventsource-py
322
+ - Fixed mkdocs.yml site configuration with correct repository URLs
323
+ - Simplified README documentation section with links to hosted docs
324
+
325
+ ## [0.1.2] - 2025-12-07
326
+
327
+ ### Fixed
328
+
329
+ - Fixed release workflow version validation
330
+
331
+ ## [0.1.1] - 2025-12-07
332
+
333
+ ### Fixed
334
+
335
+ - Release infrastructure corrections
336
+
337
+ ## [0.1.0] - 2025-12-07
338
+
339
+ ### Added
340
+
341
+ - Initial release of eventsource-py library
342
+ - Event Store with PostgreSQL, SQLite, and In-Memory backends
343
+ - Domain Events with Pydantic validation
344
+ - Aggregate base class with optimistic concurrency control
345
+ - Projection system for building read models with checkpoint tracking
346
+ - Dead Letter Queue (DLQ) for failed event handling
347
+ - Snapshot support for aggregate state caching
348
+ - Multi-tenant support with tenant isolation
349
+ - Async-first API design throughout
350
+ - Comprehensive type hints and mypy compatibility
351
+ - Event registry for type-safe event deserialization
352
+ - Event Bus with In-Memory and Redis Streams backends
353
+ - Transactional Outbox pattern implementation
354
+ - `DatabaseProjection` class for projections requiring raw database connection access
355
+ - Pre-commit hooks configuration with ruff, mypy, and bandit
356
+
357
+ ### Infrastructure
358
+
359
+ - PostgreSQL backend with connection pooling (asyncpg)
360
+ - SQLite backend for lightweight deployments, development, and testing
361
+ - Redis Streams backend for distributed event bus
362
+ - In-Memory backends for testing and development
363
+ - Automatic schema creation and migrations
364
+ - GitHub Actions CI/CD pipeline
365
+
366
+ [Unreleased]: https://github.com/tyevans/eventsource-py/compare/v0.3.0...HEAD
367
+ [0.3.0]: https://github.com/tyevans/eventsource-py/compare/v0.2.0...v0.3.0
368
+ [0.2.0]: https://github.com/tyevans/eventsource-py/compare/v0.1.3...v0.2.0
369
+ [0.1.3]: https://github.com/tyevans/eventsource-py/compare/v0.1.2...v0.1.3
370
+ [0.1.2]: https://github.com/tyevans/eventsource-py/compare/v0.1.1...v0.1.2
371
+ [0.1.1]: https://github.com/tyevans/eventsource-py/compare/v0.1.0...v0.1.1
372
+ [0.1.0]: https://github.com/tyevans/eventsource-py/releases/tag/v0.1.0
@@ -0,0 +1,273 @@
1
+ Metadata-Version: 2.4
2
+ Name: eventsource-py
3
+ Version: 0.3.0
4
+ Summary: Production-ready event sourcing library for Python
5
+ Project-URL: Homepage, https://github.com/tyevans/eventsource-py
6
+ Project-URL: Documentation, https://tyevans.github.io/eventsource-py
7
+ Project-URL: Repository, https://github.com/tyevans/eventsource-py
8
+ Project-URL: Changelog, https://github.com/tyevans/eventsource-py/blob/main/CHANGELOG.md
9
+ Author-email: Ty Evans <tyevans@gmail.com>
10
+ License: MIT
11
+ License-File: LICENSE
12
+ Keywords: cqrs,ddd,domain-driven-design,event-sourcing,events
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
21
+ Classifier: Typing :: Typed
22
+ Requires-Python: >=3.11
23
+ Requires-Dist: pydantic<3.0,>=2.0
24
+ Requires-Dist: redis>=5.0
25
+ Requires-Dist: sqlalchemy<3.0,>=2.0
26
+ Provides-Extra: all
27
+ Requires-Dist: aio-pika>=9.0.0; extra == 'all'
28
+ Requires-Dist: aiokafka<1.0.0,>=0.9.0; extra == 'all'
29
+ Requires-Dist: aiosqlite<1.0,>=0.19.0; extra == 'all'
30
+ Requires-Dist: asyncpg<1.0,>=0.27.0; extra == 'all'
31
+ Requires-Dist: opentelemetry-api<2.0,>=1.0; extra == 'all'
32
+ Requires-Dist: opentelemetry-sdk<2.0,>=1.0; extra == 'all'
33
+ Requires-Dist: redis<6.0,>=5.0; extra == 'all'
34
+ Provides-Extra: all-backends
35
+ Requires-Dist: aiosqlite<1.0,>=0.19.0; extra == 'all-backends'
36
+ Requires-Dist: asyncpg<1.0,>=0.27.0; extra == 'all-backends'
37
+ Provides-Extra: benchmark
38
+ Requires-Dist: pytest-benchmark>=4.0.0; extra == 'benchmark'
39
+ Provides-Extra: dev
40
+ Requires-Dist: mypy>=1.8; extra == 'dev'
41
+ Requires-Dist: pre-commit>=4.0; extra == 'dev'
42
+ Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
43
+ Requires-Dist: pytest-benchmark>=4.0.0; extra == 'dev'
44
+ Requires-Dist: pytest-cov>=4.0; extra == 'dev'
45
+ Requires-Dist: pytest>=8.0; extra == 'dev'
46
+ Requires-Dist: ruff>=0.14.8; extra == 'dev'
47
+ Requires-Dist: testcontainers>=4.0; extra == 'dev'
48
+ Provides-Extra: docs
49
+ Requires-Dist: mkdocs-material>=9.5; extra == 'docs'
50
+ Requires-Dist: mkdocs>=1.5; extra == 'docs'
51
+ Requires-Dist: mkdocstrings[python]>=0.24; extra == 'docs'
52
+ Requires-Dist: pymdown-extensions>=10.0; extra == 'docs'
53
+ Provides-Extra: kafka
54
+ Requires-Dist: aiokafka<1.0.0,>=0.9.0; extra == 'kafka'
55
+ Provides-Extra: kafka-schema-registry
56
+ Requires-Dist: aiokafka<1.0.0,>=0.9.0; extra == 'kafka-schema-registry'
57
+ Requires-Dist: confluent-kafka<3.0.0,>=2.0.0; extra == 'kafka-schema-registry'
58
+ Provides-Extra: postgresql
59
+ Requires-Dist: asyncpg<1.0,>=0.27.0; extra == 'postgresql'
60
+ Provides-Extra: rabbitmq
61
+ Requires-Dist: aio-pika>=9.0.0; extra == 'rabbitmq'
62
+ Provides-Extra: redis
63
+ Requires-Dist: redis<6.0,>=5.0; extra == 'redis'
64
+ Provides-Extra: sqlite
65
+ Requires-Dist: aiosqlite<1.0,>=0.19.0; extra == 'sqlite'
66
+ Provides-Extra: telemetry
67
+ Requires-Dist: opentelemetry-api<2.0,>=1.0; extra == 'telemetry'
68
+ Requires-Dist: opentelemetry-sdk<2.0,>=1.0; extra == 'telemetry'
69
+ Description-Content-Type: text/markdown
70
+
71
+ # eventsource-py
72
+
73
+ [![PyPI version](https://img.shields.io/pypi/v/eventsource-py.svg)](https://pypi.org/project/eventsource-py/)
74
+ [![Python Version](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/)
75
+ [![CI](https://github.com/tyevans/eventsource-py/actions/workflows/ci.yml/badge.svg)](https://github.com/tyevans/eventsource-py/actions)
76
+ [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT)
77
+
78
+ **Stop losing data. Start capturing history.**
79
+
80
+ Traditional databases overwrite state on every update. Event sourcing captures *what happened* as a sequence of immutable events, giving you:
81
+
82
+ - **Complete audit trail** - Know exactly what changed, when, and why
83
+ - **Time travel** - Reconstruct state at any point in history
84
+ - **Multiple views** - Build different read models from the same events
85
+ - **Reliable debugging** - Replay events to reproduce any bug
86
+
87
+ eventsource-py makes this practical for Python applications with a clean, async-first API.
88
+
89
+ ```bash
90
+ pip install eventsource-py
91
+ ```
92
+
93
+ ## Quick Start
94
+
95
+ ```python
96
+ import asyncio
97
+ from uuid import UUID, uuid4
98
+ from pydantic import BaseModel
99
+ from eventsource import (
100
+ DomainEvent, register_event, AggregateRoot, AggregateRepository,
101
+ InMemoryEventStore, InMemoryEventBus, InMemoryCheckpointRepository,
102
+ )
103
+ from eventsource.subscriptions import SubscriptionManager, SubscriptionConfig
104
+
105
+ # 1. Define events - immutable facts that capture what happened
106
+ @register_event
107
+ class OrderPlaced(DomainEvent):
108
+ event_type: str = "OrderPlaced"
109
+ aggregate_type: str = "Order"
110
+ customer_id: UUID
111
+ total: float
112
+
113
+ @register_event
114
+ class OrderShipped(DomainEvent):
115
+ event_type: str = "OrderShipped"
116
+ aggregate_type: str = "Order"
117
+ tracking_number: str
118
+
119
+ # 2. Define aggregate state and business logic
120
+ class OrderState(BaseModel):
121
+ order_id: UUID
122
+ customer_id: UUID | None = None
123
+ total: float = 0.0
124
+ status: str = "draft"
125
+
126
+ class Order(AggregateRoot[OrderState]):
127
+ aggregate_type = "Order"
128
+
129
+ def _get_initial_state(self) -> OrderState:
130
+ return OrderState(order_id=self.aggregate_id)
131
+
132
+ def _apply(self, event: DomainEvent) -> None:
133
+ match event:
134
+ case OrderPlaced():
135
+ self._state = OrderState(
136
+ order_id=self.aggregate_id,
137
+ customer_id=event.customer_id,
138
+ total=event.total,
139
+ status="placed",
140
+ )
141
+ case OrderShipped():
142
+ self._state = self._state.model_copy(update={"status": "shipped"})
143
+
144
+ def place(self, customer_id: UUID, total: float) -> None:
145
+ if self.version > 0:
146
+ raise ValueError("Order already placed")
147
+ self.apply_event(OrderPlaced(
148
+ aggregate_id=self.aggregate_id,
149
+ customer_id=customer_id,
150
+ total=total,
151
+ aggregate_version=self.get_next_version(),
152
+ ))
153
+
154
+ def ship(self, tracking_number: str) -> None:
155
+ if self.state.status != "placed":
156
+ raise ValueError("Order must be placed before shipping")
157
+ self.apply_event(OrderShipped(
158
+ aggregate_id=self.aggregate_id,
159
+ tracking_number=tracking_number,
160
+ aggregate_version=self.get_next_version(),
161
+ ))
162
+
163
+ # 3. Define a projection - build read models from the event stream
164
+ class SalesReport:
165
+ """Read model that tracks sales metrics from events."""
166
+ def __init__(self):
167
+ self.total_revenue = 0.0
168
+ self.orders_placed = 0
169
+ self.orders_shipped = 0
170
+
171
+ def subscribed_to(self) -> list[type[DomainEvent]]:
172
+ return [OrderPlaced, OrderShipped]
173
+
174
+ async def handle(self, event: DomainEvent) -> None:
175
+ match event:
176
+ case OrderPlaced():
177
+ self.total_revenue += event.total
178
+ self.orders_placed += 1
179
+ case OrderShipped():
180
+ self.orders_shipped += 1
181
+
182
+ # 4. Wire it together
183
+ async def main():
184
+ # Infrastructure
185
+ store = InMemoryEventStore()
186
+ bus = InMemoryEventBus()
187
+ repo = AggregateRepository(
188
+ event_store=store,
189
+ aggregate_factory=Order,
190
+ aggregate_type="Order",
191
+ event_publisher=bus, # Publishes events to the bus after saving
192
+ )
193
+
194
+ # Set up subscription manager with our projection
195
+ manager = SubscriptionManager(store, bus, InMemoryCheckpointRepository())
196
+ report = SalesReport()
197
+ await manager.subscribe(report, SubscriptionConfig(start_from="beginning"), name="SalesReport")
198
+ await manager.start()
199
+
200
+ # Create some orders
201
+ for i in range(3):
202
+ order = repo.create_new(uuid4())
203
+ order.place(customer_id=uuid4(), total=100.0 * (i + 1))
204
+ await repo.save(order)
205
+
206
+ if i == 0: # Ship the first order
207
+ order.ship(tracking_number="TRACK-001")
208
+ await repo.save(order)
209
+
210
+ await asyncio.sleep(0.1) # Let events propagate
211
+
212
+ # The projection built a read model from the event stream
213
+ print(f"Revenue: ${report.total_revenue}") # Revenue: $600.0
214
+ print(f"Orders placed: {report.orders_placed}") # Orders placed: 3
215
+ print(f"Orders shipped: {report.orders_shipped}") # Orders shipped: 1
216
+
217
+ # Events are the source of truth - reload aggregate from its event history
218
+ order = await repo.load(order.aggregate_id)
219
+ print(f"Order status: {order.state.status}") # Order status: shipped
220
+ print(f"Order version: {order.version}") # Order version: 2 (placed + shipped)
221
+
222
+ await manager.stop()
223
+
224
+ asyncio.run(main())
225
+ ```
226
+
227
+ ## Production Ready
228
+
229
+ Swap in production backends when you're ready to deploy:
230
+
231
+ | Component | Development | Production |
232
+ |-----------|-------------|------------|
233
+ | Event Store | `InMemoryEventStore` | `PostgreSQLEventStore`, `SQLiteEventStore` |
234
+ | Event Bus | `InMemoryEventBus` | `RedisEventBus`, `RabbitMQEventBus`, `KafkaEventBus` |
235
+ | Checkpoints | `InMemoryCheckpointRepository` | `PostgreSQLCheckpointRepository` |
236
+
237
+ ```bash
238
+ # Add PostgreSQL + Redis for production
239
+ pip install eventsource-py[postgresql,redis]
240
+ ```
241
+
242
+ <details>
243
+ <summary>All installation options</summary>
244
+
245
+ ```bash
246
+ pip install eventsource-py[postgresql] # PostgreSQL event store
247
+ pip install eventsource-py[sqlite] # SQLite event store
248
+ pip install eventsource-py[redis] # Redis event bus
249
+ pip install eventsource-py[rabbitmq] # RabbitMQ event bus
250
+ pip install eventsource-py[kafka] # Kafka event bus
251
+ pip install eventsource-py[telemetry] # OpenTelemetry tracing
252
+ pip install eventsource-py[all] # Everything
253
+ ```
254
+
255
+ </details>
256
+
257
+ ## Features
258
+
259
+ - **Event Stores** - PostgreSQL, SQLite, In-Memory with optimistic concurrency
260
+ - **Event Bus** - Redis Streams, RabbitMQ, Kafka, In-Memory with consumer groups
261
+ - **Subscriptions** - Catch-up from history, live events, checkpointing, graceful shutdown
262
+ - **Projections** - Declarative handlers, retry logic, dead letter queues
263
+ - **Snapshots** - Optimize aggregate loading for long event streams
264
+ - **Multi-tenancy** - Built-in tenant isolation
265
+ - **Observability** - OpenTelemetry integration
266
+
267
+ ## Documentation
268
+
269
+ **[Full Documentation](https://tyevans.github.io/eventsource-py)** - Guides, examples, and API reference
270
+
271
+ ## License
272
+
273
+ MIT