mp-commons 0.2.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 (605) hide show
  1. mp_commons-0.2.0/.devcontainer/devcontainer.json +64 -0
  2. mp_commons-0.2.0/.devcontainer/docker-compose.yml +84 -0
  3. mp_commons-0.2.0/.github/ISSUE_TEMPLATE/bug_report.yml +63 -0
  4. mp_commons-0.2.0/.github/ISSUE_TEMPLATE/config.yml +5 -0
  5. mp_commons-0.2.0/.github/ISSUE_TEMPLATE/feature_request.yml +55 -0
  6. mp_commons-0.2.0/.github/dependabot.yml +34 -0
  7. mp_commons-0.2.0/.github/pull_request_template.md +48 -0
  8. mp_commons-0.2.0/.github/release-drafter.yml +65 -0
  9. mp_commons-0.2.0/.github/workflows/ci.yml +169 -0
  10. mp_commons-0.2.0/.github/workflows/docs.yml +50 -0
  11. mp_commons-0.2.0/.github/workflows/release-drafter.yml +21 -0
  12. mp_commons-0.2.0/.gitignore +101 -0
  13. mp_commons-0.2.0/.pre-commit-config.yaml +47 -0
  14. mp_commons-0.2.0/CHANGELOG.md +99 -0
  15. mp_commons-0.2.0/CONTRIBUTING.md +203 -0
  16. mp_commons-0.2.0/LICENSE +21 -0
  17. mp_commons-0.2.0/Makefile +99 -0
  18. mp_commons-0.2.0/PKG-INFO +388 -0
  19. mp_commons-0.2.0/README.md +244 -0
  20. mp_commons-0.2.0/SECURITY.md +55 -0
  21. mp_commons-0.2.0/TASKS.md +178 -0
  22. mp_commons-0.2.0/codecov.yml +30 -0
  23. mp_commons-0.2.0/docs/adapters/elasticsearch.md +54 -0
  24. mp_commons-0.2.0/docs/adapters/kafka.md +92 -0
  25. mp_commons-0.2.0/docs/adapters/mongodb.md +64 -0
  26. mp_commons-0.2.0/docs/adapters/postgresql.md +89 -0
  27. mp_commons-0.2.0/docs/adapters/redis.md +74 -0
  28. mp_commons-0.2.0/docs/adapters/s3.md +58 -0
  29. mp_commons-0.2.0/docs/api/application.md +9 -0
  30. mp_commons-0.2.0/docs/api/config.md +13 -0
  31. mp_commons-0.2.0/docs/api/kernel.md +17 -0
  32. mp_commons-0.2.0/docs/api/observability.md +17 -0
  33. mp_commons-0.2.0/docs/api/security.md +17 -0
  34. mp_commons-0.2.0/docs/api/testing.md +17 -0
  35. mp_commons-0.2.0/docs/architecture/ADR-0001-kernel-boundaries.md +43 -0
  36. mp_commons-0.2.0/docs/architecture/ADR-0002-outbox-inbox-idempotency.md +56 -0
  37. mp_commons-0.2.0/docs/architecture/ADR-0003-ports-and-adapters.md +84 -0
  38. mp_commons-0.2.0/docs/architecture/ADR-0004-async-first.md +59 -0
  39. mp_commons-0.2.0/docs/architecture/ADR-0005-optional-extras.md +66 -0
  40. mp_commons-0.2.0/docs/architecture/ADR-0006-result-type.md +79 -0
  41. mp_commons-0.2.0/docs/architecture/ADR-0007-multi-tenancy.md +96 -0
  42. mp_commons-0.2.0/docs/architecture/ADR-0008-event-sourcing.md +119 -0
  43. mp_commons-0.2.0/docs/architecture/diagrams.md +141 -0
  44. mp_commons-0.2.0/docs/contracts/openapi-compatibility.md +73 -0
  45. mp_commons-0.2.0/docs/examples/locustfile.py +157 -0
  46. mp_commons-0.2.0/docs/guides/adapters.md +99 -0
  47. mp_commons-0.2.0/docs/guides/migration-v1.md +230 -0
  48. mp_commons-0.2.0/docs/guides/quickstart.md +63 -0
  49. mp_commons-0.2.0/docs/guides/troubleshooting.md +229 -0
  50. mp_commons-0.2.0/docs/index.md +21 -0
  51. mp_commons-0.2.0/docs/observability/logging-contract.md +60 -0
  52. mp_commons-0.2.0/docs/security/pii-redaction.md +54 -0
  53. mp_commons-0.2.0/docs/security/threat-model.md +128 -0
  54. mp_commons-0.2.0/docs/versioning/semantic-versioning.md +49 -0
  55. mp_commons-0.2.0/examples/simple_service/__init__.py +0 -0
  56. mp_commons-0.2.0/examples/simple_service/app.py +177 -0
  57. mp_commons-0.2.0/mkdocs.yml +104 -0
  58. mp_commons-0.2.0/mypy.ini +388 -0
  59. mp_commons-0.2.0/pyproject.toml +139 -0
  60. mp_commons-0.2.0/ruff.toml +83 -0
  61. mp_commons-0.2.0/src/mp_commons/__init__.py +13 -0
  62. mp_commons-0.2.0/src/mp_commons/adapters/__init__.py +8 -0
  63. mp_commons-0.2.0/src/mp_commons/adapters/azure_blob/__init__.py +5 -0
  64. mp_commons-0.2.0/src/mp_commons/adapters/azure_blob/object_store.py +175 -0
  65. mp_commons-0.2.0/src/mp_commons/adapters/azure_keyvault/__init__.py +5 -0
  66. mp_commons-0.2.0/src/mp_commons/adapters/azure_keyvault/store.py +136 -0
  67. mp_commons-0.2.0/src/mp_commons/adapters/azure_servicebus/__init__.py +8 -0
  68. mp_commons-0.2.0/src/mp_commons/adapters/azure_servicebus/bus.py +219 -0
  69. mp_commons-0.2.0/src/mp_commons/adapters/cassandra/__init__.py +15 -0
  70. mp_commons-0.2.0/src/mp_commons/adapters/cassandra/repository.py +247 -0
  71. mp_commons-0.2.0/src/mp_commons/adapters/celery/__init__.py +21 -0
  72. mp_commons-0.2.0/src/mp_commons/adapters/celery/task_bus.py +194 -0
  73. mp_commons-0.2.0/src/mp_commons/adapters/dynamodb/__init__.py +17 -0
  74. mp_commons-0.2.0/src/mp_commons/adapters/dynamodb/repository.py +326 -0
  75. mp_commons-0.2.0/src/mp_commons/adapters/elasticsearch/__init__.py +15 -0
  76. mp_commons-0.2.0/src/mp_commons/adapters/elasticsearch/client.py +252 -0
  77. mp_commons-0.2.0/src/mp_commons/adapters/fastapi/__init__.py +31 -0
  78. mp_commons-0.2.0/src/mp_commons/adapters/fastapi/deps.py +141 -0
  79. mp_commons-0.2.0/src/mp_commons/adapters/fastapi/exception_mapper.py +92 -0
  80. mp_commons-0.2.0/src/mp_commons/adapters/fastapi/middleware.py +605 -0
  81. mp_commons-0.2.0/src/mp_commons/adapters/fastapi/routers.py +94 -0
  82. mp_commons-0.2.0/src/mp_commons/adapters/gcp_pubsub/__init__.py +5 -0
  83. mp_commons-0.2.0/src/mp_commons/adapters/gcp_pubsub/messaging.py +218 -0
  84. mp_commons-0.2.0/src/mp_commons/adapters/gcs/__init__.py +5 -0
  85. mp_commons-0.2.0/src/mp_commons/adapters/gcs/object_store.py +150 -0
  86. mp_commons-0.2.0/src/mp_commons/adapters/graphql/__init__.py +25 -0
  87. mp_commons-0.2.0/src/mp_commons/adapters/graphql/pagination.py +163 -0
  88. mp_commons-0.2.0/src/mp_commons/adapters/grpc/__init__.py +27 -0
  89. mp_commons-0.2.0/src/mp_commons/adapters/grpc/channel.py +241 -0
  90. mp_commons-0.2.0/src/mp_commons/adapters/grpc/server.py +374 -0
  91. mp_commons-0.2.0/src/mp_commons/adapters/http/__init__.py +7 -0
  92. mp_commons-0.2.0/src/mp_commons/adapters/http/circuit_client.py +31 -0
  93. mp_commons-0.2.0/src/mp_commons/adapters/http/client.py +96 -0
  94. mp_commons-0.2.0/src/mp_commons/adapters/http/retry_client.py +33 -0
  95. mp_commons-0.2.0/src/mp_commons/adapters/kafka/__init__.py +8 -0
  96. mp_commons-0.2.0/src/mp_commons/adapters/kafka/consumer.py +58 -0
  97. mp_commons-0.2.0/src/mp_commons/adapters/kafka/outbox_dispatcher.py +44 -0
  98. mp_commons-0.2.0/src/mp_commons/adapters/kafka/producer.py +73 -0
  99. mp_commons-0.2.0/src/mp_commons/adapters/kafka/serializer.py +26 -0
  100. mp_commons-0.2.0/src/mp_commons/adapters/keycloak/__init__.py +7 -0
  101. mp_commons-0.2.0/src/mp_commons/adapters/keycloak/jwks.py +79 -0
  102. mp_commons-0.2.0/src/mp_commons/adapters/keycloak/policy.py +24 -0
  103. mp_commons-0.2.0/src/mp_commons/adapters/keycloak/verifier.py +98 -0
  104. mp_commons-0.2.0/src/mp_commons/adapters/mailgun/__init__.py +5 -0
  105. mp_commons-0.2.0/src/mp_commons/adapters/mailgun/sender.py +173 -0
  106. mp_commons-0.2.0/src/mp_commons/adapters/mongodb/__init__.py +18 -0
  107. mp_commons-0.2.0/src/mp_commons/adapters/mongodb/event_store.py +117 -0
  108. mp_commons-0.2.0/src/mp_commons/adapters/mongodb/outbox.py +119 -0
  109. mp_commons-0.2.0/src/mp_commons/adapters/mongodb/repository.py +90 -0
  110. mp_commons-0.2.0/src/mp_commons/adapters/mongodb/uow.py +56 -0
  111. mp_commons-0.2.0/src/mp_commons/adapters/nats/__init__.py +5 -0
  112. mp_commons-0.2.0/src/mp_commons/adapters/nats/bus.py +56 -0
  113. mp_commons-0.2.0/src/mp_commons/adapters/opensearch/__init__.py +9 -0
  114. mp_commons-0.2.0/src/mp_commons/adapters/opensearch/client.py +196 -0
  115. mp_commons-0.2.0/src/mp_commons/adapters/opentelemetry/__init__.py +43 -0
  116. mp_commons-0.2.0/src/mp_commons/adapters/opentelemetry/enricher.py +25 -0
  117. mp_commons-0.2.0/src/mp_commons/adapters/opentelemetry/kafka_propagation.py +141 -0
  118. mp_commons-0.2.0/src/mp_commons/adapters/opentelemetry/metrics.py +74 -0
  119. mp_commons-0.2.0/src/mp_commons/adapters/opentelemetry/nats_propagation.py +124 -0
  120. mp_commons-0.2.0/src/mp_commons/adapters/opentelemetry/propagator.py +39 -0
  121. mp_commons-0.2.0/src/mp_commons/adapters/opentelemetry/sqlalchemy_instrumentation.py +185 -0
  122. mp_commons-0.2.0/src/mp_commons/adapters/opentelemetry/tracer.py +82 -0
  123. mp_commons-0.2.0/src/mp_commons/adapters/prometheus/__init__.py +16 -0
  124. mp_commons-0.2.0/src/mp_commons/adapters/prometheus/health_exporter.py +112 -0
  125. mp_commons-0.2.0/src/mp_commons/adapters/prometheus/metrics.py +195 -0
  126. mp_commons-0.2.0/src/mp_commons/adapters/pulsar/__init__.py +15 -0
  127. mp_commons-0.2.0/src/mp_commons/adapters/pulsar/messaging.py +246 -0
  128. mp_commons-0.2.0/src/mp_commons/adapters/rabbitmq/__init__.py +5 -0
  129. mp_commons-0.2.0/src/mp_commons/adapters/rabbitmq/bus.py +71 -0
  130. mp_commons-0.2.0/src/mp_commons/adapters/redis/__init__.py +23 -0
  131. mp_commons-0.2.0/src/mp_commons/adapters/redis/cache.py +40 -0
  132. mp_commons-0.2.0/src/mp_commons/adapters/redis/idempotency.py +42 -0
  133. mp_commons-0.2.0/src/mp_commons/adapters/redis/lock.py +54 -0
  134. mp_commons-0.2.0/src/mp_commons/adapters/redis/rate_limiter.py +41 -0
  135. mp_commons-0.2.0/src/mp_commons/adapters/redis/streams.py +198 -0
  136. mp_commons-0.2.0/src/mp_commons/adapters/s3/__init__.py +21 -0
  137. mp_commons-0.2.0/src/mp_commons/adapters/s3/object_store.py +222 -0
  138. mp_commons-0.2.0/src/mp_commons/adapters/sendgrid/__init__.py +5 -0
  139. mp_commons-0.2.0/src/mp_commons/adapters/sendgrid/sender.py +161 -0
  140. mp_commons-0.2.0/src/mp_commons/adapters/sqlalchemy/__init__.py +34 -0
  141. mp_commons-0.2.0/src/mp_commons/adapters/sqlalchemy/audit.py +182 -0
  142. mp_commons-0.2.0/src/mp_commons/adapters/sqlalchemy/event_store.py +159 -0
  143. mp_commons-0.2.0/src/mp_commons/adapters/sqlalchemy/idempotency.py +39 -0
  144. mp_commons-0.2.0/src/mp_commons/adapters/sqlalchemy/migrations.py +276 -0
  145. mp_commons-0.2.0/src/mp_commons/adapters/sqlalchemy/mixins.py +83 -0
  146. mp_commons-0.2.0/src/mp_commons/adapters/sqlalchemy/outbox.py +75 -0
  147. mp_commons-0.2.0/src/mp_commons/adapters/sqlalchemy/repository.py +49 -0
  148. mp_commons-0.2.0/src/mp_commons/adapters/sqlalchemy/session.py +38 -0
  149. mp_commons-0.2.0/src/mp_commons/adapters/sqlalchemy/specification.py +160 -0
  150. mp_commons-0.2.0/src/mp_commons/adapters/sqlalchemy/tenant_filter.py +137 -0
  151. mp_commons-0.2.0/src/mp_commons/adapters/sqlalchemy/uow.py +35 -0
  152. mp_commons-0.2.0/src/mp_commons/adapters/sqs/__init__.py +5 -0
  153. mp_commons-0.2.0/src/mp_commons/adapters/sqs/task_bus.py +170 -0
  154. mp_commons-0.2.0/src/mp_commons/adapters/vault/__init__.py +5 -0
  155. mp_commons-0.2.0/src/mp_commons/adapters/vault/store.py +122 -0
  156. mp_commons-0.2.0/src/mp_commons/adapters/websocket/__init__.py +17 -0
  157. mp_commons-0.2.0/src/mp_commons/adapters/websocket/hub.py +190 -0
  158. mp_commons-0.2.0/src/mp_commons/application/__init__.py +43 -0
  159. mp_commons-0.2.0/src/mp_commons/application/cache/__init__.py +20 -0
  160. mp_commons-0.2.0/src/mp_commons/application/cache/invalidation.py +63 -0
  161. mp_commons-0.2.0/src/mp_commons/application/cache/keys.py +23 -0
  162. mp_commons-0.2.0/src/mp_commons/application/cache/lru.py +197 -0
  163. mp_commons-0.2.0/src/mp_commons/application/cache/tags.py +58 -0
  164. mp_commons-0.2.0/src/mp_commons/application/cqrs/__init__.py +38 -0
  165. mp_commons-0.2.0/src/mp_commons/application/cqrs/commands.py +50 -0
  166. mp_commons-0.2.0/src/mp_commons/application/cqrs/decorators.py +121 -0
  167. mp_commons-0.2.0/src/mp_commons/application/cqrs/events.py +48 -0
  168. mp_commons-0.2.0/src/mp_commons/application/cqrs/pipeline_bus.py +50 -0
  169. mp_commons-0.2.0/src/mp_commons/application/cqrs/queries.py +51 -0
  170. mp_commons-0.2.0/src/mp_commons/application/email/__init__.py +12 -0
  171. mp_commons-0.2.0/src/mp_commons/application/email/in_memory.py +39 -0
  172. mp_commons-0.2.0/src/mp_commons/application/email/message.py +37 -0
  173. mp_commons-0.2.0/src/mp_commons/application/email/renderer.py +76 -0
  174. mp_commons-0.2.0/src/mp_commons/application/email/sender.py +22 -0
  175. mp_commons-0.2.0/src/mp_commons/application/email/ses.py +71 -0
  176. mp_commons-0.2.0/src/mp_commons/application/email/smtp.py +94 -0
  177. mp_commons-0.2.0/src/mp_commons/application/event_sourcing/__init__.py +29 -0
  178. mp_commons-0.2.0/src/mp_commons/application/event_sourcing/aggregate.py +54 -0
  179. mp_commons-0.2.0/src/mp_commons/application/event_sourcing/projector.py +44 -0
  180. mp_commons-0.2.0/src/mp_commons/application/event_sourcing/repository.py +112 -0
  181. mp_commons-0.2.0/src/mp_commons/application/event_sourcing/snapshot.py +60 -0
  182. mp_commons-0.2.0/src/mp_commons/application/event_sourcing/store.py +96 -0
  183. mp_commons-0.2.0/src/mp_commons/application/event_sourcing/stored_event.py +41 -0
  184. mp_commons-0.2.0/src/mp_commons/application/export/__init__.py +12 -0
  185. mp_commons-0.2.0/src/mp_commons/application/export/csv_export.py +39 -0
  186. mp_commons-0.2.0/src/mp_commons/application/export/excel_export.py +54 -0
  187. mp_commons-0.2.0/src/mp_commons/application/export/export_service.py +47 -0
  188. mp_commons-0.2.0/src/mp_commons/application/export/request.py +28 -0
  189. mp_commons-0.2.0/src/mp_commons/application/feature_flags/__init__.py +7 -0
  190. mp_commons-0.2.0/src/mp_commons/application/feature_flags/feature_flag.py +18 -0
  191. mp_commons-0.2.0/src/mp_commons/application/feature_flags/in_memory.py +32 -0
  192. mp_commons-0.2.0/src/mp_commons/application/feature_flags/provider.py +25 -0
  193. mp_commons-0.2.0/src/mp_commons/application/files/__init__.py +28 -0
  194. mp_commons-0.2.0/src/mp_commons/application/files/processor.py +46 -0
  195. mp_commons-0.2.0/src/mp_commons/application/files/service.py +103 -0
  196. mp_commons-0.2.0/src/mp_commons/application/files/upload.py +33 -0
  197. mp_commons-0.2.0/src/mp_commons/application/files/validator.py +64 -0
  198. mp_commons-0.2.0/src/mp_commons/application/gdpr/__init__.py +25 -0
  199. mp_commons-0.2.0/src/mp_commons/application/gdpr/erasure.py +158 -0
  200. mp_commons-0.2.0/src/mp_commons/application/i18n/__init__.py +17 -0
  201. mp_commons-0.2.0/src/mp_commons/application/i18n/translator.py +260 -0
  202. mp_commons-0.2.0/src/mp_commons/application/inbox/__init__.py +18 -0
  203. mp_commons-0.2.0/src/mp_commons/application/inbox/processor.py +48 -0
  204. mp_commons-0.2.0/src/mp_commons/application/inbox/store.py +75 -0
  205. mp_commons-0.2.0/src/mp_commons/application/masking/__init__.py +12 -0
  206. mp_commons-0.2.0/src/mp_commons/application/masking/log_filter.py +33 -0
  207. mp_commons-0.2.0/src/mp_commons/application/masking/masker.py +67 -0
  208. mp_commons-0.2.0/src/mp_commons/application/masking/rules.py +20 -0
  209. mp_commons-0.2.0/src/mp_commons/application/notifications/__init__.py +19 -0
  210. mp_commons-0.2.0/src/mp_commons/application/notifications/fcm.py +74 -0
  211. mp_commons-0.2.0/src/mp_commons/application/notifications/push.py +59 -0
  212. mp_commons-0.2.0/src/mp_commons/application/notifications/sms.py +51 -0
  213. mp_commons-0.2.0/src/mp_commons/application/notifications/twilio.py +61 -0
  214. mp_commons-0.2.0/src/mp_commons/application/pagination/__init__.py +6 -0
  215. mp_commons-0.2.0/src/mp_commons/application/pagination/page.py +80 -0
  216. mp_commons-0.2.0/src/mp_commons/application/pagination/page_request.py +51 -0
  217. mp_commons-0.2.0/src/mp_commons/application/pipeline/__init__.py +39 -0
  218. mp_commons-0.2.0/src/mp_commons/application/pipeline/audit_middleware.py +86 -0
  219. mp_commons-0.2.0/src/mp_commons/application/pipeline/middleware.py +20 -0
  220. mp_commons-0.2.0/src/mp_commons/application/pipeline/middlewares.py +291 -0
  221. mp_commons-0.2.0/src/mp_commons/application/pipeline/pipeline.py +35 -0
  222. mp_commons-0.2.0/src/mp_commons/application/rate_limit/__init__.py +17 -0
  223. mp_commons-0.2.0/src/mp_commons/application/rate_limit/local.py +62 -0
  224. mp_commons-0.2.0/src/mp_commons/application/rate_limit/rate_limiter.py +58 -0
  225. mp_commons-0.2.0/src/mp_commons/application/saga/__init__.py +25 -0
  226. mp_commons-0.2.0/src/mp_commons/application/saga/context.py +48 -0
  227. mp_commons-0.2.0/src/mp_commons/application/saga/orchestrator.py +171 -0
  228. mp_commons-0.2.0/src/mp_commons/application/saga/state.py +27 -0
  229. mp_commons-0.2.0/src/mp_commons/application/saga/step.py +41 -0
  230. mp_commons-0.2.0/src/mp_commons/application/saga/store.py +71 -0
  231. mp_commons-0.2.0/src/mp_commons/application/scheduler/__init__.py +17 -0
  232. mp_commons-0.2.0/src/mp_commons/application/scheduler/apscheduler.py +71 -0
  233. mp_commons-0.2.0/src/mp_commons/application/scheduler/in_memory.py +44 -0
  234. mp_commons-0.2.0/src/mp_commons/application/scheduler/job.py +26 -0
  235. mp_commons-0.2.0/src/mp_commons/application/scheduler/scheduler.py +65 -0
  236. mp_commons-0.2.0/src/mp_commons/application/search/__init__.py +14 -0
  237. mp_commons-0.2.0/src/mp_commons/application/search/query.py +33 -0
  238. mp_commons-0.2.0/src/mp_commons/application/search/result.py +30 -0
  239. mp_commons-0.2.0/src/mp_commons/application/search/service.py +96 -0
  240. mp_commons-0.2.0/src/mp_commons/application/uow/__init__.py +7 -0
  241. mp_commons-0.2.0/src/mp_commons/application/uow/decorators.py +31 -0
  242. mp_commons-0.2.0/src/mp_commons/application/uow/manager.py +21 -0
  243. mp_commons-0.2.0/src/mp_commons/application/webhooks/__init__.py +17 -0
  244. mp_commons-0.2.0/src/mp_commons/application/webhooks/dispatcher.py +91 -0
  245. mp_commons-0.2.0/src/mp_commons/application/webhooks/endpoint.py +24 -0
  246. mp_commons-0.2.0/src/mp_commons/application/webhooks/signature.py +26 -0
  247. mp_commons-0.2.0/src/mp_commons/application/webhooks/store.py +54 -0
  248. mp_commons-0.2.0/src/mp_commons/application/workflow/__init__.py +27 -0
  249. mp_commons-0.2.0/src/mp_commons/application/workflow/engine.py +143 -0
  250. mp_commons-0.2.0/src/mp_commons/application/workflow/state.py +22 -0
  251. mp_commons-0.2.0/src/mp_commons/application/workflow/transition.py +45 -0
  252. mp_commons-0.2.0/src/mp_commons/config/__init__.py +15 -0
  253. mp_commons-0.2.0/src/mp_commons/config/dynamic/__init__.py +19 -0
  254. mp_commons-0.2.0/src/mp_commons/config/dynamic/source.py +212 -0
  255. mp_commons-0.2.0/src/mp_commons/config/flags/__init__.py +17 -0
  256. mp_commons-0.2.0/src/mp_commons/config/flags/provider.py +200 -0
  257. mp_commons-0.2.0/src/mp_commons/config/secrets/__init__.py +6 -0
  258. mp_commons-0.2.0/src/mp_commons/config/secrets/kubernetes.py +29 -0
  259. mp_commons-0.2.0/src/mp_commons/config/secrets/port.py +31 -0
  260. mp_commons-0.2.0/src/mp_commons/config/settings/__init__.py +19 -0
  261. mp_commons-0.2.0/src/mp_commons/config/settings/base.py +22 -0
  262. mp_commons-0.2.0/src/mp_commons/config/settings/factory.py +93 -0
  263. mp_commons-0.2.0/src/mp_commons/config/settings/loaders.py +79 -0
  264. mp_commons-0.2.0/src/mp_commons/config/settings/validator.py +23 -0
  265. mp_commons-0.2.0/src/mp_commons/config/validation/__init__.py +9 -0
  266. mp_commons-0.2.0/src/mp_commons/config/validation/errors.py +34 -0
  267. mp_commons-0.2.0/src/mp_commons/kernel/__init__.py +33 -0
  268. mp_commons-0.2.0/src/mp_commons/kernel/contracts/__init__.py +23 -0
  269. mp_commons-0.2.0/src/mp_commons/kernel/contracts/compatibility.py +17 -0
  270. mp_commons-0.2.0/src/mp_commons/kernel/contracts/contract.py +92 -0
  271. mp_commons-0.2.0/src/mp_commons/kernel/ddd/__init__.py +74 -0
  272. mp_commons-0.2.0/src/mp_commons/kernel/ddd/aggregate.py +44 -0
  273. mp_commons-0.2.0/src/mp_commons/kernel/ddd/domain_event.py +63 -0
  274. mp_commons-0.2.0/src/mp_commons/kernel/ddd/domain_service.py +110 -0
  275. mp_commons-0.2.0/src/mp_commons/kernel/ddd/entity.py +30 -0
  276. mp_commons-0.2.0/src/mp_commons/kernel/ddd/event_bus.py +41 -0
  277. mp_commons-0.2.0/src/mp_commons/kernel/ddd/invariant.py +40 -0
  278. mp_commons-0.2.0/src/mp_commons/kernel/ddd/outbox_publisher.py +29 -0
  279. mp_commons-0.2.0/src/mp_commons/kernel/ddd/policies.py +230 -0
  280. mp_commons-0.2.0/src/mp_commons/kernel/ddd/repository.py +41 -0
  281. mp_commons-0.2.0/src/mp_commons/kernel/ddd/saga.py +88 -0
  282. mp_commons-0.2.0/src/mp_commons/kernel/ddd/specification.py +129 -0
  283. mp_commons-0.2.0/src/mp_commons/kernel/ddd/tenant.py +100 -0
  284. mp_commons-0.2.0/src/mp_commons/kernel/ddd/unit_of_work.py +35 -0
  285. mp_commons-0.2.0/src/mp_commons/kernel/ddd/value_object.py +25 -0
  286. mp_commons-0.2.0/src/mp_commons/kernel/errors/__init__.py +63 -0
  287. mp_commons-0.2.0/src/mp_commons/kernel/errors/application.py +66 -0
  288. mp_commons-0.2.0/src/mp_commons/kernel/errors/base.py +57 -0
  289. mp_commons-0.2.0/src/mp_commons/kernel/errors/domain.py +77 -0
  290. mp_commons-0.2.0/src/mp_commons/kernel/errors/infrastructure.py +77 -0
  291. mp_commons-0.2.0/src/mp_commons/kernel/messaging/__init__.py +69 -0
  292. mp_commons-0.2.0/src/mp_commons/kernel/messaging/dead_letter.py +45 -0
  293. mp_commons-0.2.0/src/mp_commons/kernel/messaging/idempotency.py +65 -0
  294. mp_commons-0.2.0/src/mp_commons/kernel/messaging/inbox.py +83 -0
  295. mp_commons-0.2.0/src/mp_commons/kernel/messaging/message.py +131 -0
  296. mp_commons-0.2.0/src/mp_commons/kernel/messaging/outbox.py +76 -0
  297. mp_commons-0.2.0/src/mp_commons/kernel/messaging/scheduled.py +51 -0
  298. mp_commons-0.2.0/src/mp_commons/kernel/security/__init__.py +53 -0
  299. mp_commons-0.2.0/src/mp_commons/kernel/security/audit.py +138 -0
  300. mp_commons-0.2.0/src/mp_commons/kernel/security/crypto.py +28 -0
  301. mp_commons-0.2.0/src/mp_commons/kernel/security/pii.py +80 -0
  302. mp_commons-0.2.0/src/mp_commons/kernel/security/pkce.py +151 -0
  303. mp_commons-0.2.0/src/mp_commons/kernel/security/policy.py +33 -0
  304. mp_commons-0.2.0/src/mp_commons/kernel/security/principal.py +49 -0
  305. mp_commons-0.2.0/src/mp_commons/kernel/security/rbac.py +255 -0
  306. mp_commons-0.2.0/src/mp_commons/kernel/security/security_context.py +44 -0
  307. mp_commons-0.2.0/src/mp_commons/kernel/time/__init__.py +5 -0
  308. mp_commons-0.2.0/src/mp_commons/kernel/time/clock.py +57 -0
  309. mp_commons-0.2.0/src/mp_commons/kernel/types/__init__.py +41 -0
  310. mp_commons-0.2.0/src/mp_commons/kernel/types/email.py +51 -0
  311. mp_commons-0.2.0/src/mp_commons/kernel/types/ids.py +105 -0
  312. mp_commons-0.2.0/src/mp_commons/kernel/types/money.py +81 -0
  313. mp_commons-0.2.0/src/mp_commons/kernel/types/option.py +100 -0
  314. mp_commons-0.2.0/src/mp_commons/kernel/types/phone.py +94 -0
  315. mp_commons-0.2.0/src/mp_commons/kernel/types/result.py +94 -0
  316. mp_commons-0.2.0/src/mp_commons/kernel/types/slug.py +47 -0
  317. mp_commons-0.2.0/src/mp_commons/kernel/types/uid.py +100 -0
  318. mp_commons-0.2.0/src/mp_commons/observability/__init__.py +21 -0
  319. mp_commons-0.2.0/src/mp_commons/observability/correlation/__init__.py +6 -0
  320. mp_commons-0.2.0/src/mp_commons/observability/correlation/context.py +90 -0
  321. mp_commons-0.2.0/src/mp_commons/observability/correlation/provider.py +16 -0
  322. mp_commons-0.2.0/src/mp_commons/observability/events/__init__.py +19 -0
  323. mp_commons-0.2.0/src/mp_commons/observability/events/emitter.py +154 -0
  324. mp_commons-0.2.0/src/mp_commons/observability/health/__init__.py +31 -0
  325. mp_commons-0.2.0/src/mp_commons/observability/health/adapters.py +218 -0
  326. mp_commons-0.2.0/src/mp_commons/observability/health/builtin.py +91 -0
  327. mp_commons-0.2.0/src/mp_commons/observability/health/check.py +34 -0
  328. mp_commons-0.2.0/src/mp_commons/observability/health/registry.py +58 -0
  329. mp_commons-0.2.0/src/mp_commons/observability/logging/__init__.py +22 -0
  330. mp_commons-0.2.0/src/mp_commons/observability/logging/async_handler.py +147 -0
  331. mp_commons-0.2.0/src/mp_commons/observability/logging/audit.py +137 -0
  332. mp_commons-0.2.0/src/mp_commons/observability/logging/factory.py +64 -0
  333. mp_commons-0.2.0/src/mp_commons/observability/logging/filters.py +34 -0
  334. mp_commons-0.2.0/src/mp_commons/observability/logging/processors.py +77 -0
  335. mp_commons-0.2.0/src/mp_commons/observability/logging/protocol.py +33 -0
  336. mp_commons-0.2.0/src/mp_commons/observability/logging/sampled.py +108 -0
  337. mp_commons-0.2.0/src/mp_commons/observability/metrics/__init__.py +15 -0
  338. mp_commons-0.2.0/src/mp_commons/observability/metrics/business.py +25 -0
  339. mp_commons-0.2.0/src/mp_commons/observability/metrics/noop.py +48 -0
  340. mp_commons-0.2.0/src/mp_commons/observability/metrics/ports.py +60 -0
  341. mp_commons-0.2.0/src/mp_commons/observability/profiling/__init__.py +10 -0
  342. mp_commons-0.2.0/src/mp_commons/observability/profiling/sampler.py +98 -0
  343. mp_commons-0.2.0/src/mp_commons/observability/slo/__init__.py +19 -0
  344. mp_commons-0.2.0/src/mp_commons/observability/slo/tracker.py +109 -0
  345. mp_commons-0.2.0/src/mp_commons/observability/tracing/__init__.py +6 -0
  346. mp_commons-0.2.0/src/mp_commons/observability/tracing/noop.py +48 -0
  347. mp_commons-0.2.0/src/mp_commons/observability/tracing/ports.py +76 -0
  348. mp_commons-0.2.0/src/mp_commons/py.typed +0 -0
  349. mp_commons-0.2.0/src/mp_commons/resilience/__init__.py +50 -0
  350. mp_commons-0.2.0/src/mp_commons/resilience/backpressure.py +135 -0
  351. mp_commons-0.2.0/src/mp_commons/resilience/bulkhead/__init__.py +7 -0
  352. mp_commons-0.2.0/src/mp_commons/resilience/bulkhead/bulkhead.py +23 -0
  353. mp_commons-0.2.0/src/mp_commons/resilience/bulkhead/errors.py +14 -0
  354. mp_commons-0.2.0/src/mp_commons/resilience/bulkhead/limiters.py +52 -0
  355. mp_commons-0.2.0/src/mp_commons/resilience/cache/__init__.py +5 -0
  356. mp_commons-0.2.0/src/mp_commons/resilience/cache/aside.py +87 -0
  357. mp_commons-0.2.0/src/mp_commons/resilience/circuit_breaker/__init__.py +15 -0
  358. mp_commons-0.2.0/src/mp_commons/resilience/circuit_breaker/breaker.py +92 -0
  359. mp_commons-0.2.0/src/mp_commons/resilience/circuit_breaker/errors.py +27 -0
  360. mp_commons-0.2.0/src/mp_commons/resilience/circuit_breaker/policy.py +19 -0
  361. mp_commons-0.2.0/src/mp_commons/resilience/circuit_breaker/redis_breaker.py +247 -0
  362. mp_commons-0.2.0/src/mp_commons/resilience/circuit_breaker/state.py +16 -0
  363. mp_commons-0.2.0/src/mp_commons/resilience/dead_letter_scheduler.py +166 -0
  364. mp_commons-0.2.0/src/mp_commons/resilience/deadline/__init__.py +9 -0
  365. mp_commons-0.2.0/src/mp_commons/resilience/deadline/context.py +75 -0
  366. mp_commons-0.2.0/src/mp_commons/resilience/fallback/__init__.py +5 -0
  367. mp_commons-0.2.0/src/mp_commons/resilience/fallback/policy.py +70 -0
  368. mp_commons-0.2.0/src/mp_commons/resilience/graceful_shutdown.py +194 -0
  369. mp_commons-0.2.0/src/mp_commons/resilience/hedge/__init__.py +5 -0
  370. mp_commons-0.2.0/src/mp_commons/resilience/hedge/policy.py +69 -0
  371. mp_commons-0.2.0/src/mp_commons/resilience/retry/__init__.py +25 -0
  372. mp_commons-0.2.0/src/mp_commons/resilience/retry/backoff.py +47 -0
  373. mp_commons-0.2.0/src/mp_commons/resilience/retry/jitter.py +36 -0
  374. mp_commons-0.2.0/src/mp_commons/resilience/retry/policy.py +83 -0
  375. mp_commons-0.2.0/src/mp_commons/resilience/retry/tenacity_adapter.py +114 -0
  376. mp_commons-0.2.0/src/mp_commons/resilience/throttle/__init__.py +9 -0
  377. mp_commons-0.2.0/src/mp_commons/resilience/throttle/token_bucket.py +79 -0
  378. mp_commons-0.2.0/src/mp_commons/resilience/timeouts/__init__.py +6 -0
  379. mp_commons-0.2.0/src/mp_commons/resilience/timeouts/deadline.py +34 -0
  380. mp_commons-0.2.0/src/mp_commons/resilience/timeouts/policy.py +28 -0
  381. mp_commons-0.2.0/src/mp_commons/security/__init__.py +32 -0
  382. mp_commons-0.2.0/src/mp_commons/security/apikeys/__init__.py +19 -0
  383. mp_commons-0.2.0/src/mp_commons/security/apikeys/generator.py +113 -0
  384. mp_commons-0.2.0/src/mp_commons/security/apikeys/hash_upgrade.py +192 -0
  385. mp_commons-0.2.0/src/mp_commons/security/encryption/__init__.py +15 -0
  386. mp_commons-0.2.0/src/mp_commons/security/encryption/fernet.py +63 -0
  387. mp_commons-0.2.0/src/mp_commons/security/encryption/key_rotation.py +47 -0
  388. mp_commons-0.2.0/src/mp_commons/security/jwt/__init__.py +5 -0
  389. mp_commons-0.2.0/src/mp_commons/security/jwt/decoder.py +114 -0
  390. mp_commons-0.2.0/src/mp_commons/security/rotation/__init__.py +19 -0
  391. mp_commons-0.2.0/src/mp_commons/security/rotation/rotator.py +140 -0
  392. mp_commons-0.2.0/src/mp_commons/security/tls/__init__.py +18 -0
  393. mp_commons-0.2.0/src/mp_commons/security/tls/certificates.py +147 -0
  394. mp_commons-0.2.0/src/mp_commons/security/tls/pinning.py +44 -0
  395. mp_commons-0.2.0/src/mp_commons/testing/__init__.py +51 -0
  396. mp_commons-0.2.0/src/mp_commons/testing/approval/__init__.py +19 -0
  397. mp_commons-0.2.0/src/mp_commons/testing/approval/asserter.py +157 -0
  398. mp_commons-0.2.0/src/mp_commons/testing/approval/plugin.py +125 -0
  399. mp_commons-0.2.0/src/mp_commons/testing/chaos/__init__.py +7 -0
  400. mp_commons-0.2.0/src/mp_commons/testing/chaos/failure.py +36 -0
  401. mp_commons-0.2.0/src/mp_commons/testing/chaos/latency.py +26 -0
  402. mp_commons-0.2.0/src/mp_commons/testing/chaos/toxiproxy.py +96 -0
  403. mp_commons-0.2.0/src/mp_commons/testing/contracts/__init__.py +11 -0
  404. mp_commons-0.2.0/src/mp_commons/testing/contracts/asyncapi.py +26 -0
  405. mp_commons-0.2.0/src/mp_commons/testing/contracts/compatibility.py +35 -0
  406. mp_commons-0.2.0/src/mp_commons/testing/contracts/openapi.py +39 -0
  407. mp_commons-0.2.0/src/mp_commons/testing/databases/__init__.py +15 -0
  408. mp_commons-0.2.0/src/mp_commons/testing/fakes/__init__.py +25 -0
  409. mp_commons-0.2.0/src/mp_commons/testing/fakes/clock.py +15 -0
  410. mp_commons-0.2.0/src/mp_commons/testing/fakes/feature_flags.py +73 -0
  411. mp_commons-0.2.0/src/mp_commons/testing/fakes/idempotency.py +33 -0
  412. mp_commons-0.2.0/src/mp_commons/testing/fakes/inbox.py +60 -0
  413. mp_commons-0.2.0/src/mp_commons/testing/fakes/message_bus.py +33 -0
  414. mp_commons-0.2.0/src/mp_commons/testing/fakes/metrics.py +133 -0
  415. mp_commons-0.2.0/src/mp_commons/testing/fakes/outbox.py +55 -0
  416. mp_commons-0.2.0/src/mp_commons/testing/fakes/policy.py +34 -0
  417. mp_commons-0.2.0/src/mp_commons/testing/fakes/secrets.py +63 -0
  418. mp_commons-0.2.0/src/mp_commons/testing/fixtures/__init__.py +32 -0
  419. mp_commons-0.2.0/src/mp_commons/testing/fixtures/clock.py +18 -0
  420. mp_commons-0.2.0/src/mp_commons/testing/fixtures/correlation.py +20 -0
  421. mp_commons-0.2.0/src/mp_commons/testing/fixtures/database.py +97 -0
  422. mp_commons-0.2.0/src/mp_commons/testing/fixtures/message_bus.py +35 -0
  423. mp_commons-0.2.0/src/mp_commons/testing/fixtures/principal.py +44 -0
  424. mp_commons-0.2.0/src/mp_commons/testing/fixtures/security.py +17 -0
  425. mp_commons-0.2.0/src/mp_commons/testing/fixtures/tenant.py +21 -0
  426. mp_commons-0.2.0/src/mp_commons/testing/generators/__init__.py +31 -0
  427. mp_commons-0.2.0/src/mp_commons/testing/generators/builder.py +110 -0
  428. mp_commons-0.2.0/src/mp_commons/testing/generators/domain_gen.py +47 -0
  429. mp_commons-0.2.0/src/mp_commons/testing/generators/id_gen.py +22 -0
  430. mp_commons-0.2.0/src/mp_commons/testing/generators/step_clock.py +88 -0
  431. mp_commons-0.2.0/src/mp_commons/testing/generators/strategies.py +131 -0
  432. mp_commons-0.2.0/src/mp_commons/testing/http/__init__.py +13 -0
  433. mp_commons-0.2.0/src/mp_commons/testing/http/stub_server.py +127 -0
  434. mp_commons-0.2.0/src/mp_commons/testing/load/__init__.py +14 -0
  435. mp_commons-0.2.0/src/mp_commons/testing/load/locust_helpers.py +192 -0
  436. mp_commons-0.2.0/src/mp_commons/testing/load/runner.py +160 -0
  437. mp_commons-0.2.0/src/mp_commons/testing/performance/__init__.py +17 -0
  438. mp_commons-0.2.0/src/mp_commons/testing/performance/assertions.py +73 -0
  439. mp_commons-0.2.0/src/mp_commons/testing/snapshot/__init__.py +12 -0
  440. mp_commons-0.2.0/src/mp_commons/testing/snapshot/asserter.py +80 -0
  441. mp_commons-0.2.0/src/mp_commons/testing/snapshot/serializer.py +42 -0
  442. mp_commons-0.2.0/src/mp_commons/testing/tenant_isolation.py +146 -0
  443. mp_commons-0.2.0/tests/__init__.py +0 -0
  444. mp_commons-0.2.0/tests/benchmarks/__init__.py +12 -0
  445. mp_commons-0.2.0/tests/benchmarks/bench_circuit_breaker.py +72 -0
  446. mp_commons-0.2.0/tests/benchmarks/bench_command_bus.py +115 -0
  447. mp_commons-0.2.0/tests/benchmarks/bench_entity_id.py +85 -0
  448. mp_commons-0.2.0/tests/benchmarks/bench_logging.py +174 -0
  449. mp_commons-0.2.0/tests/benchmarks/bench_rate_limiter.py +96 -0
  450. mp_commons-0.2.0/tests/benchmarks/bench_retry.py +87 -0
  451. mp_commons-0.2.0/tests/benchmarks/conftest.py +38 -0
  452. mp_commons-0.2.0/tests/conftest.py +5 -0
  453. mp_commons-0.2.0/tests/integration/__init__.py +0 -0
  454. mp_commons-0.2.0/tests/integration/test_cassandra.py +152 -0
  455. mp_commons-0.2.0/tests/integration/test_dynamodb.py +125 -0
  456. mp_commons-0.2.0/tests/integration/test_e2e_outbox_kafka.py +169 -0
  457. mp_commons-0.2.0/tests/integration/test_elasticsearch.py +132 -0
  458. mp_commons-0.2.0/tests/integration/test_kafka.py +221 -0
  459. mp_commons-0.2.0/tests/integration/test_keycloak.py +167 -0
  460. mp_commons-0.2.0/tests/integration/test_mongodb.py +378 -0
  461. mp_commons-0.2.0/tests/integration/test_nats.py +134 -0
  462. mp_commons-0.2.0/tests/integration/test_placeholder.py +43 -0
  463. mp_commons-0.2.0/tests/integration/test_postgres.py +325 -0
  464. mp_commons-0.2.0/tests/integration/test_pulsar.py +86 -0
  465. mp_commons-0.2.0/tests/integration/test_rabbitmq.py +170 -0
  466. mp_commons-0.2.0/tests/integration/test_redis.py +312 -0
  467. mp_commons-0.2.0/tests/integration/test_redis_streams.py +133 -0
  468. mp_commons-0.2.0/tests/integration/test_s3.py +150 -0
  469. mp_commons-0.2.0/tests/integration/test_saga_postgres.py +271 -0
  470. mp_commons-0.2.0/tests/integration/test_vault.py +139 -0
  471. mp_commons-0.2.0/tests/unit/__init__.py +0 -0
  472. mp_commons-0.2.0/tests/unit/adapters/__init__.py +1 -0
  473. mp_commons-0.2.0/tests/unit/adapters/test_alembic_migrations.py +143 -0
  474. mp_commons-0.2.0/tests/unit/adapters/test_azure_blob.py +110 -0
  475. mp_commons-0.2.0/tests/unit/adapters/test_azure_keyvault.py +117 -0
  476. mp_commons-0.2.0/tests/unit/adapters/test_azure_servicebus.py +144 -0
  477. mp_commons-0.2.0/tests/unit/adapters/test_cassandra.py +161 -0
  478. mp_commons-0.2.0/tests/unit/adapters/test_celery.py +155 -0
  479. mp_commons-0.2.0/tests/unit/adapters/test_dynamodb.py +214 -0
  480. mp_commons-0.2.0/tests/unit/adapters/test_elasticsearch.py +233 -0
  481. mp_commons-0.2.0/tests/unit/adapters/test_fastapi_adapter.py +606 -0
  482. mp_commons-0.2.0/tests/unit/adapters/test_fastapi_security_middleware.py +215 -0
  483. mp_commons-0.2.0/tests/unit/adapters/test_gcp_pubsub.py +117 -0
  484. mp_commons-0.2.0/tests/unit/adapters/test_gcs.py +95 -0
  485. mp_commons-0.2.0/tests/unit/adapters/test_graphql.py +129 -0
  486. mp_commons-0.2.0/tests/unit/adapters/test_grpc.py +153 -0
  487. mp_commons-0.2.0/tests/unit/adapters/test_grpc_server.py +284 -0
  488. mp_commons-0.2.0/tests/unit/adapters/test_http_clients.py +226 -0
  489. mp_commons-0.2.0/tests/unit/adapters/test_kafka_adapters.py +368 -0
  490. mp_commons-0.2.0/tests/unit/adapters/test_keycloak.py +263 -0
  491. mp_commons-0.2.0/tests/unit/adapters/test_mailgun.py +147 -0
  492. mp_commons-0.2.0/tests/unit/adapters/test_nats_adapters.py +181 -0
  493. mp_commons-0.2.0/tests/unit/adapters/test_nats_propagation.py +168 -0
  494. mp_commons-0.2.0/tests/unit/adapters/test_opensearch.py +206 -0
  495. mp_commons-0.2.0/tests/unit/adapters/test_opentelemetry_adapters.py +445 -0
  496. mp_commons-0.2.0/tests/unit/adapters/test_otel_instrumentation.py +198 -0
  497. mp_commons-0.2.0/tests/unit/adapters/test_prometheus.py +219 -0
  498. mp_commons-0.2.0/tests/unit/adapters/test_pulsar.py +226 -0
  499. mp_commons-0.2.0/tests/unit/adapters/test_rabbitmq_adapters.py +225 -0
  500. mp_commons-0.2.0/tests/unit/adapters/test_redis_adapters.py +415 -0
  501. mp_commons-0.2.0/tests/unit/adapters/test_redis_streams.py +203 -0
  502. mp_commons-0.2.0/tests/unit/adapters/test_s3.py +246 -0
  503. mp_commons-0.2.0/tests/unit/adapters/test_sendgrid.py +117 -0
  504. mp_commons-0.2.0/tests/unit/adapters/test_sqlalchemy_sqla.py +794 -0
  505. mp_commons-0.2.0/tests/unit/adapters/test_sqs.py +267 -0
  506. mp_commons-0.2.0/tests/unit/adapters/test_vault_adapters.py +244 -0
  507. mp_commons-0.2.0/tests/unit/adapters/test_websocket.py +197 -0
  508. mp_commons-0.2.0/tests/unit/application/__init__.py +0 -0
  509. mp_commons-0.2.0/tests/unit/application/test_async_lru_cache.py +135 -0
  510. mp_commons-0.2.0/tests/unit/application/test_cache.py +131 -0
  511. mp_commons-0.2.0/tests/unit/application/test_cqrs.py +289 -0
  512. mp_commons-0.2.0/tests/unit/application/test_cqrs_decorators.py +179 -0
  513. mp_commons-0.2.0/tests/unit/application/test_email.py +116 -0
  514. mp_commons-0.2.0/tests/unit/application/test_event_sourcing.py +562 -0
  515. mp_commons-0.2.0/tests/unit/application/test_export.py +191 -0
  516. mp_commons-0.2.0/tests/unit/application/test_feature_flags.py +118 -0
  517. mp_commons-0.2.0/tests/unit/application/test_files.py +230 -0
  518. mp_commons-0.2.0/tests/unit/application/test_gdpr.py +120 -0
  519. mp_commons-0.2.0/tests/unit/application/test_i18n.py +239 -0
  520. mp_commons-0.2.0/tests/unit/application/test_inbox.py +75 -0
  521. mp_commons-0.2.0/tests/unit/application/test_masking.py +119 -0
  522. mp_commons-0.2.0/tests/unit/application/test_notifications.py +164 -0
  523. mp_commons-0.2.0/tests/unit/application/test_pagination.py +151 -0
  524. mp_commons-0.2.0/tests/unit/application/test_pipeline.py +794 -0
  525. mp_commons-0.2.0/tests/unit/application/test_rate_limit.py +129 -0
  526. mp_commons-0.2.0/tests/unit/application/test_saga.py +472 -0
  527. mp_commons-0.2.0/tests/unit/application/test_scheduler.py +213 -0
  528. mp_commons-0.2.0/tests/unit/application/test_search.py +125 -0
  529. mp_commons-0.2.0/tests/unit/application/test_uow.py +183 -0
  530. mp_commons-0.2.0/tests/unit/application/test_webhooks.py +214 -0
  531. mp_commons-0.2.0/tests/unit/application/test_workflow.py +130 -0
  532. mp_commons-0.2.0/tests/unit/config/__init__.py +0 -0
  533. mp_commons-0.2.0/tests/unit/config/test_dynamic.py +166 -0
  534. mp_commons-0.2.0/tests/unit/config/test_flags.py +221 -0
  535. mp_commons-0.2.0/tests/unit/config/test_secrets.py +113 -0
  536. mp_commons-0.2.0/tests/unit/config/test_settings.py +147 -0
  537. mp_commons-0.2.0/tests/unit/config/test_settings_factory.py +145 -0
  538. mp_commons-0.2.0/tests/unit/config/test_validation.py +81 -0
  539. mp_commons-0.2.0/tests/unit/kernel/__init__.py +0 -0
  540. mp_commons-0.2.0/tests/unit/kernel/security/__init__.py +0 -0
  541. mp_commons-0.2.0/tests/unit/kernel/security/test_pkce.py +181 -0
  542. mp_commons-0.2.0/tests/unit/kernel/test_audit.py +499 -0
  543. mp_commons-0.2.0/tests/unit/kernel/test_contracts.py +204 -0
  544. mp_commons-0.2.0/tests/unit/kernel/test_ddd.py +966 -0
  545. mp_commons-0.2.0/tests/unit/kernel/test_errors.py +173 -0
  546. mp_commons-0.2.0/tests/unit/kernel/test_messaging.py +369 -0
  547. mp_commons-0.2.0/tests/unit/kernel/test_money_properties.py +165 -0
  548. mp_commons-0.2.0/tests/unit/kernel/test_pii_redaction_fuzz.py +148 -0
  549. mp_commons-0.2.0/tests/unit/kernel/test_result_properties.py +175 -0
  550. mp_commons-0.2.0/tests/unit/kernel/test_security.py +481 -0
  551. mp_commons-0.2.0/tests/unit/kernel/test_time.py +154 -0
  552. mp_commons-0.2.0/tests/unit/kernel/test_types.py +399 -0
  553. mp_commons-0.2.0/tests/unit/observability/__init__.py +0 -0
  554. mp_commons-0.2.0/tests/unit/observability/test_adapter_health_checks.py +205 -0
  555. mp_commons-0.2.0/tests/unit/observability/test_correlation.py +75 -0
  556. mp_commons-0.2.0/tests/unit/observability/test_correlation_headers.py +72 -0
  557. mp_commons-0.2.0/tests/unit/observability/test_events.py +169 -0
  558. mp_commons-0.2.0/tests/unit/observability/test_health.py +99 -0
  559. mp_commons-0.2.0/tests/unit/observability/test_logging.py +207 -0
  560. mp_commons-0.2.0/tests/unit/observability/test_logging_extras.py +541 -0
  561. mp_commons-0.2.0/tests/unit/observability/test_metrics.py +277 -0
  562. mp_commons-0.2.0/tests/unit/observability/test_profiling.py +55 -0
  563. mp_commons-0.2.0/tests/unit/observability/test_slo.py +108 -0
  564. mp_commons-0.2.0/tests/unit/observability/test_tracing.py +219 -0
  565. mp_commons-0.2.0/tests/unit/resilience/__init__.py +0 -0
  566. mp_commons-0.2.0/tests/unit/resilience/test_backpressure.py +75 -0
  567. mp_commons-0.2.0/tests/unit/resilience/test_bulkhead.py +156 -0
  568. mp_commons-0.2.0/tests/unit/resilience/test_cache_aside.py +83 -0
  569. mp_commons-0.2.0/tests/unit/resilience/test_circuit_breaker.py +160 -0
  570. mp_commons-0.2.0/tests/unit/resilience/test_circuit_breaker_stress.py +172 -0
  571. mp_commons-0.2.0/tests/unit/resilience/test_dead_letter_scheduler.py +219 -0
  572. mp_commons-0.2.0/tests/unit/resilience/test_deadline.py +92 -0
  573. mp_commons-0.2.0/tests/unit/resilience/test_fallback.py +106 -0
  574. mp_commons-0.2.0/tests/unit/resilience/test_graceful_shutdown.py +113 -0
  575. mp_commons-0.2.0/tests/unit/resilience/test_hedge.py +70 -0
  576. mp_commons-0.2.0/tests/unit/resilience/test_redis_circuit_breaker.py +269 -0
  577. mp_commons-0.2.0/tests/unit/resilience/test_retry.py +296 -0
  578. mp_commons-0.2.0/tests/unit/resilience/test_throttle.py +67 -0
  579. mp_commons-0.2.0/tests/unit/resilience/test_timeouts.py +115 -0
  580. mp_commons-0.2.0/tests/unit/security/__init__.py +1 -0
  581. mp_commons-0.2.0/tests/unit/security/test_apikeys.py +124 -0
  582. mp_commons-0.2.0/tests/unit/security/test_encryption.py +104 -0
  583. mp_commons-0.2.0/tests/unit/security/test_hash_upgrade.py +241 -0
  584. mp_commons-0.2.0/tests/unit/security/test_jwt.py +97 -0
  585. mp_commons-0.2.0/tests/unit/security/test_rotation.py +128 -0
  586. mp_commons-0.2.0/tests/unit/security/test_tls.py +74 -0
  587. mp_commons-0.2.0/tests/unit/test_example_service.py +66 -0
  588. mp_commons-0.2.0/tests/unit/test_trio_compat.py +208 -0
  589. mp_commons-0.2.0/tests/unit/testing/__init__.py +0 -0
  590. mp_commons-0.2.0/tests/unit/testing/test_approval.py +253 -0
  591. mp_commons-0.2.0/tests/unit/testing/test_builder.py +181 -0
  592. mp_commons-0.2.0/tests/unit/testing/test_chaos.py +176 -0
  593. mp_commons-0.2.0/tests/unit/testing/test_contracts.py +241 -0
  594. mp_commons-0.2.0/tests/unit/testing/test_db_fixtures.py +108 -0
  595. mp_commons-0.2.0/tests/unit/testing/test_fakes.py +381 -0
  596. mp_commons-0.2.0/tests/unit/testing/test_fixtures.py +165 -0
  597. mp_commons-0.2.0/tests/unit/testing/test_generators.py +137 -0
  598. mp_commons-0.2.0/tests/unit/testing/test_http_stubs.py +108 -0
  599. mp_commons-0.2.0/tests/unit/testing/test_load.py +284 -0
  600. mp_commons-0.2.0/tests/unit/testing/test_new_testing_utils.py +376 -0
  601. mp_commons-0.2.0/tests/unit/testing/test_performance.py +86 -0
  602. mp_commons-0.2.0/tests/unit/testing/test_snapshot.py +147 -0
  603. mp_commons-0.2.0/tests/unit/testing/test_strategies.py +420 -0
  604. mp_commons-0.2.0/tests/unit/testing/test_tenant_isolation_validator.py +117 -0
  605. mp_commons-0.2.0/uv.lock +3313 -0
