hexcore 7.0.0__tar.gz → 9.0.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.
- hexcore-9.0.0/PKG-INFO +340 -0
- hexcore-9.0.0/README.md +265 -0
- hexcore-9.0.0/hexcore/__init__.py +86 -0
- hexcore-9.0.0/hexcore/_deprecation.py +206 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/application/cqrs/in_memory_buses.py +24 -5
- hexcore-9.0.0/hexcore/application/eventsourcing/__init__.py +14 -0
- hexcore-9.0.0/hexcore/application/eventsourcing/config.py +115 -0
- hexcore-9.0.0/hexcore/application/eventsourcing/factory.py +208 -0
- hexcore-9.0.0/hexcore/application/eventsourcing/projector.py +301 -0
- hexcore-9.0.0/hexcore/application/eventsourcing/relay.py +202 -0
- hexcore-9.0.0/hexcore/application/eventsourcing/repository.py +211 -0
- hexcore-9.0.0/hexcore/capabilities.py +145 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/config.py +78 -27
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/cqrs.py +48 -1
- hexcore-9.0.0/hexcore/cqrs.pyi +146 -0
- hexcore-9.0.0/hexcore/darwin/__init__.py +499 -0
- hexcore-9.0.0/hexcore/darwin/__init__.pyi +402 -0
- hexcore-9.0.0/hexcore/darwin/application/__init__.py +6 -0
- hexcore-9.0.0/hexcore/darwin/application/commands.py +360 -0
- hexcore-9.0.0/hexcore/darwin/application/config.py +355 -0
- hexcore-9.0.0/hexcore/darwin/application/container.py +573 -0
- hexcore-9.0.0/hexcore/darwin/application/hooks.py +130 -0
- hexcore-9.0.0/hexcore/darwin/application/plugins.py +397 -0
- hexcore-9.0.0/hexcore/darwin/application/services.py +840 -0
- hexcore-9.0.0/hexcore/darwin/domain/__init__.py +8 -0
- hexcore-9.0.0/hexcore/darwin/domain/context.py +390 -0
- hexcore-9.0.0/hexcore/darwin/domain/entities.py +201 -0
- hexcore-9.0.0/hexcore/darwin/domain/events.py +181 -0
- hexcore-9.0.0/hexcore/darwin/domain/exceptions.py +208 -0
- hexcore-9.0.0/hexcore/darwin/domain/permissions.py +321 -0
- hexcore-9.0.0/hexcore/darwin/domain/plugins.py +311 -0
- hexcore-9.0.0/hexcore/darwin/domain/ports.py +343 -0
- hexcore-9.0.0/hexcore/darwin/domain/value_objects.py +232 -0
- hexcore-9.0.0/hexcore/darwin/infrastructure/__init__.py +8 -0
- hexcore-9.0.0/hexcore/darwin/infrastructure/api/__init__.py +7 -0
- hexcore-9.0.0/hexcore/darwin/infrastructure/api/dependencies.py +176 -0
- hexcore-9.0.0/hexcore/darwin/infrastructure/api/middlewares.py +289 -0
- hexcore-9.0.0/hexcore/darwin/infrastructure/api/routers.py +457 -0
- hexcore-9.0.0/hexcore/darwin/infrastructure/cli.py +175 -0
- hexcore-9.0.0/hexcore/darwin/infrastructure/clock.py +79 -0
- hexcore-9.0.0/hexcore/darwin/infrastructure/envelope.py +429 -0
- hexcore-9.0.0/hexcore/darwin/infrastructure/hashing.py +213 -0
- hexcore-9.0.0/hexcore/darwin/infrastructure/keys.py +308 -0
- hexcore-9.0.0/hexcore/darwin/infrastructure/lifespan.py +205 -0
- hexcore-9.0.0/hexcore/darwin/infrastructure/orms/__init__.py +13 -0
- hexcore-9.0.0/hexcore/darwin/infrastructure/orms/beanie/__init__.py +6 -0
- hexcore-9.0.0/hexcore/darwin/infrastructure/orms/beanie/documents.py +313 -0
- hexcore-9.0.0/hexcore/darwin/infrastructure/orms/beanie/repositories.py +572 -0
- hexcore-9.0.0/hexcore/darwin/infrastructure/orms/beanie/schema.py +174 -0
- hexcore-9.0.0/hexcore/darwin/infrastructure/orms/selection.py +136 -0
- hexcore-9.0.0/hexcore/darwin/infrastructure/orms/sqlalchemy/__init__.py +10 -0
- hexcore-9.0.0/hexcore/darwin/infrastructure/orms/sqlalchemy/models.py +97 -0
- hexcore-9.0.0/hexcore/darwin/infrastructure/orms/sqlalchemy/models_mixins.py +400 -0
- hexcore-9.0.0/hexcore/darwin/infrastructure/orms/sqlalchemy/repositories.py +682 -0
- hexcore-9.0.0/hexcore/darwin/infrastructure/orms/sqlalchemy/schema.py +287 -0
- hexcore-9.0.0/hexcore/darwin/infrastructure/revocation.py +299 -0
- hexcore-9.0.0/hexcore/darwin/infrastructure/secretbox.py +117 -0
- hexcore-9.0.0/hexcore/darwin/infrastructure/tokens.py +398 -0
- hexcore-9.0.0/hexcore/darwin/infrastructure/transports.py +277 -0
- hexcore-9.0.0/hexcore/darwin/plugins/__init__.py +6 -0
- hexcore-9.0.0/hexcore/darwin/plugins/impersonate/__init__.py +244 -0
- hexcore-9.0.0/hexcore/darwin/plugins/impersonate/commands.py +76 -0
- hexcore-9.0.0/hexcore/darwin/plugins/impersonate/domain.py +208 -0
- hexcore-9.0.0/hexcore/darwin/plugins/impersonate/router.py +194 -0
- hexcore-9.0.0/hexcore/darwin/plugins/impersonate/service.py +310 -0
- hexcore-9.0.0/hexcore/darwin/plugins/magic_link/__init__.py +124 -0
- hexcore-9.0.0/hexcore/darwin/plugins/magic_link/commands.py +233 -0
- hexcore-9.0.0/hexcore/darwin/plugins/magic_link/router.py +152 -0
- hexcore-9.0.0/hexcore/darwin/plugins/oauth/__init__.py +320 -0
- hexcore-9.0.0/hexcore/darwin/plugins/oauth/domain.py +252 -0
- hexcore-9.0.0/hexcore/darwin/plugins/oauth/http.py +219 -0
- hexcore-9.0.0/hexcore/darwin/plugins/oauth/orms/__init__.py +13 -0
- hexcore-9.0.0/hexcore/darwin/plugins/oauth/orms/beanie/__init__.py +6 -0
- hexcore-9.0.0/hexcore/darwin/plugins/oauth/orms/beanie/repository.py +148 -0
- hexcore-9.0.0/hexcore/darwin/plugins/oauth/orms/sqlalchemy/__init__.py +10 -0
- hexcore-9.0.0/hexcore/darwin/plugins/oauth/orms/sqlalchemy/models.py +80 -0
- hexcore-9.0.0/hexcore/darwin/plugins/oauth/orms/sqlalchemy/models_mixins.py +115 -0
- hexcore-9.0.0/hexcore/darwin/plugins/oauth/orms/sqlalchemy/repository.py +136 -0
- hexcore-9.0.0/hexcore/darwin/plugins/oauth/providers.py +278 -0
- hexcore-9.0.0/hexcore/darwin/plugins/oauth/router.py +249 -0
- hexcore-9.0.0/hexcore/darwin/plugins/oauth/service.py +575 -0
- hexcore-9.0.0/hexcore/darwin/plugins/organization/__init__.py +247 -0
- hexcore-9.0.0/hexcore/darwin/plugins/organization/domain.py +345 -0
- hexcore-9.0.0/hexcore/darwin/plugins/organization/orms/__init__.py +13 -0
- hexcore-9.0.0/hexcore/darwin/plugins/organization/orms/beanie/__init__.py +6 -0
- hexcore-9.0.0/hexcore/darwin/plugins/organization/orms/beanie/repository.py +557 -0
- hexcore-9.0.0/hexcore/darwin/plugins/organization/orms/sqlalchemy/__init__.py +10 -0
- hexcore-9.0.0/hexcore/darwin/plugins/organization/orms/sqlalchemy/models.py +114 -0
- hexcore-9.0.0/hexcore/darwin/plugins/organization/orms/sqlalchemy/models_mixins.py +193 -0
- hexcore-9.0.0/hexcore/darwin/plugins/organization/orms/sqlalchemy/repository.py +428 -0
- hexcore-9.0.0/hexcore/darwin/plugins/organization/router.py +351 -0
- hexcore-9.0.0/hexcore/darwin/plugins/organization/service.py +579 -0
- hexcore-9.0.0/hexcore/darwin/plugins/passkey/__init__.py +319 -0
- hexcore-9.0.0/hexcore/darwin/plugins/passkey/domain.py +322 -0
- hexcore-9.0.0/hexcore/darwin/plugins/passkey/orms/__init__.py +13 -0
- hexcore-9.0.0/hexcore/darwin/plugins/passkey/orms/beanie/__init__.py +6 -0
- hexcore-9.0.0/hexcore/darwin/plugins/passkey/orms/beanie/repository.py +274 -0
- hexcore-9.0.0/hexcore/darwin/plugins/passkey/orms/sqlalchemy/__init__.py +10 -0
- hexcore-9.0.0/hexcore/darwin/plugins/passkey/orms/sqlalchemy/models.py +114 -0
- hexcore-9.0.0/hexcore/darwin/plugins/passkey/orms/sqlalchemy/models_mixins.py +173 -0
- hexcore-9.0.0/hexcore/darwin/plugins/passkey/orms/sqlalchemy/repository.py +257 -0
- hexcore-9.0.0/hexcore/darwin/plugins/passkey/router.py +286 -0
- hexcore-9.0.0/hexcore/darwin/plugins/passkey/service.py +419 -0
- hexcore-9.0.0/hexcore/darwin/plugins/passkey/webauthn_adapter.py +257 -0
- hexcore-9.0.0/hexcore/darwin/plugins/storage.py +166 -0
- hexcore-9.0.0/hexcore/darwin/plugins/two_factor/__init__.py +260 -0
- hexcore-9.0.0/hexcore/darwin/plugins/two_factor/commands.py +121 -0
- hexcore-9.0.0/hexcore/darwin/plugins/two_factor/crypto.py +43 -0
- hexcore-9.0.0/hexcore/darwin/plugins/two_factor/domain.py +192 -0
- hexcore-9.0.0/hexcore/darwin/plugins/two_factor/orms/__init__.py +13 -0
- hexcore-9.0.0/hexcore/darwin/plugins/two_factor/orms/beanie/__init__.py +6 -0
- hexcore-9.0.0/hexcore/darwin/plugins/two_factor/orms/beanie/repository.py +210 -0
- hexcore-9.0.0/hexcore/darwin/plugins/two_factor/orms/sqlalchemy/__init__.py +10 -0
- hexcore-9.0.0/hexcore/darwin/plugins/two_factor/orms/sqlalchemy/models.py +82 -0
- hexcore-9.0.0/hexcore/darwin/plugins/two_factor/orms/sqlalchemy/models_mixins.py +113 -0
- hexcore-9.0.0/hexcore/darwin/plugins/two_factor/orms/sqlalchemy/repository.py +224 -0
- hexcore-9.0.0/hexcore/darwin/plugins/two_factor/router.py +239 -0
- hexcore-9.0.0/hexcore/darwin/plugins/two_factor/service.py +397 -0
- hexcore-9.0.0/hexcore/darwin/plugins/two_factor/totp.py +198 -0
- hexcore-9.0.0/hexcore/darwin/testing/__init__.py +86 -0
- hexcore-9.0.0/hexcore/darwin/testing/fakes.py +567 -0
- hexcore-9.0.0/hexcore/darwin/testing/fixtures.py +107 -0
- hexcore-9.0.0/hexcore/darwin/testing/helpers.py +401 -0
- hexcore-9.0.0/hexcore/domain/auth/__init__.py +66 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/domain/auth/permissions.py +7 -7
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/domain/base.py +65 -18
- hexcore-9.0.0/hexcore/domain/cqrs/__init__.py +60 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/domain/cqrs/buses.py +0 -20
- hexcore-9.0.0/hexcore/domain/cqrs/dispatch.py +89 -0
- hexcore-9.0.0/hexcore/domain/cqrs/envelope.py +245 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/domain/cqrs/handlers.py +0 -15
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/domain/cqrs/middleware.py +0 -11
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/domain/cqrs/resolution.py +5 -1
- hexcore-9.0.0/hexcore/domain/cqrs/serializer.py +103 -0
- hexcore-9.0.0/hexcore/domain/events.py +106 -0
- hexcore-9.0.0/hexcore/domain/eventsourcing/__init__.py +44 -0
- hexcore-9.0.0/hexcore/domain/eventsourcing/aggregate.py +330 -0
- hexcore-9.0.0/hexcore/domain/eventsourcing/exceptions.py +78 -0
- hexcore-9.0.0/hexcore/domain/eventsourcing/projections.py +98 -0
- hexcore-9.0.0/hexcore/domain/eventsourcing/snapshots.py +78 -0
- hexcore-9.0.0/hexcore/domain/eventsourcing/store.py +175 -0
- hexcore-9.0.0/hexcore/domain/eventsourcing/stored.py +95 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/domain/services.py +2 -2
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/domain/uow.py +7 -0
- hexcore-9.0.0/hexcore/eventsourcing.py +255 -0
- hexcore-9.0.0/hexcore/eventsourcing.pyi +124 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/fastapi.py +6 -1
- hexcore-9.0.0/hexcore/fastapi.pyi +114 -0
- hexcore-9.0.0/hexcore/infrastructure/api/__init__.py +131 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/infrastructure/api/app.py +99 -2
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/infrastructure/api/cqrs.py +3 -9
- hexcore-9.0.0/hexcore/infrastructure/api/eventsourcing.py +211 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/infrastructure/api/health.py +39 -15
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/infrastructure/api/utils.py +0 -1
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/infrastructure/cache/cache_backends/redis.py +6 -2
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/infrastructure/cli.py +38 -1
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/infrastructure/cqrs/postgres_bus.py +70 -21
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/infrastructure/cqrs/postgres_lock.py +10 -7
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/infrastructure/cqrs/procrastinate.py +22 -12
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/infrastructure/cqrs/rabbitmq.py +28 -11
- hexcore-9.0.0/hexcore/infrastructure/cqrs/redis_bus.py +217 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/infrastructure/cqrs/redis_lock.py +1 -2
- hexcore-9.0.0/hexcore/infrastructure/events/events_backends/memory.py +40 -0
- hexcore-9.0.0/hexcore/infrastructure/eventsourcing/__init__.py +11 -0
- hexcore-9.0.0/hexcore/infrastructure/eventsourcing/beanie_documents.py +190 -0
- hexcore-9.0.0/hexcore/infrastructure/eventsourcing/beanie_store.py +311 -0
- hexcore-9.0.0/hexcore/infrastructure/eventsourcing/memory.py +215 -0
- hexcore-9.0.0/hexcore/infrastructure/eventsourcing/redis_store.py +393 -0
- hexcore-9.0.0/hexcore/infrastructure/eventsourcing/sqlalchemy_models.py +137 -0
- hexcore-9.0.0/hexcore/infrastructure/eventsourcing/sqlalchemy_models_mixins.py +187 -0
- hexcore-9.0.0/hexcore/infrastructure/eventsourcing/sqlalchemy_store.py +503 -0
- hexcore-9.0.0/hexcore/infrastructure/repositories/_beanie_impl.py +87 -0
- hexcore-9.0.0/hexcore/infrastructure/repositories/_sqlalchemy_impl.py +133 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/infrastructure/repositories/base.py +9 -3
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/infrastructure/repositories/decorators.py +6 -6
- hexcore-9.0.0/hexcore/infrastructure/repositories/implementations.py +119 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/infrastructure/repositories/orms/beanie/__init__.py +3 -1
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/infrastructure/repositories/orms/beanie/utils.py +3 -2
- hexcore-9.0.0/hexcore/infrastructure/repositories/orms/sqlalchemy/__init__.py +71 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/infrastructure/repositories/orms/sqlalchemy/session.py +0 -17
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/infrastructure/repositories/orms/sqlalchemy/utils.py +92 -5
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/infrastructure/repositories/utils.py +31 -12
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/infrastructure/task_queues/celery_adapter.py +60 -14
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/infrastructure/task_queues/procrastinate_adapter.py +18 -8
- hexcore-9.0.0/hexcore/infrastructure/uow/__init__.py +442 -0
- hexcore-9.0.0/hexcore/infrastructure/uow/decorators.py +36 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/infrastructure/workers/consumer.py +22 -10
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/infrastructure/workers/rabbitmq_worker.py +10 -1
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/sql.py +19 -1
- hexcore-9.0.0/hexcore/sql.pyi +72 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/testing/__init__.py +3 -0
- hexcore-9.0.0/hexcore/testing/repositories.py +283 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/types.py +17 -5
- hexcore-9.0.0/hexcore.egg-info/PKG-INFO +340 -0
- hexcore-9.0.0/hexcore.egg-info/SOURCES.txt +347 -0
- hexcore-9.0.0/hexcore.egg-info/requires.txt +81 -0
- hexcore-9.0.0/pyproject.toml +237 -0
- hexcore-9.0.0/tests/test_alembic_metadata_completeness.py +194 -0
- hexcore-9.0.0/tests/test_cqrs_envelope.py +349 -0
- hexcore-9.0.0/tests/test_darwin_backend_neutrality.py +456 -0
- hexcore-9.0.0/tests/test_darwin_beanie.py +594 -0
- hexcore-9.0.0/tests/test_darwin_cli.py +263 -0
- hexcore-9.0.0/tests/test_darwin_container.py +338 -0
- hexcore-9.0.0/tests/test_darwin_context.py +284 -0
- hexcore-9.0.0/tests/test_darwin_custom_plugin.py +387 -0
- hexcore-9.0.0/tests/test_darwin_envelope.py +784 -0
- hexcore-9.0.0/tests/test_darwin_facade_and_events.py +447 -0
- hexcore-9.0.0/tests/test_darwin_flows.py +555 -0
- hexcore-9.0.0/tests/test_darwin_hashing.py +210 -0
- hexcore-9.0.0/tests/test_darwin_http.py +658 -0
- hexcore-9.0.0/tests/test_darwin_impersonate.py +1114 -0
- hexcore-9.0.0/tests/test_darwin_magic_link.py +597 -0
- hexcore-9.0.0/tests/test_darwin_models.py +369 -0
- hexcore-9.0.0/tests/test_darwin_oauth.py +1296 -0
- hexcore-9.0.0/tests/test_darwin_organization.py +1313 -0
- hexcore-9.0.0/tests/test_darwin_passkey.py +1174 -0
- hexcore-9.0.0/tests/test_darwin_permissions.py +240 -0
- hexcore-9.0.0/tests/test_darwin_plugin_decoupling.py +343 -0
- hexcore-9.0.0/tests/test_darwin_plugins.py +860 -0
- hexcore-9.0.0/tests/test_darwin_repositories.py +489 -0
- hexcore-9.0.0/tests/test_darwin_revocation.py +297 -0
- hexcore-9.0.0/tests/test_darwin_schema_registration.py +431 -0
- hexcore-9.0.0/tests/test_darwin_storage_selection.py +573 -0
- hexcore-9.0.0/tests/test_darwin_tokens.py +502 -0
- hexcore-9.0.0/tests/test_darwin_two_factor.py +1161 -0
- hexcore-9.0.0/tests/test_darwin_value_objects.py +216 -0
- hexcore-9.0.0/tests/test_deprecations.py +581 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/tests/test_documentation_examples.py +92 -35
- hexcore-9.0.0/tests/test_domain_base_contract.py +159 -0
- hexcore-9.0.0/tests/test_event_dispatch_mro.py +282 -0
- hexcore-9.0.0/tests/test_eventsourcing_aggregate.py +527 -0
- hexcore-9.0.0/tests/test_eventsourcing_beanie.py +303 -0
- hexcore-9.0.0/tests/test_eventsourcing_config.py +389 -0
- hexcore-9.0.0/tests/test_eventsourcing_ports.py +259 -0
- hexcore-9.0.0/tests/test_eventsourcing_projections.py +512 -0
- hexcore-9.0.0/tests/test_eventsourcing_redis.py +396 -0
- hexcore-9.0.0/tests/test_eventsourcing_relay.py +429 -0
- hexcore-9.0.0/tests/test_eventsourcing_repository.py +422 -0
- hexcore-9.0.0/tests/test_eventsourcing_snapshot_checkpoint.py +257 -0
- hexcore-9.0.0/tests/test_eventsourcing_sql_schema.py +284 -0
- hexcore-9.0.0/tests/test_eventsourcing_store_contract.py +473 -0
- hexcore-9.0.0/tests/test_eventsourcing_uow_integration.py +283 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/tests/test_facades.py +9 -6
- {hexcore-7.0.0 → hexcore-9.0.0}/tests/test_infrastructure_query_path.py +4 -4
- hexcore-9.0.0/tests/test_optional_dependencies.py +346 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/tests/test_packaging.py +91 -1
- hexcore-9.0.0/tests/test_sql_naming_convention.py +153 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/tests/test_sql_session_layer.py +8 -8
- hexcore-9.0.0/tests/test_testing_kit.py +937 -0
- hexcore-9.0.0/tests/test_typing_gate.py +179 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/tests/test_uow_session_regression.py +134 -4
- hexcore-7.0.0/PKG-INFO +0 -1156
- hexcore-7.0.0/README.md +0 -1112
- hexcore-7.0.0/hexcore/__init__.py +0 -38
- hexcore-7.0.0/hexcore/_deprecation.py +0 -134
- hexcore-7.0.0/hexcore/domain/auth/__init__.py +0 -13
- hexcore-7.0.0/hexcore/domain/cqrs/__init__.py +0 -104
- hexcore-7.0.0/hexcore/domain/cqrs/serializer.py +0 -46
- hexcore-7.0.0/hexcore/domain/events.py +0 -103
- hexcore-7.0.0/hexcore/infrastructure/api/__init__.py +0 -78
- hexcore-7.0.0/hexcore/infrastructure/cqrs/redis_bus.py +0 -151
- hexcore-7.0.0/hexcore/infrastructure/events/events_backends/memory.py +0 -36
- hexcore-7.0.0/hexcore/infrastructure/repositories/implementations.py +0 -227
- hexcore-7.0.0/hexcore/infrastructure/repositories/orms/sqlalchemy/__init__.py +0 -44
- hexcore-7.0.0/hexcore/infrastructure/uow/__init__.py +0 -218
- hexcore-7.0.0/hexcore/infrastructure/uow/decorators.py +0 -16
- hexcore-7.0.0/hexcore.egg-info/PKG-INFO +0 -1156
- hexcore-7.0.0/hexcore.egg-info/SOURCES.txt +0 -160
- hexcore-7.0.0/hexcore.egg-info/requires.txt +0 -41
- hexcore-7.0.0/pyproject.toml +0 -122
- hexcore-7.0.0/tests/test_deprecations.py +0 -306
- hexcore-7.0.0/tests/test_optional_dependencies.py +0 -57
- {hexcore-7.0.0 → hexcore-9.0.0}/LICENSE +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/MANIFEST.in +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/__main__.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/application/__init__.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/application/cqrs/__init__.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/application/cqrs/adapters.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/application/cqrs/config.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/application/cqrs/factory.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/application/cqrs/pipeline.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/application/cqrs/registry.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/application/cqrs/scheduler.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/application/dtos/__init__.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/application/dtos/base.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/application/dtos/cursor.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/application/dtos/errors.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/application/dtos/query.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/application/use_cases/__init__.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/application/use_cases/base.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/application/use_cases/query.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/domain/__init__.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/domain/auth/value_objects.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/domain/cqrs/commands.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/domain/cqrs/context.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/domain/cqrs/cron.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/domain/cqrs/decorators.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/domain/cqrs/exceptions.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/domain/cqrs/queries.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/domain/cqrs/task_queues.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/domain/exceptions.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/domain/repositories.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/infrastructure/__init__.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/infrastructure/api/exception_handlers.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/infrastructure/api/lifespan.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/infrastructure/api/middlewares.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/infrastructure/api/rate_limit.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/infrastructure/api/routing.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/infrastructure/api/streaming.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/infrastructure/cache/__init__.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/infrastructure/cache/cache_backends/__init__.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/infrastructure/cache/cache_backends/memory.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/infrastructure/cqrs/__init__.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/infrastructure/cqrs/cron_sql.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/infrastructure/cqrs/middlewares.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/infrastructure/cqrs/pydantic_serializer.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/infrastructure/events/__init__.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/infrastructure/events/events_backends/__init__.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/infrastructure/repositories/__init__.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/infrastructure/repositories/orms/__init__.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/infrastructure/task_queues/__init__.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/infrastructure/uow/helpers.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/infrastructure/uow/scopes.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/infrastructure/workers/__init__.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/infrastructure/workers/runner.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/py.typed +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/testing/fakes.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/testing/fixtures.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore/testing/helpers.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore.egg-info/dependency_links.txt +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore.egg-info/entry_points.txt +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/hexcore.egg-info/top_level.txt +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/setup.cfg +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/tests/test_api_app_and_lifespan.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/tests/test_api_cqrs_providers.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/tests/test_api_exception_handlers.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/tests/test_api_health.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/tests/test_api_middlewares_and_routing.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/tests/test_api_rate_limit.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/tests/test_api_streaming.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/tests/test_basic.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/tests/test_beanie_query_utils.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/tests/test_celery_event_loop.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/tests/test_config_cors_security.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/tests/test_config_loading.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/tests/test_consumer_optional_event_bus.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/tests/test_cqrs.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/tests/test_cqrs_factory.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/tests/test_cqrs_middlewares.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/tests/test_cron_sql.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/tests/test_domain_service_query.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/tests/test_dotted_resolution.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/tests/test_handler_registry.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/tests/test_lock_error_policy.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/tests/test_postgres_bus.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/tests/test_postgres_lock.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/tests/test_query_cursor_and_endpoint.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/tests/test_query_field_validation.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/tests/test_rabbitmq_bus.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/tests/test_redis_bus.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/tests/test_redis_lock.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/tests/test_repositories_utils.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/tests/test_scheduler.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/tests/test_scheduler_catchup.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/tests/test_smart_routing.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/tests/test_task_queues_adapters.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/tests/test_testing_utilities.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/tests/test_use_cases_query.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/tests/test_worker_bus_integration.py +0 -0
- {hexcore-7.0.0 → hexcore-9.0.0}/tests/test_worker_runner.py +0 -0
hexcore-9.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: hexcore
|
|
3
|
+
Version: 9.0.0
|
|
4
|
+
Summary: Reusable core for Python projects with hexagonal architecture, DDD, CQRS and background tasks. Ships the abstractions and the infrastructure: SQL session layer, FastAPI factories, worker runner, dynamic cron and identity.
|
|
5
|
+
Author-email: "David Latosefki (Indroic)" <indroic@outlook.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Requires-Python: >=3.12
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Requires-Dist: croniter>=2.0.0
|
|
11
|
+
Requires-Dist: pydantic>=2.11.7
|
|
12
|
+
Requires-Dist: typer>=0.17.3
|
|
13
|
+
Provides-Extra: api
|
|
14
|
+
Requires-Dist: fastapi>=0.116.1; extra == "api"
|
|
15
|
+
Provides-Extra: redis
|
|
16
|
+
Requires-Dist: redis>=6.4.0; extra == "redis"
|
|
17
|
+
Provides-Extra: mongo
|
|
18
|
+
Requires-Dist: beanie>=2.0.0; extra == "mongo"
|
|
19
|
+
Provides-Extra: sql
|
|
20
|
+
Requires-Dist: sqlalchemy>=2.0.43; extra == "sql"
|
|
21
|
+
Requires-Dist: alembic>=1.16.5; extra == "sql"
|
|
22
|
+
Requires-Dist: asyncpg>=0.30.0; extra == "sql"
|
|
23
|
+
Requires-Dist: aiosqlite>=0.21.0; extra == "sql"
|
|
24
|
+
Provides-Extra: rabbitmq
|
|
25
|
+
Requires-Dist: aio-pika>=9.4.0; extra == "rabbitmq"
|
|
26
|
+
Requires-Dist: pika>=1.3.2; extra == "rabbitmq"
|
|
27
|
+
Provides-Extra: procrastinate
|
|
28
|
+
Requires-Dist: procrastinate>=3.0.0; extra == "procrastinate"
|
|
29
|
+
Provides-Extra: celery
|
|
30
|
+
Requires-Dist: celery>=5.4.0; extra == "celery"
|
|
31
|
+
Provides-Extra: darwin
|
|
32
|
+
Requires-Dist: fastapi>=0.116.1; extra == "darwin"
|
|
33
|
+
Requires-Dist: joserfc>=1.0.0; extra == "darwin"
|
|
34
|
+
Requires-Dist: argon2-cffi>=23.1.0; extra == "darwin"
|
|
35
|
+
Provides-Extra: darwin-sqlalchemy
|
|
36
|
+
Requires-Dist: hexcore[darwin]; extra == "darwin-sqlalchemy"
|
|
37
|
+
Requires-Dist: sqlalchemy>=2.0.43; extra == "darwin-sqlalchemy"
|
|
38
|
+
Requires-Dist: alembic>=1.16.5; extra == "darwin-sqlalchemy"
|
|
39
|
+
Requires-Dist: asyncpg>=0.30.0; extra == "darwin-sqlalchemy"
|
|
40
|
+
Requires-Dist: aiosqlite>=0.21.0; extra == "darwin-sqlalchemy"
|
|
41
|
+
Provides-Extra: darwin-beanie
|
|
42
|
+
Requires-Dist: hexcore[darwin]; extra == "darwin-beanie"
|
|
43
|
+
Requires-Dist: beanie>=2.0.0; extra == "darwin-beanie"
|
|
44
|
+
Provides-Extra: darwin-magic-link
|
|
45
|
+
Requires-Dist: hexcore[darwin]; extra == "darwin-magic-link"
|
|
46
|
+
Provides-Extra: darwin-two-factor
|
|
47
|
+
Requires-Dist: hexcore[darwin]; extra == "darwin-two-factor"
|
|
48
|
+
Provides-Extra: darwin-oauth
|
|
49
|
+
Requires-Dist: hexcore[darwin]; extra == "darwin-oauth"
|
|
50
|
+
Requires-Dist: httpx>=0.27.0; extra == "darwin-oauth"
|
|
51
|
+
Provides-Extra: darwin-impersonate
|
|
52
|
+
Requires-Dist: hexcore[darwin]; extra == "darwin-impersonate"
|
|
53
|
+
Provides-Extra: darwin-passkey
|
|
54
|
+
Requires-Dist: hexcore[darwin]; extra == "darwin-passkey"
|
|
55
|
+
Requires-Dist: webauthn>=2.0.0; extra == "darwin-passkey"
|
|
56
|
+
Provides-Extra: darwin-organization
|
|
57
|
+
Requires-Dist: hexcore[darwin]; extra == "darwin-organization"
|
|
58
|
+
Provides-Extra: all
|
|
59
|
+
Requires-Dist: fastapi>=0.116.1; extra == "all"
|
|
60
|
+
Requires-Dist: redis>=6.4.0; extra == "all"
|
|
61
|
+
Requires-Dist: beanie>=2.0.0; extra == "all"
|
|
62
|
+
Requires-Dist: sqlalchemy>=2.0.43; extra == "all"
|
|
63
|
+
Requires-Dist: alembic>=1.16.5; extra == "all"
|
|
64
|
+
Requires-Dist: asyncpg>=0.30.0; extra == "all"
|
|
65
|
+
Requires-Dist: aiosqlite>=0.21.0; extra == "all"
|
|
66
|
+
Requires-Dist: aio-pika>=9.4.0; extra == "all"
|
|
67
|
+
Requires-Dist: pika>=1.3.2; extra == "all"
|
|
68
|
+
Requires-Dist: procrastinate>=3.0.0; extra == "all"
|
|
69
|
+
Requires-Dist: celery>=5.4.0; extra == "all"
|
|
70
|
+
Requires-Dist: joserfc>=1.0.0; extra == "all"
|
|
71
|
+
Requires-Dist: argon2-cffi>=23.1.0; extra == "all"
|
|
72
|
+
Requires-Dist: httpx>=0.27.0; extra == "all"
|
|
73
|
+
Requires-Dist: webauthn>=2.0.0; extra == "all"
|
|
74
|
+
Dynamic: license-file
|
|
75
|
+
|
|
76
|
+
# HexCore [](https://pepy.tech/projects/hexcore)
|
|
77
|
+
|
|
78
|
+
A reusable core for Python applications built on **hexagonal architecture**, **DDD**, **CQRS**
|
|
79
|
+
and **background tasks**. HexCore ships the abstractions (entities, repositories, unit of work,
|
|
80
|
+
buses) *and* the infrastructure every project otherwise rewrites: the SQL session layer, the
|
|
81
|
+
FastAPI factories, the worker runner, the dynamic cron, identity, and the testing utilities.
|
|
82
|
+
|
|
83
|
+
The design goal is that the happy path takes **zero configuration**: `create_app()` with no
|
|
84
|
+
arguments gives you a usable app, `init_engine()` with no arguments gives you a
|
|
85
|
+
production-correct engine.
|
|
86
|
+
|
|
87
|
+
> 🇪🇸 **¿Preferís español?** La documentación está completa en los dos idiomas:
|
|
88
|
+
> **[docs/es/](./docs/es/)**.
|
|
89
|
+
|
|
90
|
+
```python
|
|
91
|
+
# main.py — a complete HexCore app
|
|
92
|
+
from hexcore.fastapi import build_lifespan, create_app, SqlEngineStep
|
|
93
|
+
|
|
94
|
+
app = create_app(
|
|
95
|
+
lifespan=build_lifespan(SqlEngineStep()),
|
|
96
|
+
routers=[users_router, tickets_router],
|
|
97
|
+
)
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
```python
|
|
101
|
+
# worker.py — the complete worker, with cron, mutual death and SIGTERM
|
|
102
|
+
import hexcore.cqrs as cqrs
|
|
103
|
+
|
|
104
|
+
await cqrs.run_procrastinate_worker(
|
|
105
|
+
procrastinate_app,
|
|
106
|
+
queues=["default", "reactive"],
|
|
107
|
+
scheduler=cqrs.DynamicScheduler(repo, enqueuer, lock_provider=lock),
|
|
108
|
+
on_startup=[lambda: cqrs.seed_cron_jobs(CRON_JOBS)],
|
|
109
|
+
)
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## 📚 Documentation
|
|
115
|
+
|
|
116
|
+
**→ [`docs/`](./docs/) — 🇬🇧 [English](./docs/en/) · 🇪🇸 [español](./docs/es/)**
|
|
117
|
+
|
|
118
|
+
| | English | Español |
|
|
119
|
+
| :-- | :-- | :-- |
|
|
120
|
+
| Installation and extras | [installation](./docs/en/installation.md) | [instalacion](./docs/es/instalacion.md) |
|
|
121
|
+
| Quickstart | [quickstart](./docs/en/quickstart.md) | [inicio-rapido](./docs/es/inicio-rapido.md) |
|
|
122
|
+
| Configuration | [configuration](./docs/en/configuration.md) | [configuracion](./docs/es/configuracion.md) |
|
|
123
|
+
| SQL layer | [sql](./docs/en/sql.md) | [sql](./docs/es/sql.md) |
|
|
124
|
+
| Repositories and entities | [repositories](./docs/en/repositories.md) | [repositorios](./docs/es/repositorios.md) |
|
|
125
|
+
| FastAPI utilities | [fastapi](./docs/en/fastapi.md) | [fastapi](./docs/es/fastapi.md) |
|
|
126
|
+
| CQRS architecture | [cqrs](./docs/en/cqrs.md) | [cqrs](./docs/es/cqrs.md) |
|
|
127
|
+
| Queues and workers | [queues-and-workers](./docs/en/queues-and-workers.md) | [colas-y-workers](./docs/es/colas-y-workers.md) |
|
|
128
|
+
| Scheduled tasks | [cron](./docs/en/cron.md) | [cron](./docs/es/cron.md) |
|
|
129
|
+
| **Event Sourcing** | [event-sourcing](./docs/en/event-sourcing.md) | [event-sourcing](./docs/es/event-sourcing.md) |
|
|
130
|
+
| Testing | [testing](./docs/en/testing.md) | [testing](./docs/es/testing.md) |
|
|
131
|
+
| CLI | [cli](./docs/en/cli.md) | [cli](./docs/es/cli.md) |
|
|
132
|
+
| **Darwin** (identity) | [darwin/](./docs/en/darwin/) | [darwin/](./docs/es/darwin/) |
|
|
133
|
+
| API reference | [reference](./docs/en/reference.md) | [referencia](./docs/es/referencia.md) |
|
|
134
|
+
| Versions and migration | [versions-and-migration](./docs/en/versions-and-migration.md) | [versiones-y-migracion](./docs/es/versiones-y-migracion.md) |
|
|
135
|
+
| Typing | [typing](./docs/en/typing.md) | [tipado](./docs/es/tipado.md) |
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## Installation
|
|
140
|
+
|
|
141
|
+
```sh
|
|
142
|
+
pip install hexcore
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Requires Python ≥ 3.12. HexCore pulls in no heavy dependencies: everything that is not the core
|
|
146
|
+
lives in **extras**, and the modules that need them only import them when you use them.
|
|
147
|
+
|
|
148
|
+
```sh
|
|
149
|
+
pip install "hexcore[api,sql,procrastinate]"
|
|
150
|
+
pip install "hexcore[darwin-sqlalchemy]"
|
|
151
|
+
pip install "hexcore[all]"
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
| Group | Extras |
|
|
155
|
+
| :-- | :-- |
|
|
156
|
+
| Core | `api`, `sql`, `mongo`, `redis`, `rabbitmq`, `procrastinate`, `celery` |
|
|
157
|
+
| Identity | `darwin`, `darwin-sqlalchemy`, `darwin-beanie`, `darwin-magic-link`, `darwin-two-factor`, `darwin-oauth`, `darwin-impersonate`, `darwin-passkey`, `darwin-organization` |
|
|
158
|
+
| Everything | `all` |
|
|
159
|
+
|
|
160
|
+
The full table, with what each one enables, is in
|
|
161
|
+
[installation](./docs/en/installation.md) · [instalación](./docs/es/instalacion.md).
|
|
162
|
+
|
|
163
|
+
> `import hexcore.cqrs` works with no extras at all: name resolution is lazy, so
|
|
164
|
+
> `hexcore.cqrs.SqlAlchemyCronJobRepository` only requires `[sql]` at the moment you ask for it.
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## The four imports
|
|
169
|
+
|
|
170
|
+
There is one facade module per task. They re-export the public surface **without moving
|
|
171
|
+
anything**: the long paths keep resolving to the same object.
|
|
172
|
+
|
|
173
|
+
```python
|
|
174
|
+
import hexcore.fastapi as hx # create_app, build_lifespan, providers, middlewares, health
|
|
175
|
+
import hexcore.cqrs as cqrs # Command, Query, handlers, decorators, buses, worker, cron
|
|
176
|
+
import hexcore.sql as sql # init_engine, session_scope, uow_scope, Base, query DTOs
|
|
177
|
+
import hexcore.darwin as darwin # IdentityConfig, configure_identity, build_identity_router
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
The facades expose **only the canonical names**. The historical `I*` aliases were removed in
|
|
181
|
+
7.0 — see [Removed API](#removed-api-and-its-replacement).
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## What you get, at a glance
|
|
186
|
+
|
|
187
|
+
| You need | API | Extra |
|
|
188
|
+
| :-- | :-- | :-- |
|
|
189
|
+
| A wired-up FastAPI app | `hx.create_app()`, `hx.AppFeatures` | `api` |
|
|
190
|
+
| Orchestrated startup and shutdown | `hx.build_lifespan()` + steps | `api` |
|
|
191
|
+
| SQL engine and sessions | `sql.init_engine()`, `sql.PoolSettings` | `sql` |
|
|
192
|
+
| A session or UoW outside a request | `sql.session_scope()`, `sql.uow_scope()` | `sql` |
|
|
193
|
+
| Health checks that actually probe | `hx.register_health_routes()` | `api` |
|
|
194
|
+
| Rate limiting | `hx.rate_limit()` | `api` |
|
|
195
|
+
| SSE / WebSocket / connection caps | `hx.sse_stream()`, `hx.connection_slot()` | `api` |
|
|
196
|
+
| Commands, queries and events | `cqrs.Command`, `cqrs.Query`, `cqrs.HandlerRegistry` | — |
|
|
197
|
+
| Running work in the background | `cqrs.background_command`, `cqrs.background_task` | — |
|
|
198
|
+
| The worker entrypoint | `cqrs.run_cqrs_worker()`, `cqrs.run_procrastinate_worker()` | — |
|
|
199
|
+
| Cron you can edit without a restart | `cqrs.DynamicScheduler`, `cqrs.SqlAlchemyCronJobRepository` | `sql` |
|
|
200
|
+
| Distributed locks | `cqrs.RedisLockProvider`, `cqrs.PostgresLockProvider` | `redis` / `sql` |
|
|
201
|
+
| Identity and authentication | `darwin.configure_identity()`, `darwin.build_identity_router()` | `darwin` + storage |
|
|
202
|
+
| Testing all of the above | `hexcore.testing` | — |
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
## Darwin: the identity module
|
|
207
|
+
|
|
208
|
+
Registration, email verification, sign-in, sessions with rotating refresh, revocation, audited
|
|
209
|
+
impersonation, and a plugin system that adds second factor, OAuth, magic links, passkeys and
|
|
210
|
+
organizations without the core knowing about them.
|
|
211
|
+
|
|
212
|
+
```python
|
|
213
|
+
from hexcore.darwin import (
|
|
214
|
+
IdentityConfig,
|
|
215
|
+
build_identity_router,
|
|
216
|
+
configure_identity,
|
|
217
|
+
identity_startup_steps,
|
|
218
|
+
)
|
|
219
|
+
from hexcore.fastapi import AppFeatures, SqlEngineStep, build_lifespan, create_app
|
|
220
|
+
|
|
221
|
+
configure_identity(IdentityConfig())
|
|
222
|
+
|
|
223
|
+
app = create_app(
|
|
224
|
+
features=AppFeatures(auth_context=True, csrf=True),
|
|
225
|
+
lifespan=build_lifespan(SqlEngineStep(), *identity_startup_steps()),
|
|
226
|
+
routers=[build_identity_router()],
|
|
227
|
+
)
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
⚠️ If you use SQL, the most important thing to read before deploying is the Alembic section:
|
|
231
|
+
[storage](./docs/en/darwin/storage.md) · [almacenamiento](./docs/es/darwin/almacenamiento.md).
|
|
232
|
+
A plugin missing from your `env.py` makes `alembic revision --autogenerate` emit
|
|
233
|
+
`op.drop_table` for its tables.
|
|
234
|
+
|
|
235
|
+
---
|
|
236
|
+
|
|
237
|
+
## Project templates (CLI)
|
|
238
|
+
|
|
239
|
+
```sh
|
|
240
|
+
hexcore init my_project --template hexagonal
|
|
241
|
+
hexcore init my_project --template vertical-slice
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
- `hexagonal` → `src/domain`, `src/application`, `src/infrastructure`.
|
|
245
|
+
- `vertical-slice` → `src/features`, `src/shared/{domain,application,infrastructure}`.
|
|
246
|
+
|
|
247
|
+
Both generate a root `config.py` and leave Alembic configured. See
|
|
248
|
+
[CLI](./docs/en/cli.md) · [CLI](./docs/es/cli.md).
|
|
249
|
+
|
|
250
|
+
---
|
|
251
|
+
|
|
252
|
+
## Versions and support
|
|
253
|
+
|
|
254
|
+
| Series | Status | What it means |
|
|
255
|
+
| :-- | :-- | :-- |
|
|
256
|
+
| **9.x** | ✅ **Active** | The only supported one. Receives features and fixes. Adds the event store and Event Sourcing, and leaves a single event bus port. |
|
|
257
|
+
| **8.x** | ⛔ **Deprecated** | Ships Darwin. Migrating to 9.x is mechanical: the two deprecated names still resolve and warn. |
|
|
258
|
+
| **7.x** | ⛔ **Deprecated** | Removes the pre-5.0 surface and fixes the CORS and rate-limiting defects. No Darwin: it shipped before the module landed on `master`. |
|
|
259
|
+
| **6.x** | ⛔ **Deprecated** | No longer receives fixes. Contains the CORS and rate-limiting security defects fixed in 7.0, and the pre-5.0 aliases still present. |
|
|
260
|
+
| **5.x** | ⛔ **Deprecated** | Same API surface as 6.x. |
|
|
261
|
+
| **4.x** | ⛔ **Deprecated** | **Partial** application: missing the Celery event-loop fix, the facades, and the aligned documentation. |
|
|
262
|
+
| **3.x** | ⛔ **Deprecated** | **Partial** application: has the P0/P1 fixes but none of the FastAPI factories. |
|
|
263
|
+
| **2.x** | ⛔ **Deprecated** | Contains silent bugs fixed in 5.x: the worker re-enqueued instead of executing, the cron skipped or duplicated runs, and a Redis outage switched off the entire cron. |
|
|
264
|
+
| **1.x** | ⛔ **Deprecated** | No support of any kind. |
|
|
265
|
+
|
|
266
|
+
**Everything before 9.0 is deprecated. Migrate to 9.x.** The detail of each series, the silent
|
|
267
|
+
2.x bugs and the step-by-step guides are in
|
|
268
|
+
[versions and migration](./docs/en/versions-and-migration.md) ·
|
|
269
|
+
[versiones y migración](./docs/es/versiones-y-migracion.md).
|
|
270
|
+
|
|
271
|
+
### Removed API and its replacement
|
|
272
|
+
|
|
273
|
+
The v1/v2 aliases were deprecated since 5.0 — two full majors of notice — and were removed in
|
|
274
|
+
7.0. The replacement is mechanical: they are renames, not behavior changes.
|
|
275
|
+
|
|
276
|
+
| Removed in 7.0 (was v1/v2) | Use instead |
|
|
277
|
+
| :-- | :-- |
|
|
278
|
+
| `ICommandBus`, `IQueryBus`, `IEventBus` | `AbstractCommandBus`, `AbstractQueryBus`, `AbstractEventBus` |
|
|
279
|
+
| `ICommandHandler`, `IQueryHandler` | `AbstractCommandHandler`, `AbstractQueryHandler` |
|
|
280
|
+
| `IMiddleware` | `AbstractMiddleware` |
|
|
281
|
+
| `ISerializer` | `AbstractSerializer` |
|
|
282
|
+
| `IEventDispatcher` | `EventBus` |
|
|
283
|
+
| `EventBus.register()` / `.dispatch()` | `EventBus.subscribe()` / `.publish()` |
|
|
284
|
+
| `ServerConfig.event_dispatcher` | `ServerConfig.event_bus` |
|
|
285
|
+
| `SQLAlchemyCommonImplementationsRepo` | `SqlAlchemyRepository` |
|
|
286
|
+
| `BeanieODMCommonImplementationsRepo` | `BeanieRepository` |
|
|
287
|
+
| `NoSqlUnitOfWork` | `BeanieUnitOfWork` |
|
|
288
|
+
| `reset_sqlalchemy_engine()` | `dispose_engine()` |
|
|
289
|
+
| `MiddlewareConfig` | **Removed in 3.0.** It was dead code: never read. |
|
|
290
|
+
|
|
291
|
+
Passing `event_dispatcher=` to `ServerConfig` **fails with an error that says what to use**,
|
|
292
|
+
rather than being silently ignored: pydantic discards keyword arguments it does not know, and
|
|
293
|
+
keeping the default bus without noticing would surface much later as "my events never arrive".
|
|
294
|
+
|
|
295
|
+
If you are still on 6.x, run your tests with warnings visible to see what you have left to
|
|
296
|
+
migrate:
|
|
297
|
+
|
|
298
|
+
```sh
|
|
299
|
+
python -m pytest -W "default::DeprecationWarning"
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
---
|
|
303
|
+
|
|
304
|
+
## Contributing
|
|
305
|
+
|
|
306
|
+
1. **Code of conduct** — read the [Code of Conduct](CODE_OF_CONDUCT.md) before interacting.
|
|
307
|
+
2. **Branches** — fork and create a branch (`feat/name`, `fix/name`, `docs/name`).
|
|
308
|
+
3. **Tests** — every fix lands with at least one test that fails before and passes after:
|
|
309
|
+
|
|
310
|
+
```sh
|
|
311
|
+
uv sync --extra all --group dev
|
|
312
|
+
uv run python -m pytest -q
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
CI fails if any test is **skipped**: a skip means an extra is missing, and we would be
|
|
316
|
+
reporting green without having run half the suite.
|
|
317
|
+
4. **Typecheck** — `uv run pyright hexcore`. The verdict comes from the ratchet, not the exit
|
|
318
|
+
code: see [typing](./docs/en/typing.md) · [tipado](./docs/es/tipado.md).
|
|
319
|
+
5. **Style** — [PEP8](https://pep8.org/). Comment the *why*, not the *what*.
|
|
320
|
+
6. **Commits** — [Commitizen](https://commitizen-tools.github.io/commitizen/): `feat:`, `fix:`,
|
|
321
|
+
`docs:`, `refactor:`, and `!` for breaking changes. The version bump and the CHANGELOG are
|
|
322
|
+
automatic on merge to `master`.
|
|
323
|
+
7. **PRs** — describe the problem, the reproduction, the solution and **why that option**.
|
|
324
|
+
|
|
325
|
+
Full detail in [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
326
|
+
|
|
327
|
+
### Project skills
|
|
328
|
+
|
|
329
|
+
There is a set of skills for extending HexCore in VS Code and compatible environments:
|
|
330
|
+
[HexCore Skills repository](https://github.com/Indroic/hexcore-skill).
|
|
331
|
+
|
|
332
|
+
---
|
|
333
|
+
|
|
334
|
+
## References
|
|
335
|
+
|
|
336
|
+
- [docs/](./docs/) — the complete documentation, in English and Spanish.
|
|
337
|
+
- [docs/ARCHITECTURE_TYPING.md](./docs/ARCHITECTURE_TYPING.md) — type system and stubs.
|
|
338
|
+
- [CHANGELOG.md](./CHANGELOG.md) — change history.
|
|
339
|
+
- [CONTRIBUTING.md](./CONTRIBUTING.md) — collaboration guidelines.
|
|
340
|
+
- [SECURITY.md](./SECURITY.md) — security policy.
|
hexcore-9.0.0/README.md
ADDED
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
# HexCore [](https://pepy.tech/projects/hexcore)
|
|
2
|
+
|
|
3
|
+
A reusable core for Python applications built on **hexagonal architecture**, **DDD**, **CQRS**
|
|
4
|
+
and **background tasks**. HexCore ships the abstractions (entities, repositories, unit of work,
|
|
5
|
+
buses) *and* the infrastructure every project otherwise rewrites: the SQL session layer, the
|
|
6
|
+
FastAPI factories, the worker runner, the dynamic cron, identity, and the testing utilities.
|
|
7
|
+
|
|
8
|
+
The design goal is that the happy path takes **zero configuration**: `create_app()` with no
|
|
9
|
+
arguments gives you a usable app, `init_engine()` with no arguments gives you a
|
|
10
|
+
production-correct engine.
|
|
11
|
+
|
|
12
|
+
> 🇪🇸 **¿Preferís español?** La documentación está completa en los dos idiomas:
|
|
13
|
+
> **[docs/es/](./docs/es/)**.
|
|
14
|
+
|
|
15
|
+
```python
|
|
16
|
+
# main.py — a complete HexCore app
|
|
17
|
+
from hexcore.fastapi import build_lifespan, create_app, SqlEngineStep
|
|
18
|
+
|
|
19
|
+
app = create_app(
|
|
20
|
+
lifespan=build_lifespan(SqlEngineStep()),
|
|
21
|
+
routers=[users_router, tickets_router],
|
|
22
|
+
)
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
```python
|
|
26
|
+
# worker.py — the complete worker, with cron, mutual death and SIGTERM
|
|
27
|
+
import hexcore.cqrs as cqrs
|
|
28
|
+
|
|
29
|
+
await cqrs.run_procrastinate_worker(
|
|
30
|
+
procrastinate_app,
|
|
31
|
+
queues=["default", "reactive"],
|
|
32
|
+
scheduler=cqrs.DynamicScheduler(repo, enqueuer, lock_provider=lock),
|
|
33
|
+
on_startup=[lambda: cqrs.seed_cron_jobs(CRON_JOBS)],
|
|
34
|
+
)
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## 📚 Documentation
|
|
40
|
+
|
|
41
|
+
**→ [`docs/`](./docs/) — 🇬🇧 [English](./docs/en/) · 🇪🇸 [español](./docs/es/)**
|
|
42
|
+
|
|
43
|
+
| | English | Español |
|
|
44
|
+
| :-- | :-- | :-- |
|
|
45
|
+
| Installation and extras | [installation](./docs/en/installation.md) | [instalacion](./docs/es/instalacion.md) |
|
|
46
|
+
| Quickstart | [quickstart](./docs/en/quickstart.md) | [inicio-rapido](./docs/es/inicio-rapido.md) |
|
|
47
|
+
| Configuration | [configuration](./docs/en/configuration.md) | [configuracion](./docs/es/configuracion.md) |
|
|
48
|
+
| SQL layer | [sql](./docs/en/sql.md) | [sql](./docs/es/sql.md) |
|
|
49
|
+
| Repositories and entities | [repositories](./docs/en/repositories.md) | [repositorios](./docs/es/repositorios.md) |
|
|
50
|
+
| FastAPI utilities | [fastapi](./docs/en/fastapi.md) | [fastapi](./docs/es/fastapi.md) |
|
|
51
|
+
| CQRS architecture | [cqrs](./docs/en/cqrs.md) | [cqrs](./docs/es/cqrs.md) |
|
|
52
|
+
| Queues and workers | [queues-and-workers](./docs/en/queues-and-workers.md) | [colas-y-workers](./docs/es/colas-y-workers.md) |
|
|
53
|
+
| Scheduled tasks | [cron](./docs/en/cron.md) | [cron](./docs/es/cron.md) |
|
|
54
|
+
| **Event Sourcing** | [event-sourcing](./docs/en/event-sourcing.md) | [event-sourcing](./docs/es/event-sourcing.md) |
|
|
55
|
+
| Testing | [testing](./docs/en/testing.md) | [testing](./docs/es/testing.md) |
|
|
56
|
+
| CLI | [cli](./docs/en/cli.md) | [cli](./docs/es/cli.md) |
|
|
57
|
+
| **Darwin** (identity) | [darwin/](./docs/en/darwin/) | [darwin/](./docs/es/darwin/) |
|
|
58
|
+
| API reference | [reference](./docs/en/reference.md) | [referencia](./docs/es/referencia.md) |
|
|
59
|
+
| Versions and migration | [versions-and-migration](./docs/en/versions-and-migration.md) | [versiones-y-migracion](./docs/es/versiones-y-migracion.md) |
|
|
60
|
+
| Typing | [typing](./docs/en/typing.md) | [tipado](./docs/es/tipado.md) |
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## Installation
|
|
65
|
+
|
|
66
|
+
```sh
|
|
67
|
+
pip install hexcore
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Requires Python ≥ 3.12. HexCore pulls in no heavy dependencies: everything that is not the core
|
|
71
|
+
lives in **extras**, and the modules that need them only import them when you use them.
|
|
72
|
+
|
|
73
|
+
```sh
|
|
74
|
+
pip install "hexcore[api,sql,procrastinate]"
|
|
75
|
+
pip install "hexcore[darwin-sqlalchemy]"
|
|
76
|
+
pip install "hexcore[all]"
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
| Group | Extras |
|
|
80
|
+
| :-- | :-- |
|
|
81
|
+
| Core | `api`, `sql`, `mongo`, `redis`, `rabbitmq`, `procrastinate`, `celery` |
|
|
82
|
+
| Identity | `darwin`, `darwin-sqlalchemy`, `darwin-beanie`, `darwin-magic-link`, `darwin-two-factor`, `darwin-oauth`, `darwin-impersonate`, `darwin-passkey`, `darwin-organization` |
|
|
83
|
+
| Everything | `all` |
|
|
84
|
+
|
|
85
|
+
The full table, with what each one enables, is in
|
|
86
|
+
[installation](./docs/en/installation.md) · [instalación](./docs/es/instalacion.md).
|
|
87
|
+
|
|
88
|
+
> `import hexcore.cqrs` works with no extras at all: name resolution is lazy, so
|
|
89
|
+
> `hexcore.cqrs.SqlAlchemyCronJobRepository` only requires `[sql]` at the moment you ask for it.
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## The four imports
|
|
94
|
+
|
|
95
|
+
There is one facade module per task. They re-export the public surface **without moving
|
|
96
|
+
anything**: the long paths keep resolving to the same object.
|
|
97
|
+
|
|
98
|
+
```python
|
|
99
|
+
import hexcore.fastapi as hx # create_app, build_lifespan, providers, middlewares, health
|
|
100
|
+
import hexcore.cqrs as cqrs # Command, Query, handlers, decorators, buses, worker, cron
|
|
101
|
+
import hexcore.sql as sql # init_engine, session_scope, uow_scope, Base, query DTOs
|
|
102
|
+
import hexcore.darwin as darwin # IdentityConfig, configure_identity, build_identity_router
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
The facades expose **only the canonical names**. The historical `I*` aliases were removed in
|
|
106
|
+
7.0 — see [Removed API](#removed-api-and-its-replacement).
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## What you get, at a glance
|
|
111
|
+
|
|
112
|
+
| You need | API | Extra |
|
|
113
|
+
| :-- | :-- | :-- |
|
|
114
|
+
| A wired-up FastAPI app | `hx.create_app()`, `hx.AppFeatures` | `api` |
|
|
115
|
+
| Orchestrated startup and shutdown | `hx.build_lifespan()` + steps | `api` |
|
|
116
|
+
| SQL engine and sessions | `sql.init_engine()`, `sql.PoolSettings` | `sql` |
|
|
117
|
+
| A session or UoW outside a request | `sql.session_scope()`, `sql.uow_scope()` | `sql` |
|
|
118
|
+
| Health checks that actually probe | `hx.register_health_routes()` | `api` |
|
|
119
|
+
| Rate limiting | `hx.rate_limit()` | `api` |
|
|
120
|
+
| SSE / WebSocket / connection caps | `hx.sse_stream()`, `hx.connection_slot()` | `api` |
|
|
121
|
+
| Commands, queries and events | `cqrs.Command`, `cqrs.Query`, `cqrs.HandlerRegistry` | — |
|
|
122
|
+
| Running work in the background | `cqrs.background_command`, `cqrs.background_task` | — |
|
|
123
|
+
| The worker entrypoint | `cqrs.run_cqrs_worker()`, `cqrs.run_procrastinate_worker()` | — |
|
|
124
|
+
| Cron you can edit without a restart | `cqrs.DynamicScheduler`, `cqrs.SqlAlchemyCronJobRepository` | `sql` |
|
|
125
|
+
| Distributed locks | `cqrs.RedisLockProvider`, `cqrs.PostgresLockProvider` | `redis` / `sql` |
|
|
126
|
+
| Identity and authentication | `darwin.configure_identity()`, `darwin.build_identity_router()` | `darwin` + storage |
|
|
127
|
+
| Testing all of the above | `hexcore.testing` | — |
|
|
128
|
+
|
|
129
|
+
---
|
|
130
|
+
|
|
131
|
+
## Darwin: the identity module
|
|
132
|
+
|
|
133
|
+
Registration, email verification, sign-in, sessions with rotating refresh, revocation, audited
|
|
134
|
+
impersonation, and a plugin system that adds second factor, OAuth, magic links, passkeys and
|
|
135
|
+
organizations without the core knowing about them.
|
|
136
|
+
|
|
137
|
+
```python
|
|
138
|
+
from hexcore.darwin import (
|
|
139
|
+
IdentityConfig,
|
|
140
|
+
build_identity_router,
|
|
141
|
+
configure_identity,
|
|
142
|
+
identity_startup_steps,
|
|
143
|
+
)
|
|
144
|
+
from hexcore.fastapi import AppFeatures, SqlEngineStep, build_lifespan, create_app
|
|
145
|
+
|
|
146
|
+
configure_identity(IdentityConfig())
|
|
147
|
+
|
|
148
|
+
app = create_app(
|
|
149
|
+
features=AppFeatures(auth_context=True, csrf=True),
|
|
150
|
+
lifespan=build_lifespan(SqlEngineStep(), *identity_startup_steps()),
|
|
151
|
+
routers=[build_identity_router()],
|
|
152
|
+
)
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
⚠️ If you use SQL, the most important thing to read before deploying is the Alembic section:
|
|
156
|
+
[storage](./docs/en/darwin/storage.md) · [almacenamiento](./docs/es/darwin/almacenamiento.md).
|
|
157
|
+
A plugin missing from your `env.py` makes `alembic revision --autogenerate` emit
|
|
158
|
+
`op.drop_table` for its tables.
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## Project templates (CLI)
|
|
163
|
+
|
|
164
|
+
```sh
|
|
165
|
+
hexcore init my_project --template hexagonal
|
|
166
|
+
hexcore init my_project --template vertical-slice
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
- `hexagonal` → `src/domain`, `src/application`, `src/infrastructure`.
|
|
170
|
+
- `vertical-slice` → `src/features`, `src/shared/{domain,application,infrastructure}`.
|
|
171
|
+
|
|
172
|
+
Both generate a root `config.py` and leave Alembic configured. See
|
|
173
|
+
[CLI](./docs/en/cli.md) · [CLI](./docs/es/cli.md).
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
## Versions and support
|
|
178
|
+
|
|
179
|
+
| Series | Status | What it means |
|
|
180
|
+
| :-- | :-- | :-- |
|
|
181
|
+
| **9.x** | ✅ **Active** | The only supported one. Receives features and fixes. Adds the event store and Event Sourcing, and leaves a single event bus port. |
|
|
182
|
+
| **8.x** | ⛔ **Deprecated** | Ships Darwin. Migrating to 9.x is mechanical: the two deprecated names still resolve and warn. |
|
|
183
|
+
| **7.x** | ⛔ **Deprecated** | Removes the pre-5.0 surface and fixes the CORS and rate-limiting defects. No Darwin: it shipped before the module landed on `master`. |
|
|
184
|
+
| **6.x** | ⛔ **Deprecated** | No longer receives fixes. Contains the CORS and rate-limiting security defects fixed in 7.0, and the pre-5.0 aliases still present. |
|
|
185
|
+
| **5.x** | ⛔ **Deprecated** | Same API surface as 6.x. |
|
|
186
|
+
| **4.x** | ⛔ **Deprecated** | **Partial** application: missing the Celery event-loop fix, the facades, and the aligned documentation. |
|
|
187
|
+
| **3.x** | ⛔ **Deprecated** | **Partial** application: has the P0/P1 fixes but none of the FastAPI factories. |
|
|
188
|
+
| **2.x** | ⛔ **Deprecated** | Contains silent bugs fixed in 5.x: the worker re-enqueued instead of executing, the cron skipped or duplicated runs, and a Redis outage switched off the entire cron. |
|
|
189
|
+
| **1.x** | ⛔ **Deprecated** | No support of any kind. |
|
|
190
|
+
|
|
191
|
+
**Everything before 9.0 is deprecated. Migrate to 9.x.** The detail of each series, the silent
|
|
192
|
+
2.x bugs and the step-by-step guides are in
|
|
193
|
+
[versions and migration](./docs/en/versions-and-migration.md) ·
|
|
194
|
+
[versiones y migración](./docs/es/versiones-y-migracion.md).
|
|
195
|
+
|
|
196
|
+
### Removed API and its replacement
|
|
197
|
+
|
|
198
|
+
The v1/v2 aliases were deprecated since 5.0 — two full majors of notice — and were removed in
|
|
199
|
+
7.0. The replacement is mechanical: they are renames, not behavior changes.
|
|
200
|
+
|
|
201
|
+
| Removed in 7.0 (was v1/v2) | Use instead |
|
|
202
|
+
| :-- | :-- |
|
|
203
|
+
| `ICommandBus`, `IQueryBus`, `IEventBus` | `AbstractCommandBus`, `AbstractQueryBus`, `AbstractEventBus` |
|
|
204
|
+
| `ICommandHandler`, `IQueryHandler` | `AbstractCommandHandler`, `AbstractQueryHandler` |
|
|
205
|
+
| `IMiddleware` | `AbstractMiddleware` |
|
|
206
|
+
| `ISerializer` | `AbstractSerializer` |
|
|
207
|
+
| `IEventDispatcher` | `EventBus` |
|
|
208
|
+
| `EventBus.register()` / `.dispatch()` | `EventBus.subscribe()` / `.publish()` |
|
|
209
|
+
| `ServerConfig.event_dispatcher` | `ServerConfig.event_bus` |
|
|
210
|
+
| `SQLAlchemyCommonImplementationsRepo` | `SqlAlchemyRepository` |
|
|
211
|
+
| `BeanieODMCommonImplementationsRepo` | `BeanieRepository` |
|
|
212
|
+
| `NoSqlUnitOfWork` | `BeanieUnitOfWork` |
|
|
213
|
+
| `reset_sqlalchemy_engine()` | `dispose_engine()` |
|
|
214
|
+
| `MiddlewareConfig` | **Removed in 3.0.** It was dead code: never read. |
|
|
215
|
+
|
|
216
|
+
Passing `event_dispatcher=` to `ServerConfig` **fails with an error that says what to use**,
|
|
217
|
+
rather than being silently ignored: pydantic discards keyword arguments it does not know, and
|
|
218
|
+
keeping the default bus without noticing would surface much later as "my events never arrive".
|
|
219
|
+
|
|
220
|
+
If you are still on 6.x, run your tests with warnings visible to see what you have left to
|
|
221
|
+
migrate:
|
|
222
|
+
|
|
223
|
+
```sh
|
|
224
|
+
python -m pytest -W "default::DeprecationWarning"
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
## Contributing
|
|
230
|
+
|
|
231
|
+
1. **Code of conduct** — read the [Code of Conduct](CODE_OF_CONDUCT.md) before interacting.
|
|
232
|
+
2. **Branches** — fork and create a branch (`feat/name`, `fix/name`, `docs/name`).
|
|
233
|
+
3. **Tests** — every fix lands with at least one test that fails before and passes after:
|
|
234
|
+
|
|
235
|
+
```sh
|
|
236
|
+
uv sync --extra all --group dev
|
|
237
|
+
uv run python -m pytest -q
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
CI fails if any test is **skipped**: a skip means an extra is missing, and we would be
|
|
241
|
+
reporting green without having run half the suite.
|
|
242
|
+
4. **Typecheck** — `uv run pyright hexcore`. The verdict comes from the ratchet, not the exit
|
|
243
|
+
code: see [typing](./docs/en/typing.md) · [tipado](./docs/es/tipado.md).
|
|
244
|
+
5. **Style** — [PEP8](https://pep8.org/). Comment the *why*, not the *what*.
|
|
245
|
+
6. **Commits** — [Commitizen](https://commitizen-tools.github.io/commitizen/): `feat:`, `fix:`,
|
|
246
|
+
`docs:`, `refactor:`, and `!` for breaking changes. The version bump and the CHANGELOG are
|
|
247
|
+
automatic on merge to `master`.
|
|
248
|
+
7. **PRs** — describe the problem, the reproduction, the solution and **why that option**.
|
|
249
|
+
|
|
250
|
+
Full detail in [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
251
|
+
|
|
252
|
+
### Project skills
|
|
253
|
+
|
|
254
|
+
There is a set of skills for extending HexCore in VS Code and compatible environments:
|
|
255
|
+
[HexCore Skills repository](https://github.com/Indroic/hexcore-skill).
|
|
256
|
+
|
|
257
|
+
---
|
|
258
|
+
|
|
259
|
+
## References
|
|
260
|
+
|
|
261
|
+
- [docs/](./docs/) — the complete documentation, in English and Spanish.
|
|
262
|
+
- [docs/ARCHITECTURE_TYPING.md](./docs/ARCHITECTURE_TYPING.md) — type system and stubs.
|
|
263
|
+
- [CHANGELOG.md](./CHANGELOG.md) — change history.
|
|
264
|
+
- [CONTRIBUTING.md](./CONTRIBUTING.md) — collaboration guidelines.
|
|
265
|
+
- [SECURITY.md](./SECURITY.md) — security policy.
|