loom-kernel 0.1.0__tar.gz → 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.
- loom_kernel-0.2.0/CHANGELOG.md +120 -0
- loom_kernel-0.2.0/CHANGELOG_RELEASE.md +125 -0
- loom_kernel-0.2.0/PKG-INFO +459 -0
- loom_kernel-0.2.0/README.md +424 -0
- loom_kernel-0.2.0/docs/examples-repo/index.md +477 -0
- loom_kernel-0.2.0/docs/guides/autocrud.md +166 -0
- loom_kernel-0.2.0/docs/guides/celery.md +538 -0
- loom_kernel-0.2.0/docs/guides/fake-repo-examples.md +28 -0
- loom_kernel-0.2.0/docs/guides/quickstart.md +405 -0
- loom_kernel-0.2.0/docs/guides/use-case-dsl.md +474 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/docs/index.rst +4 -1
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/pyproject.toml +4 -2
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/celery/__init__.py +2 -0
- loom_kernel-0.2.0/src/loom/celery/auto.py +45 -0
- loom_kernel-0.2.0/src/loom/celery/bootstrap.py +776 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/celery/config.py +20 -0
- loom_kernel-0.2.0/src/loom/celery/constants.py +22 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/celery/runner.py +9 -7
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/celery/service.py +42 -21
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/backend/__init__.py +6 -0
- loom_kernel-0.2.0/src/loom/core/backend/core_model.py +426 -0
- loom_kernel-0.2.0/src/loom/core/backend/sqlalchemy.py +909 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/bootstrap/__init__.py +8 -1
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/bootstrap/bootstrap.py +15 -5
- loom_kernel-0.2.0/src/loom/core/bootstrap/kernel.py +100 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/cache/repository.py +107 -4
- loom_kernel-0.2.0/src/loom/core/config/keys.py +24 -0
- loom_kernel-0.2.0/src/loom/core/contracts/__init__.py +1 -0
- loom_kernel-0.2.0/src/loom/core/contracts/manifest.py +38 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/discovery/_utils.py +67 -22
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/discovery/interfaces.py +1 -1
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/discovery/manifest.py +30 -6
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/discovery/modules.py +1 -1
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/engine/compiler.py +1 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/engine/executor.py +26 -11
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/engine/plan.py +5 -0
- loom_kernel-0.2.0/src/loom/core/errors/codes.py +32 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/errors/errors.py +8 -6
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/job/service.py +0 -1
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/model/__init__.py +0 -4
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/model/projection.py +19 -19
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/projection/__init__.py +8 -6
- loom_kernel-0.2.0/src/loom/core/projection/loaders.py +265 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/projection/runtime.py +89 -159
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/repository/abc/repo_for.py +19 -1
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/repository/abc/repository.py +8 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/repository/sqlalchemy/__init__.py +12 -8
- loom_kernel-0.2.0/src/loom/core/repository/sqlalchemy/loaders.py +134 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/repository/sqlalchemy/mixins.py +179 -310
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/repository/sqlalchemy/query_compiler/compiler.py +44 -40
- loom_kernel-0.2.0/src/loom/core/repository/sqlalchemy/registry.py +125 -0
- loom_kernel-0.2.0/src/loom/core/use_case/constants.py +27 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/use_case/factory.py +3 -2
- loom_kernel-0.2.0/src/loom/core/use_case/invoker.py +120 -0
- loom_kernel-0.2.0/src/loom/core/use_case/keys.py +55 -0
- loom_kernel-0.2.0/src/loom/core/use_case/registry.py +88 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/use_case/use_case.py +9 -3
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/prometheus/adapter.py +43 -4
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/rest/autocrud.py +25 -24
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/rest/compiler.py +4 -0
- loom_kernel-0.2.0/src/loom/rest/constants.py +29 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/rest/errors.py +7 -6
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/rest/fastapi/app.py +12 -6
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/rest/fastapi/auto.py +164 -85
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/rest/fastapi/openapi.py +17 -15
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/rest/fastapi/router_runtime.py +13 -10
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/testing/in_memory.py +29 -16
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/testing/repository_harness.py +6 -1
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/testing/runner.py +1 -1
- loom_kernel-0.2.0/tests/integration/celery_bootstrap/config/conf.celery.integration.yaml +51 -0
- loom_kernel-0.2.0/tests/integration/celery_bootstrap/test_auto_create_app_integration.py +402 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/integration/celery_bootstrap/test_bootstrap_worker.py +6 -5
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/integration/core/repository/sqlalchemy/test_repository_integration.py +88 -1
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/integration/core/rest/test_fastapi_app_integration.py +10 -2
- loom_kernel-0.2.0/tests/integration/core/use_case/test_custom_repository_integration.py +103 -0
- loom_kernel-0.2.0/tests/integration/fake_repo/config/conf.interfaces.yaml +14 -0
- loom_kernel-0.2.0/tests/integration/fake_repo/config/conf.manifest.yaml +8 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/integration/fake_repo/config/conf.modules.yaml +4 -17
- loom_kernel-0.1.0/tests/integration/fake_repo/config/conf.manifest.yaml → loom_kernel-0.2.0/tests/integration/fake_repo/config/conf.yaml +0 -4
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/integration/fake_repo/manifest.py +4 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/integration/fake_repo/product/interface.py +6 -0
- loom_kernel-0.2.0/tests/integration/fake_repo/product/jobs.py +17 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/integration/fake_repo/product/model.py +7 -21
- loom_kernel-0.2.0/tests/integration/fake_repo/product/repository.py +37 -0
- loom_kernel-0.2.0/tests/integration/fake_repo/product/repository_contract.py +14 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/integration/fake_repo/product/use_cases.py +10 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/celery_bootstrap/test_bootstrap.py +162 -3
- loom_kernel-0.2.0/tests/unit/celery_jobs/test_auto.py +73 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/celery_jobs/test_celery_service.py +8 -4
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/celery_jobs/test_runner.py +9 -4
- loom_kernel-0.2.0/tests/unit/core/backend/test_backend_compiler.py +246 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/core/bootstrap/test_bootstrap.py +8 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/core/bootstrap/test_bootstrap_metrics.py +20 -14
- loom_kernel-0.2.0/tests/unit/core/bootstrap/test_kernel.py +58 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/core/cache/test_cached_repository.py +120 -0
- loom_kernel-0.2.0/tests/unit/core/discovery/test_manifest.py +50 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/core/engine/test_executor.py +118 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/core/engine/test_executor_uow.py +53 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/core/errors/test_errors.py +8 -7
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/core/job/test_inline_service.py +2 -4
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/core/projection/test_runtime.py +13 -29
- loom_kernel-0.2.0/tests/unit/core/repository/sqlalchemy/test_loaders.py +113 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/core/repository/sqlalchemy/test_repository.py +89 -1
- loom_kernel-0.2.0/tests/unit/core/use_case/test_invoker.py +152 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/rest/test_autocrud.py +21 -18
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/rest/test_rest_adapter.py +2 -1
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/rest/test_rest_compiler.py +50 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/testing/test_in_memory.py +9 -3
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/uv.lock +18 -4
- loom_kernel-0.1.0/CHANGELOG.md +0 -69
- loom_kernel-0.1.0/CHANGELOG_RELEASE.md +0 -74
- loom_kernel-0.1.0/PKG-INFO +0 -248
- loom_kernel-0.1.0/README.md +0 -215
- loom_kernel-0.1.0/docs/examples-repo/index.md +0 -16
- loom_kernel-0.1.0/docs/guides/autocrud.md +0 -25
- loom_kernel-0.1.0/docs/guides/fake-repo-examples.md +0 -17
- loom_kernel-0.1.0/docs/guides/quickstart.md +0 -59
- loom_kernel-0.1.0/docs/guides/use-case-dsl.md +0 -76
- loom_kernel-0.1.0/src/loom/celery/bootstrap.py +0 -317
- loom_kernel-0.1.0/src/loom/core/backend/sqlalchemy.py +0 -291
- loom_kernel-0.1.0/src/loom/core/projection/loaders.py +0 -94
- loom_kernel-0.1.0/src/loom/core/repository/sqlalchemy/loaders.py +0 -235
- loom_kernel-0.1.0/tests/integration/fake_repo/config/conf.interfaces.yaml +0 -24
- loom_kernel-0.1.0/tests/integration/fake_repo/config/conf.yaml +0 -24
- loom_kernel-0.1.0/tests/unit/core/backend/test_backend_compiler.py +0 -114
- loom_kernel-0.1.0/tests/unit/core/repository/sqlalchemy/test_loaders.py +0 -493
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/.github/workflows/ci-main.yml +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/.github/workflows/ci-pr.yml +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/.github/workflows/docs.yml +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/.github/workflows/release.yml +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/.gitignore +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/.pre-commit-config.yaml +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/.readthedocs.yaml +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/LICENSE +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/Makefile +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/codecov.yml +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/docs/_static/.gitkeep +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/docs/_static/custom.css +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/docs/_static/logo-transparent.png +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/docs/_static/logo.svg +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/docs/architecture/adr/README.md +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/docs/architecture/clean-architecture.md +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/docs/architecture/overview.md +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/docs/conf.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/docs/reference/api/core.rst +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/docs/reference/api/repository.rst +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/docs/reference/api/rest.rst +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/docs/reference/api/testing.rst +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/docs/reference/index.rst +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/docs/requirements.txt +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/sonar-project.properties +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/__init__.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/celery/event_loop.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/backend/protocol.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/cache/__init__.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/cache/abc/__init__.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/cache/abc/backend.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/cache/abc/config.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/cache/abc/dependency.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/cache/codec.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/cache/decorators.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/cache/dependency.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/cache/gateway.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/cache/keys.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/cache/serializer.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/command/__init__.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/command/adapter.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/command/base.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/command/field.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/command/introspection.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/config/__init__.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/config/errors.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/config/loader.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/config/model.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/di/__init__.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/di/container.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/di/scope.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/discovery/__init__.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/discovery/base.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/engine/__init__.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/engine/compilable.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/engine/events.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/engine/metrics.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/errors/__init__.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/job/__init__.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/job/callback.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/job/context.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/job/handle.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/job/job.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/logger/__init__.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/logger/abc.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/logger/config.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/logger/registry.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/logger/structlogger.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/model/base.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/model/enums.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/model/field.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/model/introspection.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/model/relation.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/model/timestamped.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/model/types.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/model/types_postgres.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/repository/__init__.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/repository/abc/__init__.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/repository/abc/query.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/repository/mutation.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/repository/sqlalchemy/integrity.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/repository/sqlalchemy/model.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/repository/sqlalchemy/profile_loader.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/repository/sqlalchemy/projection.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/repository/sqlalchemy/query_compiler/__init__.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/repository/sqlalchemy/query_compiler/cursor.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/repository/sqlalchemy/query_compiler/errors.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/repository/sqlalchemy/query_compiler/filters.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/repository/sqlalchemy/query_compiler/ordering.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/repository/sqlalchemy/query_compiler/paths.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/repository/sqlalchemy/query_compiler/subquery.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/repository/sqlalchemy/repository.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/repository/sqlalchemy/session_manager.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/repository/sqlalchemy/transactional.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/repository/sqlalchemy/uow.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/response/__init__.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/response/base.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/tracing/__init__.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/tracing/context.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/transport/__init__.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/transport/adapter.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/uow/__init__.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/uow/abc.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/uow/context.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/use_case/__init__.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/use_case/_predicates.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/use_case/compute.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/use_case/field_ref.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/use_case/markers.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/core/use_case/rule.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/prometheus/__init__.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/prometheus/middleware.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/rest/__init__.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/rest/adapter.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/rest/fastapi/__init__.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/rest/fastapi/response.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/rest/middleware.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/rest/model.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/rest/rest_adapter.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/testing/__init__.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/testing/golden.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/src/loom/testing/http_harness.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/__init__.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/conftest.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/golden/__init__.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/golden/baselines/.gitkeep +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/golden/outputs/.gitkeep +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/golden/plans/.gitkeep +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/helpers/__init__.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/integration/__init__.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/integration/celery_bootstrap/__init__.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/integration/conftest.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/integration/core/__init__.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/integration/core/repository/__init__.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/integration/core/repository/sqlalchemy/__init__.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/integration/core/repository/sqlalchemy/conftest.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/integration/core/repository/sqlalchemy/test_cache_integration.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/integration/core/rest/__init__.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/integration/core/rest/test_auto_interface_integration.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/integration/core/use_case/test_use_case_crud_integration.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/integration/fake_repo/__init__.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/integration/fake_repo/config/__init__.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/integration/fake_repo/main.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/integration/fake_repo/product/__init__.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/integration/fake_repo/product/category/__init__.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/integration/fake_repo/product/category/model.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/integration/fake_repo/product/category/schemas.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/integration/fake_repo/product/relations.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/integration/fake_repo/product/review/__init__.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/integration/fake_repo/product/review/model.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/integration/fake_repo/product/review/schemas.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/integration/fake_repo/product/schemas.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/celery_bootstrap/__init__.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/celery_bootstrap/test_event_loop.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/celery_jobs/__init__.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/celery_jobs/test_config.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/core/backend/__init__.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/core/bootstrap/__init__.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/core/command/__init__.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/core/command/test_command_base.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/core/command/test_command_field.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/core/command/test_command_patch.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/core/command/test_introspection.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/core/config/__init__.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/core/config/test_config.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/core/di/__init__.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/core/di/test_container.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/core/engine/__init__.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/core/engine/test_compiler.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/core/engine/test_executor_trace.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/core/engine/test_metrics.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/core/engine/test_plan.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/core/errors/__init__.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/core/job/__init__.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/core/job/conftest.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/core/job/test_callback.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/core/job/test_context.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/core/job/test_handle.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/core/job/test_job.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/core/logger/test_registry.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/core/model/__init__.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/core/model/test_model.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/core/model/test_timestamped.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/core/repository/abc/conftest.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/core/repository/abc/test_query.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/core/repository/abc/test_repository_contract.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/core/repository/sqlalchemy/conftest.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/core/repository/sqlalchemy/test_transactional.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/core/tracing/__init__.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/core/tracing/test_context.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/core/uow/__init__.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/core/uow/test_executor_uow.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/core/uow/test_sqlalchemy_uow.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/core/uow/test_uow_protocols.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/core/use_case/__init__.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/core/use_case/test_compute.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/core/use_case/test_factory.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/core/use_case/test_field_ref.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/core/use_case/test_markers.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/core/use_case/test_rule.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/core/use_case/test_use_case.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/prometheus/__init__.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/prometheus/test_adapter.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/prometheus/test_middleware.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/rest/__init__.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/rest/test_fastapi_auto_logger.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/rest/test_middleware.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/rest/test_pydantic_adapter.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/rest/test_response.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/rest/test_rest_model.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/rest/test_router_runtime.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/testing/__init__.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/testing/test_golden.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/testing/test_http_harness.py +0 -0
- {loom_kernel-0.1.0 → loom_kernel-0.2.0}/tests/unit/testing/test_runner.py +0 -0
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# 🚀 Release 0.2.0 ([#9](https://github.com/the-reacher-data/loom-py/pull/9)) ([`2f669ab`](https://github.com/the-reacher-data/loom-py/commit/2f669ab205c7255eb6494e4cdb8ab8092817af62))
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
## ✨ Features
|
|
5
|
+
### core
|
|
6
|
+
- **core:** typed repository abstractions and SQLAlchemy backend<br>
|
|
7
|
+
> Async repository protocol (RepositoryRead, RepositoryWrite, RepoFor) backed
|
|
8
|
+
> by SQLAlchemy 2.0 async session. Struct-based model system using
|
|
9
|
+
> msgspec.Struct
|
|
10
|
+
> as the single source of truth — models compile to SA mapped classes at startup
|
|
11
|
+
> via compile_all(). count() and UPDATE RETURNING included as first-class
|
|
12
|
+
> operations.
|
|
13
|
+
|
|
14
|
+
- **core:** use-case DSL with field refs, compute, rules and typed markers<br>
|
|
15
|
+
> Declarative use-case definition via Input, Load, LoadById, Exists, Compute and
|
|
16
|
+
> Rule markers. Signature inspection runs once at compile time; RuntimeExecutor
|
|
17
|
+
> drives execution from an immutable ExecutionPlan. No per-request reflection.
|
|
18
|
+
|
|
19
|
+
- **core:** ApplicationInvoker and named use-case registry<br>
|
|
20
|
+
> Use cases and job callbacks invoke other use cases by type through
|
|
21
|
+
> ApplicationInvoker without direct coupling. A named registry maps use-case
|
|
22
|
+
> keys to compiled instances at bootstrap, providing a stable cross-invocation
|
|
23
|
+
> contract.
|
|
24
|
+
|
|
25
|
+
- **core:** compiled model artifact and cache entity keys<br>
|
|
26
|
+
> compile_all() produces a typed CompiledCore artifact exposing stable entity
|
|
27
|
+
> keys used by the cache layer for deterministic repository-level invalidation
|
|
28
|
+
> across reads and writes.
|
|
29
|
+
|
|
30
|
+
- **core:** executor skips UoW for read-only use cases and GET routes<br>
|
|
31
|
+
> UseCase.read_only=True and all GET routes bypass UoW.begin/commit, removing
|
|
32
|
+
> at minimum one BEGIN+COMMIT round-trip from every read request on PostgreSQL.
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
### projection
|
|
36
|
+
- **projection:** compiler-driven memory/SQL routing<br>
|
|
37
|
+
> Projections are source-agnostic at declaration time. The backend compiler
|
|
38
|
+
> decides at compile_all() whether each projection runs in-memory (relation
|
|
39
|
+
> already loaded in the active profile) or via SQL. Users declare only
|
|
40
|
+
> CountLoader, ExistsLoader, or JoinFieldsLoader — no source= parameter.
|
|
41
|
+
> Internal _Memory* and _Sql* loaders are synthesized at compile time.
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
### cache
|
|
45
|
+
- **cache:** aiocache gateway with auto-inferred invalidation specs<br>
|
|
46
|
+
> CachedRepository wraps any repository with read-through/write-through caching.
|
|
47
|
+
> ONE_TO_MANY depends_on specs are auto-generated from field annotations — no
|
|
48
|
+
> explicit declaration needed. Explicit depends_on always wins.
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
### job
|
|
52
|
+
- **job:** async job domain model and orchestration primitives<br>
|
|
53
|
+
> Job[ResultT] base class with Celery routing ClassVars. JobHandle / JobGroup
|
|
54
|
+
> with dual-mode waiting (Celery + inline). JobCallback lifecycle with
|
|
55
|
+
> on_success/on_failure. Dispatch is transactionally safe — jobs flush on
|
|
56
|
+
> UoW commit and are cleared on rollback.
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
### celery
|
|
60
|
+
- **celery:** production-ready Celery integration layer<br>
|
|
61
|
+
> CeleryJobService, persistent worker event loop, trace propagation, eager
|
|
62
|
+
> fallback, and task_default_queue routing so callbacks land on the correct
|
|
63
|
+
> consumed queue. bootstrap_worker compiles use cases, repositories, and
|
|
64
|
+
> registers Celery tasks in a single call.
|
|
65
|
+
|
|
66
|
+
- **celery:** worker job discovery from modules or manifest<br>
|
|
67
|
+
> bootstrap_worker discovers and registers Job classes automatically from
|
|
68
|
+
> module include paths (mode: modules) or from a typed WorkerManifest
|
|
69
|
+
> (mode: manifest). WorkerManifest replaces scattered JOBS/USE_CASES/INTERFACES
|
|
70
|
+
> module attributes with a single typed contract.
|
|
71
|
+
|
|
72
|
+
- **celery:** interfaces= and use_cases= on bootstrap_worker<br>
|
|
73
|
+
> Callbacks that call ApplicationInvoker need matching use-case keys compiled
|
|
74
|
+
> in the worker. interfaces= extracts use-case types from RestInterface route
|
|
75
|
+
> declarations (including AutoCRUD-generated ones). use_cases= handles
|
|
76
|
+
> non-AutoCRUD scenarios. Both can be combined with discovery mode.
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
### rest
|
|
80
|
+
- **rest:** AutoCRUD and FastAPI adapter<br>
|
|
81
|
+
> RestInterface.auto=True generates full CRUD routes at class definition time
|
|
82
|
+
> via build_auto_routes(). OpenAPI contracts expose query params, pagination
|
|
83
|
+
> defaults, and decoupled CreateInput/UpdateInput write DTOs. Discovery engine
|
|
84
|
+
> mounts all declared interfaces at bootstrap.
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
### observability
|
|
88
|
+
- **observability:** trace_id propagation and Prometheus adapter<br>
|
|
89
|
+
> trace_id injected into every request context and propagated to job callbacks.
|
|
90
|
+
> MetricsAdapter protocol emits execution events; PrometheusAdapter records
|
|
91
|
+
> latency histograms and error counters with low cardinality labels.
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
## 📖 Documentation
|
|
97
|
+
- Sphinx documentation platform with full public guides<br>
|
|
98
|
+
> Quickstart, use-case DSL reference, AutoCRUD guide, Celery integration guide
|
|
99
|
+
> (job definition, dispatch, callbacks, YAML reference, bootstrap options,
|
|
100
|
+
> ApplicationInvoker, Docker-compose stack), and dummy-loom examples-repo
|
|
101
|
+
> walkthrough. Deployed to Read the Docs.
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
## ⚡ Performance
|
|
108
|
+
### repository
|
|
109
|
+
- **repository:** single-query total count for offset pagination<br>
|
|
110
|
+
> list_with_query with PaginationMode.OFFSET issues a single SELECT COUNT(*)
|
|
111
|
+
> instead of a separate full-table scan, eliminating one round-trip per
|
|
112
|
+
> paginated list operation.
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
### engine
|
|
116
|
+
- **engine:** UPDATE RETURNING replaces SELECT + flush + refresh<br>
|
|
117
|
+
> SQLAlchemyUpdateMixin.update() issues a single UPDATE ... RETURNING
|
|
118
|
+
> round-trip.
|
|
119
|
+
> Server-side onupdate expressions are pre-computed at init time and injected
|
|
120
|
+
> into the SET clause automatically.
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# 🚀 Release 0.2.0 ([#9](https://github.com/the-reacher-data/loom-py/pull/9)) ([`2f669ab`](https://github.com/the-reacher-data/loom-py/commit/2f669ab205c7255eb6494e4cdb8ab8092817af62))
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
## ✨ Features
|
|
5
|
+
### core
|
|
6
|
+
- **core:** typed repository abstractions and SQLAlchemy backend<br>
|
|
7
|
+
> Async repository protocol (RepositoryRead, RepositoryWrite, RepoFor) backed
|
|
8
|
+
> by SQLAlchemy 2.0 async session. Struct-based model system using
|
|
9
|
+
> msgspec.Struct
|
|
10
|
+
> as the single source of truth — models compile to SA mapped classes at startup
|
|
11
|
+
> via compile_all(). count() and UPDATE RETURNING included as first-class
|
|
12
|
+
> operations.
|
|
13
|
+
|
|
14
|
+
- **core:** use-case DSL with field refs, compute, rules and typed markers<br>
|
|
15
|
+
> Declarative use-case definition via Input, Load, LoadById, Exists, Compute and
|
|
16
|
+
> Rule markers. Signature inspection runs once at compile time; RuntimeExecutor
|
|
17
|
+
> drives execution from an immutable ExecutionPlan. No per-request reflection.
|
|
18
|
+
|
|
19
|
+
- **core:** ApplicationInvoker and named use-case registry<br>
|
|
20
|
+
> Use cases and job callbacks invoke other use cases by type through
|
|
21
|
+
> ApplicationInvoker without direct coupling. A named registry maps use-case
|
|
22
|
+
> keys to compiled instances at bootstrap, providing a stable cross-invocation
|
|
23
|
+
> contract.
|
|
24
|
+
|
|
25
|
+
- **core:** compiled model artifact and cache entity keys<br>
|
|
26
|
+
> compile_all() produces a typed CompiledCore artifact exposing stable entity
|
|
27
|
+
> keys used by the cache layer for deterministic repository-level invalidation
|
|
28
|
+
> across reads and writes.
|
|
29
|
+
|
|
30
|
+
- **core:** executor skips UoW for read-only use cases and GET routes<br>
|
|
31
|
+
> UseCase.read_only=True and all GET routes bypass UoW.begin/commit, removing
|
|
32
|
+
> at minimum one BEGIN+COMMIT round-trip from every read request on PostgreSQL.
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
### projection
|
|
36
|
+
- **projection:** compiler-driven memory/SQL routing<br>
|
|
37
|
+
> Projections are source-agnostic at declaration time. The backend compiler
|
|
38
|
+
> decides at compile_all() whether each projection runs in-memory (relation
|
|
39
|
+
> already loaded in the active profile) or via SQL. Users declare only
|
|
40
|
+
> CountLoader, ExistsLoader, or JoinFieldsLoader — no source= parameter.
|
|
41
|
+
> Internal _Memory* and _Sql* loaders are synthesized at compile time.
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
### cache
|
|
45
|
+
- **cache:** aiocache gateway with auto-inferred invalidation specs<br>
|
|
46
|
+
> CachedRepository wraps any repository with read-through/write-through caching.
|
|
47
|
+
> ONE_TO_MANY depends_on specs are auto-generated from field annotations — no
|
|
48
|
+
> explicit declaration needed. Explicit depends_on always wins.
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
### job
|
|
52
|
+
- **job:** async job domain model and orchestration primitives<br>
|
|
53
|
+
> Job[ResultT] base class with Celery routing ClassVars. JobHandle / JobGroup
|
|
54
|
+
> with dual-mode waiting (Celery + inline). JobCallback lifecycle with
|
|
55
|
+
> on_success/on_failure. Dispatch is transactionally safe — jobs flush on
|
|
56
|
+
> UoW commit and are cleared on rollback.
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
### celery
|
|
60
|
+
- **celery:** production-ready Celery integration layer<br>
|
|
61
|
+
> CeleryJobService, persistent worker event loop, trace propagation, eager
|
|
62
|
+
> fallback, and task_default_queue routing so callbacks land on the correct
|
|
63
|
+
> consumed queue. bootstrap_worker compiles use cases, repositories, and
|
|
64
|
+
> registers Celery tasks in a single call.
|
|
65
|
+
|
|
66
|
+
- **celery:** worker job discovery from modules or manifest<br>
|
|
67
|
+
> bootstrap_worker discovers and registers Job classes automatically from
|
|
68
|
+
> module include paths (mode: modules) or from a typed WorkerManifest
|
|
69
|
+
> (mode: manifest). WorkerManifest replaces scattered JOBS/USE_CASES/INTERFACES
|
|
70
|
+
> module attributes with a single typed contract.
|
|
71
|
+
|
|
72
|
+
- **celery:** interfaces= and use_cases= on bootstrap_worker<br>
|
|
73
|
+
> Callbacks that call ApplicationInvoker need matching use-case keys compiled
|
|
74
|
+
> in the worker. interfaces= extracts use-case types from RestInterface route
|
|
75
|
+
> declarations (including AutoCRUD-generated ones). use_cases= handles
|
|
76
|
+
> non-AutoCRUD scenarios. Both can be combined with discovery mode.
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
### rest
|
|
80
|
+
- **rest:** AutoCRUD and FastAPI adapter<br>
|
|
81
|
+
> RestInterface.auto=True generates full CRUD routes at class definition time
|
|
82
|
+
> via build_auto_routes(). OpenAPI contracts expose query params, pagination
|
|
83
|
+
> defaults, and decoupled CreateInput/UpdateInput write DTOs. Discovery engine
|
|
84
|
+
> mounts all declared interfaces at bootstrap.
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
### observability
|
|
88
|
+
- **observability:** trace_id propagation and Prometheus adapter<br>
|
|
89
|
+
> trace_id injected into every request context and propagated to job callbacks.
|
|
90
|
+
> MetricsAdapter protocol emits execution events; PrometheusAdapter records
|
|
91
|
+
> latency histograms and error counters with low cardinality labels.
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
## 📖 Documentation
|
|
97
|
+
- Sphinx documentation platform with full public guides<br>
|
|
98
|
+
> Quickstart, use-case DSL reference, AutoCRUD guide, Celery integration guide
|
|
99
|
+
> (job definition, dispatch, callbacks, YAML reference, bootstrap options,
|
|
100
|
+
> ApplicationInvoker, Docker-compose stack), and dummy-loom examples-repo
|
|
101
|
+
> walkthrough. Deployed to Read the Docs.
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
## ⚡ Performance
|
|
108
|
+
### repository
|
|
109
|
+
- **repository:** single-query total count for offset pagination<br>
|
|
110
|
+
> list_with_query with PaginationMode.OFFSET issues a single SELECT COUNT(*)
|
|
111
|
+
> instead of a separate full-table scan, eliminating one round-trip per
|
|
112
|
+
> paginated list operation.
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
### engine
|
|
116
|
+
- **engine:** UPDATE RETURNING replaces SELECT + flush + refresh<br>
|
|
117
|
+
> SQLAlchemyUpdateMixin.update() issues a single UPDATE ... RETURNING
|
|
118
|
+
> round-trip.
|
|
119
|
+
> Server-side onupdate expressions are pre-computed at init time and injected
|
|
120
|
+
> into the SET clause automatically.
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
|