@@ -0,0 +1,64 @@
1
+ {
2
+ "name": "mp-commons Dev Container",
3
+ "image": "mcr.microsoft.com/devcontainers/python:1-3.12-bullseye",
4
+
5
+ // Install uv + project dependencies on container creation
6
+ "onCreateCommand": "curl -LsSf https://astral.sh/uv/install.sh | sh && /root/.cargo/bin/uv pip install -e '.[dev]'",
7
+
8
+ // Start required Docker-in-Docker services for integration tests
9
+ "features": {
10
+ "ghcr.io/devcontainers/features/docker-in-docker:2": {
11
+ "version": "latest",
12
+ "enableNonRootDocker": "true"
13
+ },
14
+ "ghcr.io/devcontainers/features/git:1": {}
15
+ },
16
+
17
+ // VS Code extensions — Python tooling and database viewers
18
+ "customizations": {
19
+ "vscode": {
20
+ "extensions": [
21
+ "ms-python.python",
22
+ "ms-python.vscode-pylance",
23
+ "charliermarsh.ruff",
24
+ "ms-python.mypy-type-checker",
25
+ "cweijan.vscode-redis-client",
26
+ "cweijan.vscode-postgresql-client2",
27
+ "eamodio.gitlens",
28
+ "github.vscode-pull-request-github"
29
+ ],
30
+ "settings": {
31
+ "python.defaultInterpreterPath": "/root/.venv/bin/python",
32
+ "editor.formatOnSave": true,
33
+ "[python]": {
34
+ "editor.defaultFormatter": "charliermarsh.ruff",
35
+ "editor.codeActionsOnSave": {
36
+ "source.fixAll.ruff": "explicit",
37
+ "source.organizeImports.ruff": "explicit"
38
+ }
39
+ },
40
+ "mypy-type-checker.args": ["--config-file=pyproject.toml"],
41
+ "ruff.args": ["--config=pyproject.toml"]
42
+ }
43
+ }
44
+ },
45
+
46
+ // Expose common service ports for local development
47
+ "forwardPorts": [
48
+ 8000, // uvicorn (example service)
49
+ 5432, // PostgreSQL
50
+ 6379, // Redis
51
+ 9200, // Elasticsearch
52
+ 9000, // MinIO
53
+ 9092, // Kafka
54
+ 4222, // NATS
55
+ 5672 // RabbitMQ
56
+ ],
57
+
58
+ // Run infrastructure services via docker-compose
59
+ "dockerComposeFile": "docker-compose.yml",
60
+ "service": "app",
61
+ "workspaceFolder": "/workspace",
62
+
63
+ "postCreateCommand": "echo 'Dev container ready. Run: make test-unit'"
64
+ }
@@ -0,0 +1,84 @@
1
+ version: "3.9"
2
+
3
+ # Development infrastructure for mp-commons local development.
4
+ # All services are optional — comment out what you don't need.
5
+ # Start with: docker compose -f .devcontainer/docker-compose.yml up -d
6
+
7
+ services:
8
+ app:
9
+ image: mcr.microsoft.com/devcontainers/python:1-3.12-bullseye
10
+ volumes:
11
+ - ..:/workspace:cached
12
+ command: sleep infinity
13
+ environment:
14
+ DATABASE_URL: "postgresql+asyncpg://dev:dev@postgres:5432/devdb"
15
+ REDIS_URL: "redis://redis:6379/0"
16
+ ELASTICSEARCH_URL: "http://elasticsearch:9200"
17
+ KAFKA_BOOTSTRAP_SERVERS: "kafka:9092"
18
+ NATS_URL: "nats://nats:4222"
19
+
20
+ postgres:
21
+ image: postgres:16-alpine
22
+ restart: unless-stopped
23
+ environment:
24
+ POSTGRES_DB: devdb
25
+ POSTGRES_USER: dev
26
+ POSTGRES_PASSWORD: dev
27
+ ports:
28
+ - "5432:5432"
29
+ volumes:
30
+ - postgres-data:/var/lib/postgresql/data
31
+
32
+ redis:
33
+ image: redis:7-alpine
34
+ restart: unless-stopped
35
+ ports:
36
+ - "6379:6379"
37
+
38
+ elasticsearch:
39
+ image: elasticsearch:8.13.0
40
+ restart: unless-stopped
41
+ environment:
42
+ discovery.type: single-node
43
+ ES_JAVA_OPTS: "-Xms512m -Xmx512m"
44
+ xpack.security.enabled: "false"
45
+ ports:
46
+ - "9200:9200"
47
+
48
+ minio:
49
+ image: minio/minio:latest
50
+ restart: unless-stopped
51
+ command: server /data --console-address ":9001"
52
+ environment:
53
+ MINIO_ROOT_USER: minioadmin
54
+ MINIO_ROOT_PASSWORD: minioadmin
55
+ ports:
56
+ - "9000:9000"
57
+ - "9001:9001"
58
+ volumes:
59
+ - minio-data:/data
60
+
61
+ kafka:
62
+ image: bitnami/kafka:3.7
63
+ restart: unless-stopped
64
+ environment:
65
+ KAFKA_CFG_NODE_ID: 0
66
+ KAFKA_CFG_PROCESS_ROLES: controller,broker
67
+ KAFKA_CFG_LISTENERS: "PLAINTEXT://:9092,CONTROLLER://:9093"
68
+ KAFKA_CFG_ADVERTISED_LISTENERS: "PLAINTEXT://kafka:9092"
69
+ KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP: "CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT"
70
+ KAFKA_CFG_CONTROLLER_QUORUM_VOTERS: "0@kafka:9093"
71
+ KAFKA_CFG_CONTROLLER_LISTENER_NAMES: CONTROLLER
72
+ ports:
73
+ - "9092:9092"
74
+
75
+ nats:
76
+ image: nats:2.10-alpine
77
+ restart: unless-stopped
78
+ ports:
79
+ - "4222:4222"
80
+ - "8222:8222" # NATS monitoring
81
+
82
+ volumes:
83
+ postgres-data:
84
+ minio-data:
@@ -0,0 +1,63 @@
1
+ name: "🐛 Bug Report"
2
+ description: "Report a reproducible bug in mp-commons."
3
+ labels: ["bug", "triage"]
4
+ body:
5
+ - type: markdown
6
+ attributes:
7
+ value: |
8
+ Thank you for taking the time to file a bug report.
9
+ Please fill in as much detail as possible to help us reproduce and fix the issue quickly.
10
+
11
+ - type: input
12
+ id: version
13
+ attributes:
14
+ label: "mp-commons version"
15
+ placeholder: "e.g. 0.3.1"
16
+ validations:
17
+ required: true
18
+
19
+ - type: input
20
+ id: python_version
21
+ attributes:
22
+ label: "Python version"
23
+ placeholder: "e.g. 3.12.3"
24
+ validations:
25
+ required: true
26
+
27
+ - type: textarea
28
+ id: description
29
+ attributes:
30
+ label: "Bug description"
31
+ description: "A clear and concise description of what the bug is."
32
+ validations:
33
+ required: true
34
+
35
+ - type: textarea
36
+ id: reproduction
37
+ attributes:
38
+ label: "Minimal reproduction"
39
+ description: "Paste a minimal code snippet or steps that reliably reproduce the issue."
40
+ render: python
41
+ validations:
42
+ required: true
43
+
44
+ - type: textarea
45
+ id: expected
46
+ attributes:
47
+ label: "Expected behaviour"
48
+ validations:
49
+ required: true
50
+
51
+ - type: textarea
52
+ id: actual
53
+ attributes:
54
+ label: "Actual behaviour"
55
+ description: "Include the full traceback if available."
56
+ validations:
57
+ required: true
58
+
59
+ - type: textarea
60
+ id: context
61
+ attributes:
62
+ label: "Additional context"
63
+ description: "Any other relevant information (OS, extras installed, related issues)."
@@ -0,0 +1,5 @@
1
+ blank_issues_enabled: false
2
+ contact_links:
3
+ - name: "📖 Documentation"
4
+ url: "https://github.com/marcusPrado02/python-commons/tree/main/docs"
5
+ about: "Browse architecture docs and ADRs."
@@ -0,0 +1,55 @@
1
+ name: "✨ Feature Request"
2
+ description: "Propose a new feature or enhancement for mp-commons."
3
+ labels: ["enhancement", "triage"]
4
+ body:
5
+ - type: markdown
6
+ attributes:
7
+ value: |
8
+ Thanks for suggesting an improvement!
9
+ Please describe the problem you need to solve and the solution you have in mind.
10
+
11
+ - type: textarea
12
+ id: problem
13
+ attributes:
14
+ label: "Problem statement"
15
+ description: "What problem does this feature solve? What are you trying to achieve?"
16
+ validations:
17
+ required: true
18
+
19
+ - type: textarea
20
+ id: solution
21
+ attributes:
22
+ label: "Proposed solution"
23
+ description: "Describe the API or behaviour you'd like to see, ideally with a code example."
24
+ render: python
25
+ validations:
26
+ required: true
27
+
28
+ - type: textarea
29
+ id: alternatives
30
+ attributes:
31
+ label: "Alternatives considered"
32
+ description: "Have you tried any workarounds? What other approaches did you consider?"
33
+
34
+ - type: dropdown
35
+ id: layer
36
+ attributes:
37
+ label: "Affected layer"
38
+ options:
39
+ - "kernel"
40
+ - "application"
41
+ - "resilience"
42
+ - "observability"
43
+ - "config"
44
+ - "adapter"
45
+ - "testing"
46
+ - "packaging / CI"
47
+ - "other"
48
+ validations:
49
+ required: true
50
+
51
+ - type: textarea
52
+ id: context
53
+ attributes:
54
+ label: "Additional context"
55
+ description: "Links to relevant ADRs, issues, or external references."
@@ -0,0 +1,34 @@
1
+ version: 2
2
+
3
+ updates:
4
+ # Python dependencies (pip ecosystem — covers pyproject.toml extras)
5
+ - package-ecosystem: "pip"
6
+ directory: "/"
7
+ schedule:
8
+ interval: "weekly"
9
+ day: "monday"
10
+ time: "08:00"
11
+ timezone: "America/Sao_Paulo"
12
+ open-pull-requests-limit: 10
13
+ labels:
14
+ - "dependencies"
15
+ - "python"
16
+ ignore:
17
+ # Only accept patch/minor updates automatically for major adapters
18
+ - dependency-name: "fastapi"
19
+ update-types: ["version-update:semver-major"]
20
+ - dependency-name: "sqlalchemy"
21
+ update-types: ["version-update:semver-major"]
22
+
23
+ # GitHub Actions
24
+ - package-ecosystem: "github-actions"
25
+ directory: "/"
26
+ schedule:
27
+ interval: "weekly"
28
+ day: "monday"
29
+ time: "08:00"
30
+ timezone: "America/Sao_Paulo"
31
+ open-pull-requests-limit: 5
32
+ labels:
33
+ - "dependencies"
34
+ - "ci"
@@ -0,0 +1,48 @@
1
+ ## Summary
2
+
3
+ <!-- What does this PR do? One or two sentences. -->
4
+
5
+ Closes #<!-- issue number -->
6
+
7
+ ---
8
+
9
+ ## Type of change
10
+
11
+ - [ ] 🐛 Bug fix (non-breaking change that fixes an issue)
12
+ - [ ] ✨ New feature (non-breaking change that adds functionality)
13
+ - [ ] 💥 Breaking change (fix or feature that would cause existing functionality to not work as expected)
14
+ - [ ] ♻️ Refactoring (no functional change)
15
+ - [ ] 📝 Documentation / comments
16
+ - [ ] 🔧 CI / build / tooling
17
+
18
+ ---
19
+
20
+ ## Changes
21
+
22
+ <!--
23
+ A concise bullet list of what changed and why.
24
+ Include affected modules (e.g. kernel/ddd, adapters/fastapi).
25
+ -->
26
+
27
+ -
28
+ -
29
+
30
+ ---
31
+
32
+ ## Testing
33
+
34
+ - [ ] I added or updated unit tests that cover my changes
35
+ - [ ] I added or updated integration tests where applicable
36
+ - [ ] All existing tests pass locally (`make test`)
37
+ - [ ] Type-checked with mypy (`make typecheck`)
38
+ - [ ] Linted with ruff (`make lint`)
39
+
40
+ ---
41
+
42
+ ## Checklist
43
+
44
+ - [ ] My code follows the project's [Architecture Principles](docs/architecture/)
45
+ - [ ] I updated `CHANGELOG.md` under `[Unreleased]`
46
+ - [ ] `kernel.*` imports only stdlib (no new external deps added to the kernel)
47
+ - [ ] New public symbols are exported via the relevant `__init__.py` `__all__`
48
+ - [ ] I have read and agree to the **CONTRIBUTING.md** guidelines
@@ -0,0 +1,65 @@
1
+ name-template: 'v$RESOLVED_VERSION'
2
+ tag-template: 'v$RESOLVED_VERSION'
3
+
4
+ categories:
5
+ - title: '🚀 Features'
6
+ labels:
7
+ - 'feat'
8
+ - 'feature'
9
+ - title: '🐛 Bug Fixes'
10
+ labels:
11
+ - 'fix'
12
+ - 'bugfix'
13
+ - title: '💥 Breaking Changes'
14
+ labels:
15
+ - 'breaking'
16
+ - 'breaking-change'
17
+ - title: '🧪 Tests'
18
+ labels:
19
+ - 'test'
20
+ - 'tests'
21
+ - title: '🔧 Maintenance & Chores'
22
+ labels:
23
+ - 'chore'
24
+ - 'maintenance'
25
+ - 'ci'
26
+ - 'dependencies'
27
+ - title: '📚 Documentation'
28
+ labels:
29
+ - 'docs'
30
+ - 'documentation'
31
+ - title: '⚡ Performance'
32
+ labels:
33
+ - 'performance'
34
+ - 'perf'
35
+
36
+ change-template: '- $TITLE @$AUTHOR (#$NUMBER)'
37
+ change-title-escapes: '\<*_&'
38
+
39
+ version-resolver:
40
+ major:
41
+ labels:
42
+ - 'breaking'
43
+ - 'breaking-change'
44
+ minor:
45
+ labels:
46
+ - 'feat'
47
+ - 'feature'
48
+ patch:
49
+ labels:
50
+ - 'fix'
51
+ - 'bugfix'
52
+ - 'chore'
53
+ - 'docs'
54
+ - 'test'
55
+ - 'dependencies'
56
+ - 'ci'
57
+ default: patch
58
+
59
+ template: |
60
+ ## Changes
61
+
62
+ $CHANGES
63
+
64
+ ---
65
+ *Full Changelog*: https://github.com/$OWNER/$REPOSITORY/compare/$PREVIOUS_TAG...v$RESOLVED_VERSION
@@ -0,0 +1,169 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: ["main", "develop"]
6
+ tags: ["v*"]
7
+ pull_request:
8
+
9
+ permissions:
10
+ contents: read
11
+
12
+ jobs:
13
+ lint:
14
+ name: Lint & Type-check
15
+ runs-on: ubuntu-latest
16
+ steps:
17
+ - uses: actions/checkout@v4
18
+ - uses: astral-sh/setup-uv@v2
19
+ - name: Set up Python
20
+ run: uv python install 3.12
21
+ - name: Install dev deps
22
+ run: uv sync --extra dev
23
+ - name: ruff check
24
+ run: uv run ruff check src tests
25
+ - name: ruff format (check)
26
+ run: uv run ruff format --check src tests
27
+ - name: mypy
28
+ run: uv run mypy src
29
+
30
+ test:
31
+ name: Tests – Python ${{ matrix.python-version }}
32
+ runs-on: ubuntu-latest
33
+ strategy:
34
+ fail-fast: false
35
+ matrix:
36
+ python-version: ["3.12", "3.13"]
37
+ steps:
38
+ - uses: actions/checkout@v4
39
+ - uses: astral-sh/setup-uv@v2
40
+ - name: Set up Python ${{ matrix.python-version }}
41
+ run: uv python install ${{ matrix.python-version }}
42
+ - name: Install dev deps
43
+ run: uv sync --extra dev
44
+ - name: Run unit tests
45
+ run: |
46
+ uv run pytest tests/unit -x -q \
47
+ --cov=src/mp_commons \
48
+ --cov-report=xml \
49
+ --cov-report=term-missing \
50
+ -m "not integration"
51
+ - name: Upload coverage
52
+ uses: codecov/codecov-action@v4
53
+ with:
54
+ files: coverage.xml
55
+ fail_ci_if_error: false
56
+
57
+ integration:
58
+ # C-01 — Full integration test suite.
59
+ # PostgreSQL and Redis are provided as sidecar services.
60
+ # All other adapters (Elasticsearch, S3/MinIO, DynamoDB, Cassandra,
61
+ # Redis Streams, Pulsar, MongoDB, etc.) are spun up on-demand by
62
+ # testcontainers-python — Docker is available on ubuntu-latest runners.
63
+ name: Integration Tests
64
+ runs-on: ubuntu-latest
65
+ needs: [test]
66
+ services:
67
+ redis:
68
+ image: redis:7-alpine
69
+ ports: ["6379:6379"]
70
+ postgres:
71
+ image: postgres:16-alpine
72
+ env:
73
+ POSTGRES_DB: test
74
+ POSTGRES_USER: test
75
+ POSTGRES_PASSWORD: test
76
+ ports: ["5432:5432"]
77
+ options: >-
78
+ --health-cmd pg_isready
79
+ --health-interval 10s
80
+ --health-timeout 5s
81
+ --health-retries 5
82
+ steps:
83
+ - uses: actions/checkout@v4
84
+ - uses: astral-sh/setup-uv@v2
85
+ - name: Set up Python 3.12
86
+ run: uv python install 3.12
87
+ - name: Install dev deps
88
+ run: uv sync --extra dev
89
+ - name: Run integration tests
90
+ env:
91
+ DATABASE_URL: "postgresql+asyncpg://test:test@localhost:5432/test"
92
+ REDIS_URL: "redis://localhost:6379/0"
93
+ # testcontainers-python manages all other service containers automatically
94
+ TESTCONTAINERS_RYUK_DISABLED: "false"
95
+ run: uv run pytest tests/integration -x -q -m integration
96
+
97
+ security:
98
+ name: Security Scan
99
+ runs-on: ubuntu-latest
100
+ steps:
101
+ - uses: actions/checkout@v4
102
+ - uses: astral-sh/setup-uv@v2
103
+ - name: Set up Python
104
+ run: uv python install 3.12
105
+ - name: bandit
106
+ run: uvx bandit -r src -c pyproject.toml
107
+ - name: pip-audit
108
+ run: uvx pip-audit
109
+
110
+ mutation:
111
+ name: Mutation Testing (opt-in)
112
+ runs-on: ubuntu-latest
113
+ if: github.event_name == 'workflow_dispatch'
114
+ steps:
115
+ - uses: actions/checkout@v4
116
+ - uses: astral-sh/setup-uv@v2
117
+ - name: Set up Python
118
+ run: uv python install 3.12
119
+ - name: Install dev deps + mutmut
120
+ run: |
121
+ uv sync --extra dev
122
+ uvx --with mutmut mutmut --version
123
+ - name: Run unit tests to build coverage baseline
124
+ run: |
125
+ uv run pytest tests/unit -q \
126
+ --cov=src/mp_commons \
127
+ --cov-report=xml \
128
+ -m "not integration"
129
+ - name: Run mutation testing
130
+ run: |
131
+ uv run mutmut run --use-coverage
132
+ uv run mutmut results
133
+ - name: Check mutation score
134
+ run: |
135
+ SCORE=$(uv run mutmut results | grep -oP 'Survived: \K\d+')
136
+ KILLED=$(uv run mutmut results | grep -oP 'Killed: \K\d+')
137
+ TOTAL=$((SCORE + KILLED))
138
+ if [ "$TOTAL" -eq 0 ]; then
139
+ echo "No mutations generated" && exit 0
140
+ fi
141
+ PCT=$((KILLED * 100 / TOTAL))
142
+ echo "Mutation score: ${PCT}% (killed ${KILLED}/${TOTAL})"
143
+ if [ "$PCT" -lt 80 ]; then
144
+ echo "ERROR: Mutation score ${PCT}% is below the 80% threshold" && exit 1
145
+ fi
146
+
147
+ publish:
148
+ name: Publish to PyPI
149
+ runs-on: ubuntu-latest
150
+ needs: [lint, test]
151
+ if: startsWith(github.ref, 'refs/tags/v')
152
+ permissions:
153
+ contents: write # create GitHub release assets
154
+ id-token: write # OIDC token for PyPI Trusted Publishing
155
+ steps:
156
+ - uses: actions/checkout@v4
157
+ - uses: astral-sh/setup-uv@v2
158
+ - name: Build
159
+ run: uv build
160
+ - name: Generate SBOM (CycloneDX JSON)
161
+ run: uvx --from cyclonedx-bom cyclonedx-py environment --output-format json -o sbom.json
162
+ - name: Upload SBOM as release asset
163
+ uses: softprops/action-gh-release@v2
164
+ with:
165
+ files: sbom.json
166
+ env:
167
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
168
+ - name: Publish to PyPI
169
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,50 @@
1
+ name: Docs
2
+
3
+ on:
4
+ push:
5
+ branches: ["main"]
6
+ tags: ["v*"]
7
+ pull_request:
8
+ workflow_dispatch:
9
+
10
+ permissions:
11
+ contents: read
12
+
13
+ jobs:
14
+ lint:
15
+ name: Build docs (strict)
16
+ runs-on: ubuntu-latest
17
+ steps:
18
+ - uses: actions/checkout@v4
19
+ with:
20
+ fetch-depth: 0
21
+ - uses: astral-sh/setup-uv@v2
22
+ - name: Set up Python
23
+ run: uv python install 3.12
24
+ - name: Install deps
25
+ run: uv sync --extra dev
26
+ - name: mkdocs build --strict
27
+ run: uv run mkdocs build --strict
28
+
29
+ deploy:
30
+ name: Deploy to GitHub Pages
31
+ runs-on: ubuntu-latest
32
+ needs: [lint]
33
+ if: startsWith(github.ref, 'refs/tags/v')
34
+ permissions:
35
+ contents: write
36
+ steps:
37
+ - uses: actions/checkout@v4
38
+ with:
39
+ fetch-depth: 0
40
+ - uses: astral-sh/setup-uv@v2
41
+ - name: Set up Python
42
+ run: uv python install 3.12
43
+ - name: Install deps
44
+ run: uv sync --extra dev
45
+ - name: Configure Git for gh-deploy
46
+ run: |
47
+ git config user.name "github-actions[bot]"
48
+ git config user.email "github-actions[bot]@users.noreply.github.com"
49
+ - name: Deploy to GitHub Pages
50
+ run: uv run mkdocs gh-deploy --force
@@ -0,0 +1,21 @@
1
+ name: Release Drafter
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+
8
+ permissions:
9
+ contents: write
10
+ pull-requests: write
11
+
12
+ jobs:
13
+ update_release_draft:
14
+ name: Draft Next Release Notes
15
+ runs-on: ubuntu-latest
16
+ steps:
17
+ - uses: release-drafter/release-drafter@v6
18
+ with:
19
+ config-name: release-drafter.yml
20
+ env:
21
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}