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.
- mp_commons-0.2.0/.devcontainer/devcontainer.json +64 -0
- mp_commons-0.2.0/.devcontainer/docker-compose.yml +84 -0
- mp_commons-0.2.0/.github/ISSUE_TEMPLATE/bug_report.yml +63 -0
- mp_commons-0.2.0/.github/ISSUE_TEMPLATE/config.yml +5 -0
- mp_commons-0.2.0/.github/ISSUE_TEMPLATE/feature_request.yml +55 -0
- mp_commons-0.2.0/.github/dependabot.yml +34 -0
- mp_commons-0.2.0/.github/pull_request_template.md +48 -0
- mp_commons-0.2.0/.github/release-drafter.yml +65 -0
- mp_commons-0.2.0/.github/workflows/ci.yml +169 -0
- mp_commons-0.2.0/.github/workflows/docs.yml +50 -0
- mp_commons-0.2.0/.github/workflows/release-drafter.yml +21 -0
- mp_commons-0.2.0/.gitignore +101 -0
- mp_commons-0.2.0/.pre-commit-config.yaml +47 -0
- mp_commons-0.2.0/CHANGELOG.md +99 -0
- mp_commons-0.2.0/CONTRIBUTING.md +203 -0
- mp_commons-0.2.0/LICENSE +21 -0
- mp_commons-0.2.0/Makefile +99 -0
- mp_commons-0.2.0/PKG-INFO +388 -0
- mp_commons-0.2.0/README.md +244 -0
- mp_commons-0.2.0/SECURITY.md +55 -0
- mp_commons-0.2.0/TASKS.md +178 -0
- mp_commons-0.2.0/codecov.yml +30 -0
- mp_commons-0.2.0/docs/adapters/elasticsearch.md +54 -0
- mp_commons-0.2.0/docs/adapters/kafka.md +92 -0
- mp_commons-0.2.0/docs/adapters/mongodb.md +64 -0
- mp_commons-0.2.0/docs/adapters/postgresql.md +89 -0
- mp_commons-0.2.0/docs/adapters/redis.md +74 -0
- mp_commons-0.2.0/docs/adapters/s3.md +58 -0
- mp_commons-0.2.0/docs/api/application.md +9 -0
- mp_commons-0.2.0/docs/api/config.md +13 -0
- mp_commons-0.2.0/docs/api/kernel.md +17 -0
- mp_commons-0.2.0/docs/api/observability.md +17 -0
- mp_commons-0.2.0/docs/api/security.md +17 -0
- mp_commons-0.2.0/docs/api/testing.md +17 -0
- mp_commons-0.2.0/docs/architecture/ADR-0001-kernel-boundaries.md +43 -0
- mp_commons-0.2.0/docs/architecture/ADR-0002-outbox-inbox-idempotency.md +56 -0
- mp_commons-0.2.0/docs/architecture/ADR-0003-ports-and-adapters.md +84 -0
- mp_commons-0.2.0/docs/architecture/ADR-0004-async-first.md +59 -0
- mp_commons-0.2.0/docs/architecture/ADR-0005-optional-extras.md +66 -0
- mp_commons-0.2.0/docs/architecture/ADR-0006-result-type.md +79 -0
- mp_commons-0.2.0/docs/architecture/ADR-0007-multi-tenancy.md +96 -0
- mp_commons-0.2.0/docs/architecture/ADR-0008-event-sourcing.md +119 -0
- mp_commons-0.2.0/docs/architecture/diagrams.md +141 -0
- mp_commons-0.2.0/docs/contracts/openapi-compatibility.md +73 -0
- mp_commons-0.2.0/docs/examples/locustfile.py +157 -0
- mp_commons-0.2.0/docs/guides/adapters.md +99 -0
- mp_commons-0.2.0/docs/guides/migration-v1.md +230 -0
- mp_commons-0.2.0/docs/guides/quickstart.md +63 -0
- mp_commons-0.2.0/docs/guides/troubleshooting.md +229 -0
- mp_commons-0.2.0/docs/index.md +21 -0
- mp_commons-0.2.0/docs/observability/logging-contract.md +60 -0
- mp_commons-0.2.0/docs/security/pii-redaction.md +54 -0
- mp_commons-0.2.0/docs/security/threat-model.md +128 -0
- mp_commons-0.2.0/docs/versioning/semantic-versioning.md +49 -0
- mp_commons-0.2.0/examples/simple_service/__init__.py +0 -0
- mp_commons-0.2.0/examples/simple_service/app.py +177 -0
- mp_commons-0.2.0/mkdocs.yml +104 -0
- mp_commons-0.2.0/mypy.ini +388 -0
- mp_commons-0.2.0/pyproject.toml +139 -0
- mp_commons-0.2.0/ruff.toml +83 -0
- mp_commons-0.2.0/src/mp_commons/__init__.py +13 -0
- mp_commons-0.2.0/src/mp_commons/adapters/__init__.py +8 -0
- mp_commons-0.2.0/src/mp_commons/adapters/azure_blob/__init__.py +5 -0
- mp_commons-0.2.0/src/mp_commons/adapters/azure_blob/object_store.py +175 -0
- mp_commons-0.2.0/src/mp_commons/adapters/azure_keyvault/__init__.py +5 -0
- mp_commons-0.2.0/src/mp_commons/adapters/azure_keyvault/store.py +136 -0
- mp_commons-0.2.0/src/mp_commons/adapters/azure_servicebus/__init__.py +8 -0
- mp_commons-0.2.0/src/mp_commons/adapters/azure_servicebus/bus.py +219 -0
- mp_commons-0.2.0/src/mp_commons/adapters/cassandra/__init__.py +15 -0
- mp_commons-0.2.0/src/mp_commons/adapters/cassandra/repository.py +247 -0
- mp_commons-0.2.0/src/mp_commons/adapters/celery/__init__.py +21 -0
- mp_commons-0.2.0/src/mp_commons/adapters/celery/task_bus.py +194 -0
- mp_commons-0.2.0/src/mp_commons/adapters/dynamodb/__init__.py +17 -0
- mp_commons-0.2.0/src/mp_commons/adapters/dynamodb/repository.py +326 -0
- mp_commons-0.2.0/src/mp_commons/adapters/elasticsearch/__init__.py +15 -0
- mp_commons-0.2.0/src/mp_commons/adapters/elasticsearch/client.py +252 -0
- mp_commons-0.2.0/src/mp_commons/adapters/fastapi/__init__.py +31 -0
- mp_commons-0.2.0/src/mp_commons/adapters/fastapi/deps.py +141 -0
- mp_commons-0.2.0/src/mp_commons/adapters/fastapi/exception_mapper.py +92 -0
- mp_commons-0.2.0/src/mp_commons/adapters/fastapi/middleware.py +605 -0
- mp_commons-0.2.0/src/mp_commons/adapters/fastapi/routers.py +94 -0
- mp_commons-0.2.0/src/mp_commons/adapters/gcp_pubsub/__init__.py +5 -0
- mp_commons-0.2.0/src/mp_commons/adapters/gcp_pubsub/messaging.py +218 -0
- mp_commons-0.2.0/src/mp_commons/adapters/gcs/__init__.py +5 -0
- mp_commons-0.2.0/src/mp_commons/adapters/gcs/object_store.py +150 -0
- mp_commons-0.2.0/src/mp_commons/adapters/graphql/__init__.py +25 -0
- mp_commons-0.2.0/src/mp_commons/adapters/graphql/pagination.py +163 -0
- mp_commons-0.2.0/src/mp_commons/adapters/grpc/__init__.py +27 -0
- mp_commons-0.2.0/src/mp_commons/adapters/grpc/channel.py +241 -0
- mp_commons-0.2.0/src/mp_commons/adapters/grpc/server.py +374 -0
- mp_commons-0.2.0/src/mp_commons/adapters/http/__init__.py +7 -0
- mp_commons-0.2.0/src/mp_commons/adapters/http/circuit_client.py +31 -0
- mp_commons-0.2.0/src/mp_commons/adapters/http/client.py +96 -0
- mp_commons-0.2.0/src/mp_commons/adapters/http/retry_client.py +33 -0
- mp_commons-0.2.0/src/mp_commons/adapters/kafka/__init__.py +8 -0
- mp_commons-0.2.0/src/mp_commons/adapters/kafka/consumer.py +58 -0
- mp_commons-0.2.0/src/mp_commons/adapters/kafka/outbox_dispatcher.py +44 -0
- mp_commons-0.2.0/src/mp_commons/adapters/kafka/producer.py +73 -0
- mp_commons-0.2.0/src/mp_commons/adapters/kafka/serializer.py +26 -0
- mp_commons-0.2.0/src/mp_commons/adapters/keycloak/__init__.py +7 -0
- mp_commons-0.2.0/src/mp_commons/adapters/keycloak/jwks.py +79 -0
- mp_commons-0.2.0/src/mp_commons/adapters/keycloak/policy.py +24 -0
- mp_commons-0.2.0/src/mp_commons/adapters/keycloak/verifier.py +98 -0
- mp_commons-0.2.0/src/mp_commons/adapters/mailgun/__init__.py +5 -0
- mp_commons-0.2.0/src/mp_commons/adapters/mailgun/sender.py +173 -0
- mp_commons-0.2.0/src/mp_commons/adapters/mongodb/__init__.py +18 -0
- mp_commons-0.2.0/src/mp_commons/adapters/mongodb/event_store.py +117 -0
- mp_commons-0.2.0/src/mp_commons/adapters/mongodb/outbox.py +119 -0
- mp_commons-0.2.0/src/mp_commons/adapters/mongodb/repository.py +90 -0
- mp_commons-0.2.0/src/mp_commons/adapters/mongodb/uow.py +56 -0
- mp_commons-0.2.0/src/mp_commons/adapters/nats/__init__.py +5 -0
- mp_commons-0.2.0/src/mp_commons/adapters/nats/bus.py +56 -0
- mp_commons-0.2.0/src/mp_commons/adapters/opensearch/__init__.py +9 -0
- mp_commons-0.2.0/src/mp_commons/adapters/opensearch/client.py +196 -0
- mp_commons-0.2.0/src/mp_commons/adapters/opentelemetry/__init__.py +43 -0
- mp_commons-0.2.0/src/mp_commons/adapters/opentelemetry/enricher.py +25 -0
- mp_commons-0.2.0/src/mp_commons/adapters/opentelemetry/kafka_propagation.py +141 -0
- mp_commons-0.2.0/src/mp_commons/adapters/opentelemetry/metrics.py +74 -0
- mp_commons-0.2.0/src/mp_commons/adapters/opentelemetry/nats_propagation.py +124 -0
- mp_commons-0.2.0/src/mp_commons/adapters/opentelemetry/propagator.py +39 -0
- mp_commons-0.2.0/src/mp_commons/adapters/opentelemetry/sqlalchemy_instrumentation.py +185 -0
- mp_commons-0.2.0/src/mp_commons/adapters/opentelemetry/tracer.py +82 -0
- mp_commons-0.2.0/src/mp_commons/adapters/prometheus/__init__.py +16 -0
- mp_commons-0.2.0/src/mp_commons/adapters/prometheus/health_exporter.py +112 -0
- mp_commons-0.2.0/src/mp_commons/adapters/prometheus/metrics.py +195 -0
- mp_commons-0.2.0/src/mp_commons/adapters/pulsar/__init__.py +15 -0
- mp_commons-0.2.0/src/mp_commons/adapters/pulsar/messaging.py +246 -0
- mp_commons-0.2.0/src/mp_commons/adapters/rabbitmq/__init__.py +5 -0
- mp_commons-0.2.0/src/mp_commons/adapters/rabbitmq/bus.py +71 -0
- mp_commons-0.2.0/src/mp_commons/adapters/redis/__init__.py +23 -0
- mp_commons-0.2.0/src/mp_commons/adapters/redis/cache.py +40 -0
- mp_commons-0.2.0/src/mp_commons/adapters/redis/idempotency.py +42 -0
- mp_commons-0.2.0/src/mp_commons/adapters/redis/lock.py +54 -0
- mp_commons-0.2.0/src/mp_commons/adapters/redis/rate_limiter.py +41 -0
- mp_commons-0.2.0/src/mp_commons/adapters/redis/streams.py +198 -0
- mp_commons-0.2.0/src/mp_commons/adapters/s3/__init__.py +21 -0
- mp_commons-0.2.0/src/mp_commons/adapters/s3/object_store.py +222 -0
- mp_commons-0.2.0/src/mp_commons/adapters/sendgrid/__init__.py +5 -0
- mp_commons-0.2.0/src/mp_commons/adapters/sendgrid/sender.py +161 -0
- mp_commons-0.2.0/src/mp_commons/adapters/sqlalchemy/__init__.py +34 -0
- mp_commons-0.2.0/src/mp_commons/adapters/sqlalchemy/audit.py +182 -0
- mp_commons-0.2.0/src/mp_commons/adapters/sqlalchemy/event_store.py +159 -0
- mp_commons-0.2.0/src/mp_commons/adapters/sqlalchemy/idempotency.py +39 -0
- mp_commons-0.2.0/src/mp_commons/adapters/sqlalchemy/migrations.py +276 -0
- mp_commons-0.2.0/src/mp_commons/adapters/sqlalchemy/mixins.py +83 -0
- mp_commons-0.2.0/src/mp_commons/adapters/sqlalchemy/outbox.py +75 -0
- mp_commons-0.2.0/src/mp_commons/adapters/sqlalchemy/repository.py +49 -0
- mp_commons-0.2.0/src/mp_commons/adapters/sqlalchemy/session.py +38 -0
- mp_commons-0.2.0/src/mp_commons/adapters/sqlalchemy/specification.py +160 -0
- mp_commons-0.2.0/src/mp_commons/adapters/sqlalchemy/tenant_filter.py +137 -0
- mp_commons-0.2.0/src/mp_commons/adapters/sqlalchemy/uow.py +35 -0
- mp_commons-0.2.0/src/mp_commons/adapters/sqs/__init__.py +5 -0
- mp_commons-0.2.0/src/mp_commons/adapters/sqs/task_bus.py +170 -0
- mp_commons-0.2.0/src/mp_commons/adapters/vault/__init__.py +5 -0
- mp_commons-0.2.0/src/mp_commons/adapters/vault/store.py +122 -0
- mp_commons-0.2.0/src/mp_commons/adapters/websocket/__init__.py +17 -0
- mp_commons-0.2.0/src/mp_commons/adapters/websocket/hub.py +190 -0
- mp_commons-0.2.0/src/mp_commons/application/__init__.py +43 -0
- mp_commons-0.2.0/src/mp_commons/application/cache/__init__.py +20 -0
- mp_commons-0.2.0/src/mp_commons/application/cache/invalidation.py +63 -0
- mp_commons-0.2.0/src/mp_commons/application/cache/keys.py +23 -0
- mp_commons-0.2.0/src/mp_commons/application/cache/lru.py +197 -0
- mp_commons-0.2.0/src/mp_commons/application/cache/tags.py +58 -0
- mp_commons-0.2.0/src/mp_commons/application/cqrs/__init__.py +38 -0
- mp_commons-0.2.0/src/mp_commons/application/cqrs/commands.py +50 -0
- mp_commons-0.2.0/src/mp_commons/application/cqrs/decorators.py +121 -0
- mp_commons-0.2.0/src/mp_commons/application/cqrs/events.py +48 -0
- mp_commons-0.2.0/src/mp_commons/application/cqrs/pipeline_bus.py +50 -0
- mp_commons-0.2.0/src/mp_commons/application/cqrs/queries.py +51 -0
- mp_commons-0.2.0/src/mp_commons/application/email/__init__.py +12 -0
- mp_commons-0.2.0/src/mp_commons/application/email/in_memory.py +39 -0
- mp_commons-0.2.0/src/mp_commons/application/email/message.py +37 -0
- mp_commons-0.2.0/src/mp_commons/application/email/renderer.py +76 -0
- mp_commons-0.2.0/src/mp_commons/application/email/sender.py +22 -0
- mp_commons-0.2.0/src/mp_commons/application/email/ses.py +71 -0
- mp_commons-0.2.0/src/mp_commons/application/email/smtp.py +94 -0
- mp_commons-0.2.0/src/mp_commons/application/event_sourcing/__init__.py +29 -0
- mp_commons-0.2.0/src/mp_commons/application/event_sourcing/aggregate.py +54 -0
- mp_commons-0.2.0/src/mp_commons/application/event_sourcing/projector.py +44 -0
- mp_commons-0.2.0/src/mp_commons/application/event_sourcing/repository.py +112 -0
- mp_commons-0.2.0/src/mp_commons/application/event_sourcing/snapshot.py +60 -0
- mp_commons-0.2.0/src/mp_commons/application/event_sourcing/store.py +96 -0
- mp_commons-0.2.0/src/mp_commons/application/event_sourcing/stored_event.py +41 -0
- mp_commons-0.2.0/src/mp_commons/application/export/__init__.py +12 -0
- mp_commons-0.2.0/src/mp_commons/application/export/csv_export.py +39 -0
- mp_commons-0.2.0/src/mp_commons/application/export/excel_export.py +54 -0
- mp_commons-0.2.0/src/mp_commons/application/export/export_service.py +47 -0
- mp_commons-0.2.0/src/mp_commons/application/export/request.py +28 -0
- mp_commons-0.2.0/src/mp_commons/application/feature_flags/__init__.py +7 -0
- mp_commons-0.2.0/src/mp_commons/application/feature_flags/feature_flag.py +18 -0
- mp_commons-0.2.0/src/mp_commons/application/feature_flags/in_memory.py +32 -0
- mp_commons-0.2.0/src/mp_commons/application/feature_flags/provider.py +25 -0
- mp_commons-0.2.0/src/mp_commons/application/files/__init__.py +28 -0
- mp_commons-0.2.0/src/mp_commons/application/files/processor.py +46 -0
- mp_commons-0.2.0/src/mp_commons/application/files/service.py +103 -0
- mp_commons-0.2.0/src/mp_commons/application/files/upload.py +33 -0
- mp_commons-0.2.0/src/mp_commons/application/files/validator.py +64 -0
- mp_commons-0.2.0/src/mp_commons/application/gdpr/__init__.py +25 -0
- mp_commons-0.2.0/src/mp_commons/application/gdpr/erasure.py +158 -0
- mp_commons-0.2.0/src/mp_commons/application/i18n/__init__.py +17 -0
- mp_commons-0.2.0/src/mp_commons/application/i18n/translator.py +260 -0
- mp_commons-0.2.0/src/mp_commons/application/inbox/__init__.py +18 -0
- mp_commons-0.2.0/src/mp_commons/application/inbox/processor.py +48 -0
- mp_commons-0.2.0/src/mp_commons/application/inbox/store.py +75 -0
- mp_commons-0.2.0/src/mp_commons/application/masking/__init__.py +12 -0
- mp_commons-0.2.0/src/mp_commons/application/masking/log_filter.py +33 -0
- mp_commons-0.2.0/src/mp_commons/application/masking/masker.py +67 -0
- mp_commons-0.2.0/src/mp_commons/application/masking/rules.py +20 -0
- mp_commons-0.2.0/src/mp_commons/application/notifications/__init__.py +19 -0
- mp_commons-0.2.0/src/mp_commons/application/notifications/fcm.py +74 -0
- mp_commons-0.2.0/src/mp_commons/application/notifications/push.py +59 -0
- mp_commons-0.2.0/src/mp_commons/application/notifications/sms.py +51 -0
- mp_commons-0.2.0/src/mp_commons/application/notifications/twilio.py +61 -0
- mp_commons-0.2.0/src/mp_commons/application/pagination/__init__.py +6 -0
- mp_commons-0.2.0/src/mp_commons/application/pagination/page.py +80 -0
- mp_commons-0.2.0/src/mp_commons/application/pagination/page_request.py +51 -0
- mp_commons-0.2.0/src/mp_commons/application/pipeline/__init__.py +39 -0
- mp_commons-0.2.0/src/mp_commons/application/pipeline/audit_middleware.py +86 -0
- mp_commons-0.2.0/src/mp_commons/application/pipeline/middleware.py +20 -0
- mp_commons-0.2.0/src/mp_commons/application/pipeline/middlewares.py +291 -0
- mp_commons-0.2.0/src/mp_commons/application/pipeline/pipeline.py +35 -0
- mp_commons-0.2.0/src/mp_commons/application/rate_limit/__init__.py +17 -0
- mp_commons-0.2.0/src/mp_commons/application/rate_limit/local.py +62 -0
- mp_commons-0.2.0/src/mp_commons/application/rate_limit/rate_limiter.py +58 -0
- mp_commons-0.2.0/src/mp_commons/application/saga/__init__.py +25 -0
- mp_commons-0.2.0/src/mp_commons/application/saga/context.py +48 -0
- mp_commons-0.2.0/src/mp_commons/application/saga/orchestrator.py +171 -0
- mp_commons-0.2.0/src/mp_commons/application/saga/state.py +27 -0
- mp_commons-0.2.0/src/mp_commons/application/saga/step.py +41 -0
- mp_commons-0.2.0/src/mp_commons/application/saga/store.py +71 -0
- mp_commons-0.2.0/src/mp_commons/application/scheduler/__init__.py +17 -0
- mp_commons-0.2.0/src/mp_commons/application/scheduler/apscheduler.py +71 -0
- mp_commons-0.2.0/src/mp_commons/application/scheduler/in_memory.py +44 -0
- mp_commons-0.2.0/src/mp_commons/application/scheduler/job.py +26 -0
- mp_commons-0.2.0/src/mp_commons/application/scheduler/scheduler.py +65 -0
- mp_commons-0.2.0/src/mp_commons/application/search/__init__.py +14 -0
- mp_commons-0.2.0/src/mp_commons/application/search/query.py +33 -0
- mp_commons-0.2.0/src/mp_commons/application/search/result.py +30 -0
- mp_commons-0.2.0/src/mp_commons/application/search/service.py +96 -0
- mp_commons-0.2.0/src/mp_commons/application/uow/__init__.py +7 -0
- mp_commons-0.2.0/src/mp_commons/application/uow/decorators.py +31 -0
- mp_commons-0.2.0/src/mp_commons/application/uow/manager.py +21 -0
- mp_commons-0.2.0/src/mp_commons/application/webhooks/__init__.py +17 -0
- mp_commons-0.2.0/src/mp_commons/application/webhooks/dispatcher.py +91 -0
- mp_commons-0.2.0/src/mp_commons/application/webhooks/endpoint.py +24 -0
- mp_commons-0.2.0/src/mp_commons/application/webhooks/signature.py +26 -0
- mp_commons-0.2.0/src/mp_commons/application/webhooks/store.py +54 -0
- mp_commons-0.2.0/src/mp_commons/application/workflow/__init__.py +27 -0
- mp_commons-0.2.0/src/mp_commons/application/workflow/engine.py +143 -0
- mp_commons-0.2.0/src/mp_commons/application/workflow/state.py +22 -0
- mp_commons-0.2.0/src/mp_commons/application/workflow/transition.py +45 -0
- mp_commons-0.2.0/src/mp_commons/config/__init__.py +15 -0
- mp_commons-0.2.0/src/mp_commons/config/dynamic/__init__.py +19 -0
- mp_commons-0.2.0/src/mp_commons/config/dynamic/source.py +212 -0
- mp_commons-0.2.0/src/mp_commons/config/flags/__init__.py +17 -0
- mp_commons-0.2.0/src/mp_commons/config/flags/provider.py +200 -0
- mp_commons-0.2.0/src/mp_commons/config/secrets/__init__.py +6 -0
- mp_commons-0.2.0/src/mp_commons/config/secrets/kubernetes.py +29 -0
- mp_commons-0.2.0/src/mp_commons/config/secrets/port.py +31 -0
- mp_commons-0.2.0/src/mp_commons/config/settings/__init__.py +19 -0
- mp_commons-0.2.0/src/mp_commons/config/settings/base.py +22 -0
- mp_commons-0.2.0/src/mp_commons/config/settings/factory.py +93 -0
- mp_commons-0.2.0/src/mp_commons/config/settings/loaders.py +79 -0
- mp_commons-0.2.0/src/mp_commons/config/settings/validator.py +23 -0
- mp_commons-0.2.0/src/mp_commons/config/validation/__init__.py +9 -0
- mp_commons-0.2.0/src/mp_commons/config/validation/errors.py +34 -0
- mp_commons-0.2.0/src/mp_commons/kernel/__init__.py +33 -0
- mp_commons-0.2.0/src/mp_commons/kernel/contracts/__init__.py +23 -0
- mp_commons-0.2.0/src/mp_commons/kernel/contracts/compatibility.py +17 -0
- mp_commons-0.2.0/src/mp_commons/kernel/contracts/contract.py +92 -0
- mp_commons-0.2.0/src/mp_commons/kernel/ddd/__init__.py +74 -0
- mp_commons-0.2.0/src/mp_commons/kernel/ddd/aggregate.py +44 -0
- mp_commons-0.2.0/src/mp_commons/kernel/ddd/domain_event.py +63 -0
- mp_commons-0.2.0/src/mp_commons/kernel/ddd/domain_service.py +110 -0
- mp_commons-0.2.0/src/mp_commons/kernel/ddd/entity.py +30 -0
- mp_commons-0.2.0/src/mp_commons/kernel/ddd/event_bus.py +41 -0
- mp_commons-0.2.0/src/mp_commons/kernel/ddd/invariant.py +40 -0
- mp_commons-0.2.0/src/mp_commons/kernel/ddd/outbox_publisher.py +29 -0
- mp_commons-0.2.0/src/mp_commons/kernel/ddd/policies.py +230 -0
- mp_commons-0.2.0/src/mp_commons/kernel/ddd/repository.py +41 -0
- mp_commons-0.2.0/src/mp_commons/kernel/ddd/saga.py +88 -0
- mp_commons-0.2.0/src/mp_commons/kernel/ddd/specification.py +129 -0
- mp_commons-0.2.0/src/mp_commons/kernel/ddd/tenant.py +100 -0
- mp_commons-0.2.0/src/mp_commons/kernel/ddd/unit_of_work.py +35 -0
- mp_commons-0.2.0/src/mp_commons/kernel/ddd/value_object.py +25 -0
- mp_commons-0.2.0/src/mp_commons/kernel/errors/__init__.py +63 -0
- mp_commons-0.2.0/src/mp_commons/kernel/errors/application.py +66 -0
- mp_commons-0.2.0/src/mp_commons/kernel/errors/base.py +57 -0
- mp_commons-0.2.0/src/mp_commons/kernel/errors/domain.py +77 -0
- mp_commons-0.2.0/src/mp_commons/kernel/errors/infrastructure.py +77 -0
- mp_commons-0.2.0/src/mp_commons/kernel/messaging/__init__.py +69 -0
- mp_commons-0.2.0/src/mp_commons/kernel/messaging/dead_letter.py +45 -0
- mp_commons-0.2.0/src/mp_commons/kernel/messaging/idempotency.py +65 -0
- mp_commons-0.2.0/src/mp_commons/kernel/messaging/inbox.py +83 -0
- mp_commons-0.2.0/src/mp_commons/kernel/messaging/message.py +131 -0
- mp_commons-0.2.0/src/mp_commons/kernel/messaging/outbox.py +76 -0
- mp_commons-0.2.0/src/mp_commons/kernel/messaging/scheduled.py +51 -0
- mp_commons-0.2.0/src/mp_commons/kernel/security/__init__.py +53 -0
- mp_commons-0.2.0/src/mp_commons/kernel/security/audit.py +138 -0
- mp_commons-0.2.0/src/mp_commons/kernel/security/crypto.py +28 -0
- mp_commons-0.2.0/src/mp_commons/kernel/security/pii.py +80 -0
- mp_commons-0.2.0/src/mp_commons/kernel/security/pkce.py +151 -0
- mp_commons-0.2.0/src/mp_commons/kernel/security/policy.py +33 -0
- mp_commons-0.2.0/src/mp_commons/kernel/security/principal.py +49 -0
- mp_commons-0.2.0/src/mp_commons/kernel/security/rbac.py +255 -0
- mp_commons-0.2.0/src/mp_commons/kernel/security/security_context.py +44 -0
- mp_commons-0.2.0/src/mp_commons/kernel/time/__init__.py +5 -0
- mp_commons-0.2.0/src/mp_commons/kernel/time/clock.py +57 -0
- mp_commons-0.2.0/src/mp_commons/kernel/types/__init__.py +41 -0
- mp_commons-0.2.0/src/mp_commons/kernel/types/email.py +51 -0
- mp_commons-0.2.0/src/mp_commons/kernel/types/ids.py +105 -0
- mp_commons-0.2.0/src/mp_commons/kernel/types/money.py +81 -0
- mp_commons-0.2.0/src/mp_commons/kernel/types/option.py +100 -0
- mp_commons-0.2.0/src/mp_commons/kernel/types/phone.py +94 -0
- mp_commons-0.2.0/src/mp_commons/kernel/types/result.py +94 -0
- mp_commons-0.2.0/src/mp_commons/kernel/types/slug.py +47 -0
- mp_commons-0.2.0/src/mp_commons/kernel/types/uid.py +100 -0
- mp_commons-0.2.0/src/mp_commons/observability/__init__.py +21 -0
- mp_commons-0.2.0/src/mp_commons/observability/correlation/__init__.py +6 -0
- mp_commons-0.2.0/src/mp_commons/observability/correlation/context.py +90 -0
- mp_commons-0.2.0/src/mp_commons/observability/correlation/provider.py +16 -0
- mp_commons-0.2.0/src/mp_commons/observability/events/__init__.py +19 -0
- mp_commons-0.2.0/src/mp_commons/observability/events/emitter.py +154 -0
- mp_commons-0.2.0/src/mp_commons/observability/health/__init__.py +31 -0
- mp_commons-0.2.0/src/mp_commons/observability/health/adapters.py +218 -0
- mp_commons-0.2.0/src/mp_commons/observability/health/builtin.py +91 -0
- mp_commons-0.2.0/src/mp_commons/observability/health/check.py +34 -0
- mp_commons-0.2.0/src/mp_commons/observability/health/registry.py +58 -0
- mp_commons-0.2.0/src/mp_commons/observability/logging/__init__.py +22 -0
- mp_commons-0.2.0/src/mp_commons/observability/logging/async_handler.py +147 -0
- mp_commons-0.2.0/src/mp_commons/observability/logging/audit.py +137 -0
- mp_commons-0.2.0/src/mp_commons/observability/logging/factory.py +64 -0
- mp_commons-0.2.0/src/mp_commons/observability/logging/filters.py +34 -0
- mp_commons-0.2.0/src/mp_commons/observability/logging/processors.py +77 -0
- mp_commons-0.2.0/src/mp_commons/observability/logging/protocol.py +33 -0
- mp_commons-0.2.0/src/mp_commons/observability/logging/sampled.py +108 -0
- mp_commons-0.2.0/src/mp_commons/observability/metrics/__init__.py +15 -0
- mp_commons-0.2.0/src/mp_commons/observability/metrics/business.py +25 -0
- mp_commons-0.2.0/src/mp_commons/observability/metrics/noop.py +48 -0
- mp_commons-0.2.0/src/mp_commons/observability/metrics/ports.py +60 -0
- mp_commons-0.2.0/src/mp_commons/observability/profiling/__init__.py +10 -0
- mp_commons-0.2.0/src/mp_commons/observability/profiling/sampler.py +98 -0
- mp_commons-0.2.0/src/mp_commons/observability/slo/__init__.py +19 -0
- mp_commons-0.2.0/src/mp_commons/observability/slo/tracker.py +109 -0
- mp_commons-0.2.0/src/mp_commons/observability/tracing/__init__.py +6 -0
- mp_commons-0.2.0/src/mp_commons/observability/tracing/noop.py +48 -0
- mp_commons-0.2.0/src/mp_commons/observability/tracing/ports.py +76 -0
- mp_commons-0.2.0/src/mp_commons/py.typed +0 -0
- mp_commons-0.2.0/src/mp_commons/resilience/__init__.py +50 -0
- mp_commons-0.2.0/src/mp_commons/resilience/backpressure.py +135 -0
- mp_commons-0.2.0/src/mp_commons/resilience/bulkhead/__init__.py +7 -0
- mp_commons-0.2.0/src/mp_commons/resilience/bulkhead/bulkhead.py +23 -0
- mp_commons-0.2.0/src/mp_commons/resilience/bulkhead/errors.py +14 -0
- mp_commons-0.2.0/src/mp_commons/resilience/bulkhead/limiters.py +52 -0
- mp_commons-0.2.0/src/mp_commons/resilience/cache/__init__.py +5 -0
- mp_commons-0.2.0/src/mp_commons/resilience/cache/aside.py +87 -0
- mp_commons-0.2.0/src/mp_commons/resilience/circuit_breaker/__init__.py +15 -0
- mp_commons-0.2.0/src/mp_commons/resilience/circuit_breaker/breaker.py +92 -0
- mp_commons-0.2.0/src/mp_commons/resilience/circuit_breaker/errors.py +27 -0
- mp_commons-0.2.0/src/mp_commons/resilience/circuit_breaker/policy.py +19 -0
- mp_commons-0.2.0/src/mp_commons/resilience/circuit_breaker/redis_breaker.py +247 -0
- mp_commons-0.2.0/src/mp_commons/resilience/circuit_breaker/state.py +16 -0
- mp_commons-0.2.0/src/mp_commons/resilience/dead_letter_scheduler.py +166 -0
- mp_commons-0.2.0/src/mp_commons/resilience/deadline/__init__.py +9 -0
- mp_commons-0.2.0/src/mp_commons/resilience/deadline/context.py +75 -0
- mp_commons-0.2.0/src/mp_commons/resilience/fallback/__init__.py +5 -0
- mp_commons-0.2.0/src/mp_commons/resilience/fallback/policy.py +70 -0
- mp_commons-0.2.0/src/mp_commons/resilience/graceful_shutdown.py +194 -0
- mp_commons-0.2.0/src/mp_commons/resilience/hedge/__init__.py +5 -0
- mp_commons-0.2.0/src/mp_commons/resilience/hedge/policy.py +69 -0
- mp_commons-0.2.0/src/mp_commons/resilience/retry/__init__.py +25 -0
- mp_commons-0.2.0/src/mp_commons/resilience/retry/backoff.py +47 -0
- mp_commons-0.2.0/src/mp_commons/resilience/retry/jitter.py +36 -0
- mp_commons-0.2.0/src/mp_commons/resilience/retry/policy.py +83 -0
- mp_commons-0.2.0/src/mp_commons/resilience/retry/tenacity_adapter.py +114 -0
- mp_commons-0.2.0/src/mp_commons/resilience/throttle/__init__.py +9 -0
- mp_commons-0.2.0/src/mp_commons/resilience/throttle/token_bucket.py +79 -0
- mp_commons-0.2.0/src/mp_commons/resilience/timeouts/__init__.py +6 -0
- mp_commons-0.2.0/src/mp_commons/resilience/timeouts/deadline.py +34 -0
- mp_commons-0.2.0/src/mp_commons/resilience/timeouts/policy.py +28 -0
- mp_commons-0.2.0/src/mp_commons/security/__init__.py +32 -0
- mp_commons-0.2.0/src/mp_commons/security/apikeys/__init__.py +19 -0
- mp_commons-0.2.0/src/mp_commons/security/apikeys/generator.py +113 -0
- mp_commons-0.2.0/src/mp_commons/security/apikeys/hash_upgrade.py +192 -0
- mp_commons-0.2.0/src/mp_commons/security/encryption/__init__.py +15 -0
- mp_commons-0.2.0/src/mp_commons/security/encryption/fernet.py +63 -0
- mp_commons-0.2.0/src/mp_commons/security/encryption/key_rotation.py +47 -0
- mp_commons-0.2.0/src/mp_commons/security/jwt/__init__.py +5 -0
- mp_commons-0.2.0/src/mp_commons/security/jwt/decoder.py +114 -0
- mp_commons-0.2.0/src/mp_commons/security/rotation/__init__.py +19 -0
- mp_commons-0.2.0/src/mp_commons/security/rotation/rotator.py +140 -0
- mp_commons-0.2.0/src/mp_commons/security/tls/__init__.py +18 -0
- mp_commons-0.2.0/src/mp_commons/security/tls/certificates.py +147 -0
- mp_commons-0.2.0/src/mp_commons/security/tls/pinning.py +44 -0
- mp_commons-0.2.0/src/mp_commons/testing/__init__.py +51 -0
- mp_commons-0.2.0/src/mp_commons/testing/approval/__init__.py +19 -0
- mp_commons-0.2.0/src/mp_commons/testing/approval/asserter.py +157 -0
- mp_commons-0.2.0/src/mp_commons/testing/approval/plugin.py +125 -0
- mp_commons-0.2.0/src/mp_commons/testing/chaos/__init__.py +7 -0
- mp_commons-0.2.0/src/mp_commons/testing/chaos/failure.py +36 -0
- mp_commons-0.2.0/src/mp_commons/testing/chaos/latency.py +26 -0
- mp_commons-0.2.0/src/mp_commons/testing/chaos/toxiproxy.py +96 -0
- mp_commons-0.2.0/src/mp_commons/testing/contracts/__init__.py +11 -0
- mp_commons-0.2.0/src/mp_commons/testing/contracts/asyncapi.py +26 -0
- mp_commons-0.2.0/src/mp_commons/testing/contracts/compatibility.py +35 -0
- mp_commons-0.2.0/src/mp_commons/testing/contracts/openapi.py +39 -0
- mp_commons-0.2.0/src/mp_commons/testing/databases/__init__.py +15 -0
- mp_commons-0.2.0/src/mp_commons/testing/fakes/__init__.py +25 -0
- mp_commons-0.2.0/src/mp_commons/testing/fakes/clock.py +15 -0
- mp_commons-0.2.0/src/mp_commons/testing/fakes/feature_flags.py +73 -0
- mp_commons-0.2.0/src/mp_commons/testing/fakes/idempotency.py +33 -0
- mp_commons-0.2.0/src/mp_commons/testing/fakes/inbox.py +60 -0
- mp_commons-0.2.0/src/mp_commons/testing/fakes/message_bus.py +33 -0
- mp_commons-0.2.0/src/mp_commons/testing/fakes/metrics.py +133 -0
- mp_commons-0.2.0/src/mp_commons/testing/fakes/outbox.py +55 -0
- mp_commons-0.2.0/src/mp_commons/testing/fakes/policy.py +34 -0
- mp_commons-0.2.0/src/mp_commons/testing/fakes/secrets.py +63 -0
- mp_commons-0.2.0/src/mp_commons/testing/fixtures/__init__.py +32 -0
- mp_commons-0.2.0/src/mp_commons/testing/fixtures/clock.py +18 -0
- mp_commons-0.2.0/src/mp_commons/testing/fixtures/correlation.py +20 -0
- mp_commons-0.2.0/src/mp_commons/testing/fixtures/database.py +97 -0
- mp_commons-0.2.0/src/mp_commons/testing/fixtures/message_bus.py +35 -0
- mp_commons-0.2.0/src/mp_commons/testing/fixtures/principal.py +44 -0
- mp_commons-0.2.0/src/mp_commons/testing/fixtures/security.py +17 -0
- mp_commons-0.2.0/src/mp_commons/testing/fixtures/tenant.py +21 -0
- mp_commons-0.2.0/src/mp_commons/testing/generators/__init__.py +31 -0
- mp_commons-0.2.0/src/mp_commons/testing/generators/builder.py +110 -0
- mp_commons-0.2.0/src/mp_commons/testing/generators/domain_gen.py +47 -0
- mp_commons-0.2.0/src/mp_commons/testing/generators/id_gen.py +22 -0
- mp_commons-0.2.0/src/mp_commons/testing/generators/step_clock.py +88 -0
- mp_commons-0.2.0/src/mp_commons/testing/generators/strategies.py +131 -0
- mp_commons-0.2.0/src/mp_commons/testing/http/__init__.py +13 -0
- mp_commons-0.2.0/src/mp_commons/testing/http/stub_server.py +127 -0
- mp_commons-0.2.0/src/mp_commons/testing/load/__init__.py +14 -0
- mp_commons-0.2.0/src/mp_commons/testing/load/locust_helpers.py +192 -0
- mp_commons-0.2.0/src/mp_commons/testing/load/runner.py +160 -0
- mp_commons-0.2.0/src/mp_commons/testing/performance/__init__.py +17 -0
- mp_commons-0.2.0/src/mp_commons/testing/performance/assertions.py +73 -0
- mp_commons-0.2.0/src/mp_commons/testing/snapshot/__init__.py +12 -0
- mp_commons-0.2.0/src/mp_commons/testing/snapshot/asserter.py +80 -0
- mp_commons-0.2.0/src/mp_commons/testing/snapshot/serializer.py +42 -0
- mp_commons-0.2.0/src/mp_commons/testing/tenant_isolation.py +146 -0
- mp_commons-0.2.0/tests/__init__.py +0 -0
- mp_commons-0.2.0/tests/benchmarks/__init__.py +12 -0
- mp_commons-0.2.0/tests/benchmarks/bench_circuit_breaker.py +72 -0
- mp_commons-0.2.0/tests/benchmarks/bench_command_bus.py +115 -0
- mp_commons-0.2.0/tests/benchmarks/bench_entity_id.py +85 -0
- mp_commons-0.2.0/tests/benchmarks/bench_logging.py +174 -0
- mp_commons-0.2.0/tests/benchmarks/bench_rate_limiter.py +96 -0
- mp_commons-0.2.0/tests/benchmarks/bench_retry.py +87 -0
- mp_commons-0.2.0/tests/benchmarks/conftest.py +38 -0
- mp_commons-0.2.0/tests/conftest.py +5 -0
- mp_commons-0.2.0/tests/integration/__init__.py +0 -0
- mp_commons-0.2.0/tests/integration/test_cassandra.py +152 -0
- mp_commons-0.2.0/tests/integration/test_dynamodb.py +125 -0
- mp_commons-0.2.0/tests/integration/test_e2e_outbox_kafka.py +169 -0
- mp_commons-0.2.0/tests/integration/test_elasticsearch.py +132 -0
- mp_commons-0.2.0/tests/integration/test_kafka.py +221 -0
- mp_commons-0.2.0/tests/integration/test_keycloak.py +167 -0
- mp_commons-0.2.0/tests/integration/test_mongodb.py +378 -0
- mp_commons-0.2.0/tests/integration/test_nats.py +134 -0
- mp_commons-0.2.0/tests/integration/test_placeholder.py +43 -0
- mp_commons-0.2.0/tests/integration/test_postgres.py +325 -0
- mp_commons-0.2.0/tests/integration/test_pulsar.py +86 -0
- mp_commons-0.2.0/tests/integration/test_rabbitmq.py +170 -0
- mp_commons-0.2.0/tests/integration/test_redis.py +312 -0
- mp_commons-0.2.0/tests/integration/test_redis_streams.py +133 -0
- mp_commons-0.2.0/tests/integration/test_s3.py +150 -0
- mp_commons-0.2.0/tests/integration/test_saga_postgres.py +271 -0
- mp_commons-0.2.0/tests/integration/test_vault.py +139 -0
- mp_commons-0.2.0/tests/unit/__init__.py +0 -0
- mp_commons-0.2.0/tests/unit/adapters/__init__.py +1 -0
- mp_commons-0.2.0/tests/unit/adapters/test_alembic_migrations.py +143 -0
- mp_commons-0.2.0/tests/unit/adapters/test_azure_blob.py +110 -0
- mp_commons-0.2.0/tests/unit/adapters/test_azure_keyvault.py +117 -0
- mp_commons-0.2.0/tests/unit/adapters/test_azure_servicebus.py +144 -0
- mp_commons-0.2.0/tests/unit/adapters/test_cassandra.py +161 -0
- mp_commons-0.2.0/tests/unit/adapters/test_celery.py +155 -0
- mp_commons-0.2.0/tests/unit/adapters/test_dynamodb.py +214 -0
- mp_commons-0.2.0/tests/unit/adapters/test_elasticsearch.py +233 -0
- mp_commons-0.2.0/tests/unit/adapters/test_fastapi_adapter.py +606 -0
- mp_commons-0.2.0/tests/unit/adapters/test_fastapi_security_middleware.py +215 -0
- mp_commons-0.2.0/tests/unit/adapters/test_gcp_pubsub.py +117 -0
- mp_commons-0.2.0/tests/unit/adapters/test_gcs.py +95 -0
- mp_commons-0.2.0/tests/unit/adapters/test_graphql.py +129 -0
- mp_commons-0.2.0/tests/unit/adapters/test_grpc.py +153 -0
- mp_commons-0.2.0/tests/unit/adapters/test_grpc_server.py +284 -0
- mp_commons-0.2.0/tests/unit/adapters/test_http_clients.py +226 -0
- mp_commons-0.2.0/tests/unit/adapters/test_kafka_adapters.py +368 -0
- mp_commons-0.2.0/tests/unit/adapters/test_keycloak.py +263 -0
- mp_commons-0.2.0/tests/unit/adapters/test_mailgun.py +147 -0
- mp_commons-0.2.0/tests/unit/adapters/test_nats_adapters.py +181 -0
- mp_commons-0.2.0/tests/unit/adapters/test_nats_propagation.py +168 -0
- mp_commons-0.2.0/tests/unit/adapters/test_opensearch.py +206 -0
- mp_commons-0.2.0/tests/unit/adapters/test_opentelemetry_adapters.py +445 -0
- mp_commons-0.2.0/tests/unit/adapters/test_otel_instrumentation.py +198 -0
- mp_commons-0.2.0/tests/unit/adapters/test_prometheus.py +219 -0
- mp_commons-0.2.0/tests/unit/adapters/test_pulsar.py +226 -0
- mp_commons-0.2.0/tests/unit/adapters/test_rabbitmq_adapters.py +225 -0
- mp_commons-0.2.0/tests/unit/adapters/test_redis_adapters.py +415 -0
- mp_commons-0.2.0/tests/unit/adapters/test_redis_streams.py +203 -0
- mp_commons-0.2.0/tests/unit/adapters/test_s3.py +246 -0
- mp_commons-0.2.0/tests/unit/adapters/test_sendgrid.py +117 -0
- mp_commons-0.2.0/tests/unit/adapters/test_sqlalchemy_sqla.py +794 -0
- mp_commons-0.2.0/tests/unit/adapters/test_sqs.py +267 -0
- mp_commons-0.2.0/tests/unit/adapters/test_vault_adapters.py +244 -0
- mp_commons-0.2.0/tests/unit/adapters/test_websocket.py +197 -0
- mp_commons-0.2.0/tests/unit/application/__init__.py +0 -0
- mp_commons-0.2.0/tests/unit/application/test_async_lru_cache.py +135 -0
- mp_commons-0.2.0/tests/unit/application/test_cache.py +131 -0
- mp_commons-0.2.0/tests/unit/application/test_cqrs.py +289 -0
- mp_commons-0.2.0/tests/unit/application/test_cqrs_decorators.py +179 -0
- mp_commons-0.2.0/tests/unit/application/test_email.py +116 -0
- mp_commons-0.2.0/tests/unit/application/test_event_sourcing.py +562 -0
- mp_commons-0.2.0/tests/unit/application/test_export.py +191 -0
- mp_commons-0.2.0/tests/unit/application/test_feature_flags.py +118 -0
- mp_commons-0.2.0/tests/unit/application/test_files.py +230 -0
- mp_commons-0.2.0/tests/unit/application/test_gdpr.py +120 -0
- mp_commons-0.2.0/tests/unit/application/test_i18n.py +239 -0
- mp_commons-0.2.0/tests/unit/application/test_inbox.py +75 -0
- mp_commons-0.2.0/tests/unit/application/test_masking.py +119 -0
- mp_commons-0.2.0/tests/unit/application/test_notifications.py +164 -0
- mp_commons-0.2.0/tests/unit/application/test_pagination.py +151 -0
- mp_commons-0.2.0/tests/unit/application/test_pipeline.py +794 -0
- mp_commons-0.2.0/tests/unit/application/test_rate_limit.py +129 -0
- mp_commons-0.2.0/tests/unit/application/test_saga.py +472 -0
- mp_commons-0.2.0/tests/unit/application/test_scheduler.py +213 -0
- mp_commons-0.2.0/tests/unit/application/test_search.py +125 -0
- mp_commons-0.2.0/tests/unit/application/test_uow.py +183 -0
- mp_commons-0.2.0/tests/unit/application/test_webhooks.py +214 -0
- mp_commons-0.2.0/tests/unit/application/test_workflow.py +130 -0
- mp_commons-0.2.0/tests/unit/config/__init__.py +0 -0
- mp_commons-0.2.0/tests/unit/config/test_dynamic.py +166 -0
- mp_commons-0.2.0/tests/unit/config/test_flags.py +221 -0
- mp_commons-0.2.0/tests/unit/config/test_secrets.py +113 -0
- mp_commons-0.2.0/tests/unit/config/test_settings.py +147 -0
- mp_commons-0.2.0/tests/unit/config/test_settings_factory.py +145 -0
- mp_commons-0.2.0/tests/unit/config/test_validation.py +81 -0
- mp_commons-0.2.0/tests/unit/kernel/__init__.py +0 -0
- mp_commons-0.2.0/tests/unit/kernel/security/__init__.py +0 -0
- mp_commons-0.2.0/tests/unit/kernel/security/test_pkce.py +181 -0
- mp_commons-0.2.0/tests/unit/kernel/test_audit.py +499 -0
- mp_commons-0.2.0/tests/unit/kernel/test_contracts.py +204 -0
- mp_commons-0.2.0/tests/unit/kernel/test_ddd.py +966 -0
- mp_commons-0.2.0/tests/unit/kernel/test_errors.py +173 -0
- mp_commons-0.2.0/tests/unit/kernel/test_messaging.py +369 -0
- mp_commons-0.2.0/tests/unit/kernel/test_money_properties.py +165 -0
- mp_commons-0.2.0/tests/unit/kernel/test_pii_redaction_fuzz.py +148 -0
- mp_commons-0.2.0/tests/unit/kernel/test_result_properties.py +175 -0
- mp_commons-0.2.0/tests/unit/kernel/test_security.py +481 -0
- mp_commons-0.2.0/tests/unit/kernel/test_time.py +154 -0
- mp_commons-0.2.0/tests/unit/kernel/test_types.py +399 -0
- mp_commons-0.2.0/tests/unit/observability/__init__.py +0 -0
- mp_commons-0.2.0/tests/unit/observability/test_adapter_health_checks.py +205 -0
- mp_commons-0.2.0/tests/unit/observability/test_correlation.py +75 -0
- mp_commons-0.2.0/tests/unit/observability/test_correlation_headers.py +72 -0
- mp_commons-0.2.0/tests/unit/observability/test_events.py +169 -0
- mp_commons-0.2.0/tests/unit/observability/test_health.py +99 -0
- mp_commons-0.2.0/tests/unit/observability/test_logging.py +207 -0
- mp_commons-0.2.0/tests/unit/observability/test_logging_extras.py +541 -0
- mp_commons-0.2.0/tests/unit/observability/test_metrics.py +277 -0
- mp_commons-0.2.0/tests/unit/observability/test_profiling.py +55 -0
- mp_commons-0.2.0/tests/unit/observability/test_slo.py +108 -0
- mp_commons-0.2.0/tests/unit/observability/test_tracing.py +219 -0
- mp_commons-0.2.0/tests/unit/resilience/__init__.py +0 -0
- mp_commons-0.2.0/tests/unit/resilience/test_backpressure.py +75 -0
- mp_commons-0.2.0/tests/unit/resilience/test_bulkhead.py +156 -0
- mp_commons-0.2.0/tests/unit/resilience/test_cache_aside.py +83 -0
- mp_commons-0.2.0/tests/unit/resilience/test_circuit_breaker.py +160 -0
- mp_commons-0.2.0/tests/unit/resilience/test_circuit_breaker_stress.py +172 -0
- mp_commons-0.2.0/tests/unit/resilience/test_dead_letter_scheduler.py +219 -0
- mp_commons-0.2.0/tests/unit/resilience/test_deadline.py +92 -0
- mp_commons-0.2.0/tests/unit/resilience/test_fallback.py +106 -0
- mp_commons-0.2.0/tests/unit/resilience/test_graceful_shutdown.py +113 -0
- mp_commons-0.2.0/tests/unit/resilience/test_hedge.py +70 -0
- mp_commons-0.2.0/tests/unit/resilience/test_redis_circuit_breaker.py +269 -0
- mp_commons-0.2.0/tests/unit/resilience/test_retry.py +296 -0
- mp_commons-0.2.0/tests/unit/resilience/test_throttle.py +67 -0
- mp_commons-0.2.0/tests/unit/resilience/test_timeouts.py +115 -0
- mp_commons-0.2.0/tests/unit/security/__init__.py +1 -0
- mp_commons-0.2.0/tests/unit/security/test_apikeys.py +124 -0
- mp_commons-0.2.0/tests/unit/security/test_encryption.py +104 -0
- mp_commons-0.2.0/tests/unit/security/test_hash_upgrade.py +241 -0
- mp_commons-0.2.0/tests/unit/security/test_jwt.py +97 -0
- mp_commons-0.2.0/tests/unit/security/test_rotation.py +128 -0
- mp_commons-0.2.0/tests/unit/security/test_tls.py +74 -0
- mp_commons-0.2.0/tests/unit/test_example_service.py +66 -0
- mp_commons-0.2.0/tests/unit/test_trio_compat.py +208 -0
- mp_commons-0.2.0/tests/unit/testing/__init__.py +0 -0
- mp_commons-0.2.0/tests/unit/testing/test_approval.py +253 -0
- mp_commons-0.2.0/tests/unit/testing/test_builder.py +181 -0
- mp_commons-0.2.0/tests/unit/testing/test_chaos.py +176 -0
- mp_commons-0.2.0/tests/unit/testing/test_contracts.py +241 -0
- mp_commons-0.2.0/tests/unit/testing/test_db_fixtures.py +108 -0
- mp_commons-0.2.0/tests/unit/testing/test_fakes.py +381 -0
- mp_commons-0.2.0/tests/unit/testing/test_fixtures.py +165 -0
- mp_commons-0.2.0/tests/unit/testing/test_generators.py +137 -0
- mp_commons-0.2.0/tests/unit/testing/test_http_stubs.py +108 -0
- mp_commons-0.2.0/tests/unit/testing/test_load.py +284 -0
- mp_commons-0.2.0/tests/unit/testing/test_new_testing_utils.py +376 -0
- mp_commons-0.2.0/tests/unit/testing/test_performance.py +86 -0
- mp_commons-0.2.0/tests/unit/testing/test_snapshot.py +147 -0
- mp_commons-0.2.0/tests/unit/testing/test_strategies.py +420 -0
- mp_commons-0.2.0/tests/unit/testing/test_tenant_isolation_validator.py +117 -0
- 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,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 }}
|