voodoo-framework 2.7.0__tar.gz → 2.7.2__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.
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/PKG-INFO +1 -1
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/__init__.py +1 -1
- voodoo_framework-2.7.2/src/voodoo/cli/create.py +119 -0
- voodoo_framework-2.7.2/src/voodoo/data/__init__.py +80 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/data/store_backend.py +8 -19
- voodoo_framework-2.7.2/src/voodoo/data/store_facade.py +346 -0
- voodoo_framework-2.7.2/src/voodoo/storage/__init__.py +81 -0
- voodoo_framework-2.7.2/src/voodoo/storage/database/__init__.py +51 -0
- voodoo_framework-2.7.2/src/voodoo/storage/events/__init__.py +36 -0
- voodoo_framework-2.7.2/src/voodoo/storage/execution/__init__.py +41 -0
- voodoo_framework-2.7.2/src/voodoo/storage/queue/__init__.py +51 -0
- voodoo_framework-2.7.2/src/voodoo/storage/scheduler/__init__.py +49 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo_framework.egg-info/PKG-INFO +1 -1
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo_framework.egg-info/SOURCES.txt +1 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_auth.py +5 -13
- voodoo_framework-2.7.2/tests/test_create.py +104 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_create_store_smoke.py +8 -6
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_data.py +32 -46
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_model.py +33 -65
- voodoo_framework-2.7.2/tests/test_store_only_core_import.py +89 -0
- voodoo_framework-2.7.0/src/voodoo/cli/create.py +0 -325
- voodoo_framework-2.7.0/src/voodoo/data/__init__.py +0 -51
- voodoo_framework-2.7.0/src/voodoo/data/store_facade.py +0 -140
- voodoo_framework-2.7.0/src/voodoo/storage/__init__.py +0 -49
- voodoo_framework-2.7.0/src/voodoo/storage/database/__init__.py +0 -32
- voodoo_framework-2.7.0/src/voodoo/storage/events/__init__.py +0 -16
- voodoo_framework-2.7.0/src/voodoo/storage/execution/__init__.py +0 -15
- voodoo_framework-2.7.0/src/voodoo/storage/queue/__init__.py +0 -36
- voodoo_framework-2.7.0/src/voodoo/storage/scheduler/__init__.py +0 -31
- voodoo_framework-2.7.0/tests/test_create.py +0 -157
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/LICENSE +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/README.md +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/pyproject.toml +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/setup.cfg +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/adapters/__init__.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/adapters/capabilities.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/adapters/registry.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/adapters/tailwind.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/adapters/voodoo_css.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/agent.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/agents/__init__.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/agents/models.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/agents/registry.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/ai/__init__.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/ai/agent.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/ai/agent_legacy.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/ai/agent_runtime_truth.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/ai/providers/__init__.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/ai/providers/anthropic.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/ai/providers/gemini.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/ai/providers/mock.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/ai/providers/ollama.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/ai/providers/openai.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/ai/tools/__init__.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/ai/tools/registry.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/api.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/auth/__init__.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/auth/cookies.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/auth/guards.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/auth/jwt.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/auth/middleware.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/auth/passwords.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/auth/user.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/cli/__init__.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/cli/__main__.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/cli/agents.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/cli/ai.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/cli/approvals.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/cli/auth.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/cli/dev.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/cli/doctor.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/cli/executions.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/cli/fabric.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/cli/generate.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/cli/inspect.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/cli/new.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/cli/objects.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/cli/protocol.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/cli/recover.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/cli/routes.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/cli/scaffolding.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/cli/schedules.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/cli/status.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/cli/tasks.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/cli/terminal.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/cli/theme.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/cli/version.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/cli/workers_cmd.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/components.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/config.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/core/__init__.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/core/app.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/core/errors.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/core/events.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/core/render.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/core/routing.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/core/sitemap.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/core/state.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/data/base.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/data/model.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/data/store_model.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/edge/__init__.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/edge/auth.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/edge/errors.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/edge/gateway.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/edge/http.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/edge/models.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/edge/mqtt.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/edge/protocol.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/edge/simulator.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/edge/store.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/edge/store_voodoo.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/edge/world.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/i18n.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/mcp/__init__.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/mcp/client.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/memory/__init__.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/memory/interfaces.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/memory/sqlite.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/mesh/__init__.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/mesh/auth.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/mesh/client.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/mesh/event_bus.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/mesh/remote.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/mesh/replay.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/primitives/__init__.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/primitives/capability.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/primitives/compute.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/primitives/constraint.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/primitives/effect.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/primitives/intent.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/primitives/resource.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/primitives/state.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/primitives/time.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/protocol/__init__.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/protocol/export.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/protocol/fabric.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/protocol/operational.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/protocol/schemas.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/py.typed +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/queue.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/routing/api.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/routing/pages.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/runtime/__init__.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/runtime/adaptive.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/runtime/capability.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/runtime/constraint.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/runtime/context.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/runtime/dashboard.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/runtime/engine.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/runtime/errors.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/runtime/execution.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/runtime/fabric.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/runtime/goal.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/runtime/goal_store.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/runtime/graph.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/runtime/human.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/runtime/identity.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/runtime/identity_store.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/runtime/membership.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/runtime/operations.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/runtime/persistence.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/runtime/planner.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/runtime/policy.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/runtime/scheduler.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/runtime/store.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/runtime/task.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/runtime/transaction.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/runtime/workflow.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/runtime/workflow_store.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/runtime/world_execution.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/schedule.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/security/__init__.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/security/cors.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/security/csrf.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/security/headers.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/security/passwords.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/security/rate_limit.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/security/redaction.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/security/secrets.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/seo.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/static/client.js +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/status.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/storage/cache/__init__.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/storage/cache/interfaces.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/storage/cache/memory.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/storage/cache/redis.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/storage/database/interfaces.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/storage/database/postgres.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/storage/database/sqlite.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/storage/events/interfaces.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/storage/events/local.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/storage/events/postgres.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/storage/events/sqlite.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/storage/events/store.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/storage/execution/migrations.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/storage/execution/postgres.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/storage/execution/sqlite.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/storage/execution/store.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/storage/manager.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/storage/objects/__init__.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/storage/objects/interfaces.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/storage/objects/local.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/storage/objects/s3.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/storage/objects/store.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/storage/queue/interfaces.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/storage/queue/memory.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/storage/queue/postgres.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/storage/queue/redis.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/storage/queue/sqlite.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/storage/queue/store.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/storage/scheduler/sqlite.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/storage/scheduler/store.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/telemetry/__init__.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/telemetry/api.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/telemetry/middleware.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/telemetry/otlp.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/telemetry/store.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/theme.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/tools/__init__.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/tools/registry.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/ui/__init__.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/ui/component.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/ui/events.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/ui/interactive.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/ui/layout.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/ui/library.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/ui/markdown.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/ui/primitives.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/ui/product.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/ui/rendering.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/ui/state.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/ui/styles/__init__.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/ui/styles/presets.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/ui/styles/product.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/ui/styles/system.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/ui/styles/theme.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/ui/styles/voodoo_system.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/ui/voodoo_system.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/workers/__init__.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/workers/queue.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/world/__init__.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/world/model.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/world/models.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/world/sqlite.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo/world/store.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo_framework.egg-info/dependency_links.txt +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo_framework.egg-info/entry_points.txt +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo_framework.egg-info/requires.txt +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/src/voodoo_framework.egg-info/top_level.txt +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_adaptive_agency_correctness.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_agency_runtime_truth.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_agent.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_agent_registry.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_agent_runtime.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_app.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_capability_security.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_checkpoint_resume.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_chrome.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_cli.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_cli_fabric.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_cli_inspect.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_components.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_config.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_contract_api.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_design_system.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_design_system2.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_durable_goal_runtime.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_durable_hitl.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_durable_workflow_runtime.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_edge_device.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_edge_e2e.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_edge_gateway.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_edge_http.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_edge_protocol.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_edge_security.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_edge_voodoo_store.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_edge_world.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_events.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_execution_sqlite_store.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_goal_runtime.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_hitl_persistence_correctness.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_http_runtime.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_human.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_i18n.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_identity_execution.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_identity_foundation.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_integration.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_mcp.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_mcp_runtime.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_memory.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_mesh.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_mesh_event_bus.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_mesh_remote_auth.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_mesh_remote_authority.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_mesh_remote_execution.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_mesh_remote_outcomes.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_mesh_remote_replay.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_mesh_two_node_acceptance.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_node_membership.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_object_store.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_observability.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_operational_policy.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_operational_runtime_ui.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_persistence.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_planner_adaptive.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_primitives.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_product_components.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_protocol.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_protocol_fabric.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_protocol_operational.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_provider_switching.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_providers.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_public_api_3.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_queue.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_reactive.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_runtime.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_runtime_correctness.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_runtime_fabric.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_runtime_store_app_lifecycle.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_runtime_store_lifecycle.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_runtime_store_provider.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_runtime_transaction.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_scheduler.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_security.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_seo.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_sprint27_convergence.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_sprint28_acceptance.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_state.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_store_first_user_journey.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_store_model_backend.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_theme.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_theme_presets.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_tools.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_ui.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_ui_magic.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_ui_magic_acceptance.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_voodoo_store_events.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_voodoo_store_execution.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_voodoo_store_hitl_restart.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_voodoo_store_queue.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_voodoo_store_scheduler.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_voodoo_system_components.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_websocket.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_worker_retry_semantics.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_workers.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_world_aware_execution.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_world_model.py +0 -0
- {voodoo_framework-2.7.0 → voodoo_framework-2.7.2}/tests/test_world_sqlite.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: voodoo-framework
|
|
3
|
-
Version: 2.7.
|
|
3
|
+
Version: 2.7.2
|
|
4
4
|
Summary: The programmable runtime for adaptive applications and operational systems — web, APIs, agents, workers, human workflows, distributed systems, and physical systems in one runtime.
|
|
5
5
|
Author-email: Helder Perez <contact@helderperez.com>
|
|
6
6
|
Maintainer-email: Helder Perez <contact@helderperez.com>
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"""CLI: ``voodoo create <app>`` — scaffold the stable default Voodoo app.
|
|
2
|
+
|
|
3
|
+
The official scaffold intentionally stays small. It demonstrates the public App,
|
|
4
|
+
page, and UI contracts while the Runtime opens the default Voodoo Store at
|
|
5
|
+
``.voodoo/application.vstore``. Specialized examples belong outside the default
|
|
6
|
+
scaffold until their APIs are stable.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
|
|
13
|
+
import typer
|
|
14
|
+
|
|
15
|
+
from voodoo.cli import terminal
|
|
16
|
+
|
|
17
|
+
__all__ = ["create"]
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
_MAIN_PY = '''"""{name} — a minimal Store-first Voodoo application."""
|
|
21
|
+
|
|
22
|
+
from voodoo import App, page
|
|
23
|
+
from voodoo.ui import A, Button, Container, Heading, Stack, Text
|
|
24
|
+
|
|
25
|
+
app = App()
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@page("/")
|
|
29
|
+
async def home():
|
|
30
|
+
return Container(
|
|
31
|
+
Stack(
|
|
32
|
+
Heading("Hello, Voodoo", level=1),
|
|
33
|
+
Text(
|
|
34
|
+
"One Runtime. One local Store. No external infrastructure required.",
|
|
35
|
+
tone="muted",
|
|
36
|
+
),
|
|
37
|
+
Button("Get started", variant="primary"),
|
|
38
|
+
A(
|
|
39
|
+
"Voodoo on GitHub",
|
|
40
|
+
href="https://github.com/helderperez-dev/voodoo",
|
|
41
|
+
target="_blank",
|
|
42
|
+
),
|
|
43
|
+
gap="md",
|
|
44
|
+
)
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
if __name__ == "__main__":
|
|
49
|
+
app.run()
|
|
50
|
+
'''
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
_VOODOO_TOML = """[app]
|
|
54
|
+
name = "{name}"
|
|
55
|
+
|
|
56
|
+
# Voodoo Store is the default local durable infrastructure.
|
|
57
|
+
# The Runtime creates .voodoo/application.vstore automatically.
|
|
58
|
+
# No database, queue, cache, or object-server configuration is required.
|
|
59
|
+
"""
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
_PYPROJECT_TOML = """[project]
|
|
63
|
+
name = "{name}"
|
|
64
|
+
version = "0.1.0"
|
|
65
|
+
requires-python = ">=3.12"
|
|
66
|
+
dependencies = ["voodoo-framework"]
|
|
67
|
+
"""
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def create(
|
|
71
|
+
project_name: str = typer.Argument(..., help="Name of the project to create"),
|
|
72
|
+
) -> None:
|
|
73
|
+
"""Scaffold the stable Store-first Voodoo application.
|
|
74
|
+
|
|
75
|
+
Creation is intentionally side-effect free: it writes the project files but
|
|
76
|
+
does not create environments, access the network, or install dependencies.
|
|
77
|
+
"""
|
|
78
|
+
project_dir = Path(project_name)
|
|
79
|
+
if project_dir.exists():
|
|
80
|
+
terminal.error(f"Directory '{project_name}' already exists")
|
|
81
|
+
raise typer.Exit(1)
|
|
82
|
+
|
|
83
|
+
terminal.wordmark()
|
|
84
|
+
terminal.blank()
|
|
85
|
+
terminal.status("creating", project_name)
|
|
86
|
+
terminal.blank()
|
|
87
|
+
|
|
88
|
+
project_dir.mkdir(parents=True)
|
|
89
|
+
(project_dir / ".voodoo").mkdir()
|
|
90
|
+
|
|
91
|
+
(project_dir / "main.py").write_text(_MAIN_PY.format(name=project_name))
|
|
92
|
+
(project_dir / "voodoo.toml").write_text(_VOODOO_TOML.format(name=project_name))
|
|
93
|
+
(project_dir / "pyproject.toml").write_text(
|
|
94
|
+
_PYPROJECT_TOML.format(name=project_name)
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
terminal.label_value("created", f"{project_name}/")
|
|
98
|
+
terminal.tree(
|
|
99
|
+
[
|
|
100
|
+
"main.py # Minimal app entry point",
|
|
101
|
+
"voodoo.toml # Runtime configuration",
|
|
102
|
+
"pyproject.toml # Resolves latest Voodoo release",
|
|
103
|
+
".voodoo/ # Local Runtime state",
|
|
104
|
+
" application.vstore # Created automatically on first run",
|
|
105
|
+
]
|
|
106
|
+
)
|
|
107
|
+
terminal.blank()
|
|
108
|
+
terminal.success("ready")
|
|
109
|
+
terminal.blank()
|
|
110
|
+
terminal.next_steps(
|
|
111
|
+
[
|
|
112
|
+
f"cd {project_name}",
|
|
113
|
+
"pip install -e .",
|
|
114
|
+
"voodoo dev",
|
|
115
|
+
"",
|
|
116
|
+
"Open http://localhost:8000.",
|
|
117
|
+
"The Runtime creates .voodoo/application.vstore on first start.",
|
|
118
|
+
]
|
|
119
|
+
)
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"""Voodoo Store-native data layer.
|
|
2
|
+
|
|
3
|
+
``Model`` and ``BaseModel`` use Voodoo Store directly. SQL adapters are optional
|
|
4
|
+
and are never imported by the default data package. Applications that need a
|
|
5
|
+
SQL adapter should import it explicitly from ``voodoo.storage.database``.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from typing import Any
|
|
11
|
+
|
|
12
|
+
from voodoo.data.store_facade import (
|
|
13
|
+
FK,
|
|
14
|
+
BaseModel,
|
|
15
|
+
Model,
|
|
16
|
+
ModelMeta,
|
|
17
|
+
_get_table_name,
|
|
18
|
+
_models,
|
|
19
|
+
_rls_policies,
|
|
20
|
+
_triggers,
|
|
21
|
+
on_insert,
|
|
22
|
+
on_update,
|
|
23
|
+
rls_policy,
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
__all__ = [
|
|
27
|
+
"BaseModel",
|
|
28
|
+
"Model",
|
|
29
|
+
"ModelMeta",
|
|
30
|
+
"FK",
|
|
31
|
+
"on_insert",
|
|
32
|
+
"on_update",
|
|
33
|
+
"rls_policy",
|
|
34
|
+
"_get_table_name",
|
|
35
|
+
"_models",
|
|
36
|
+
"_rls_policies",
|
|
37
|
+
"_triggers",
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
_sql_initialized = False
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
async def init_db(*args: Any, **kwargs: Any) -> Any:
|
|
44
|
+
"""Compatibility entry point for the optional SQL subsystem.
|
|
45
|
+
|
|
46
|
+
Importing ``voodoo`` does not load SQL or require ``aiosqlite``. Calling
|
|
47
|
+
this function explicitly opts into the legacy SQL adapter surface.
|
|
48
|
+
"""
|
|
49
|
+
global _sql_initialized
|
|
50
|
+
|
|
51
|
+
from voodoo.data.base import init_db as _init_db
|
|
52
|
+
|
|
53
|
+
result = await _init_db(*args, **kwargs)
|
|
54
|
+
_sql_initialized = True
|
|
55
|
+
return result
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
async def get_db() -> Any:
|
|
59
|
+
"""Return the explicitly initialized optional SQL connection."""
|
|
60
|
+
from voodoo.data.base import get_db as _get_db
|
|
61
|
+
|
|
62
|
+
return await _get_db()
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
async def close_db() -> None:
|
|
66
|
+
"""Close SQL only when the optional subsystem was explicitly initialized.
|
|
67
|
+
|
|
68
|
+
The Store-first Runtime calls this compatibility hook during shutdown. A
|
|
69
|
+
default application must therefore treat it as a no-op instead of importing
|
|
70
|
+
the legacy SQLite adapter merely to discover that no SQL connection exists.
|
|
71
|
+
"""
|
|
72
|
+
global _sql_initialized
|
|
73
|
+
|
|
74
|
+
if not _sql_initialized:
|
|
75
|
+
return
|
|
76
|
+
|
|
77
|
+
from voodoo.data.base import close_db as _close_db
|
|
78
|
+
|
|
79
|
+
await _close_db()
|
|
80
|
+
_sql_initialized = False
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
"""Voodoo Store-backed record persistence for the Model facade.
|
|
1
|
+
"""Voodoo Store-backed record persistence for the public Model facade.
|
|
2
2
|
|
|
3
|
-
Voodoo Store 0.2+ provides the native Collections contract used here.
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
Voodoo Store 0.2+ provides the native Collections contract used here. The
|
|
4
|
+
public data path has no SQL fallback and therefore no optional SQL dependency in
|
|
5
|
+
its import graph.
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
8
|
from __future__ import annotations
|
|
@@ -49,22 +49,11 @@ def close_owned_store() -> None:
|
|
|
49
49
|
|
|
50
50
|
|
|
51
51
|
def should_use_store() -> bool:
|
|
52
|
-
"""
|
|
53
|
-
from voodoo.data.base import _active_adapter
|
|
52
|
+
"""Return True for the public Model API.
|
|
54
53
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
return True
|
|
59
|
-
|
|
60
|
-
from voodoo.config import _load_raw_file_data
|
|
61
|
-
|
|
62
|
-
raw = _load_raw_file_data(None)
|
|
63
|
-
database = raw.get("database") if isinstance(raw, dict) else None
|
|
64
|
-
if isinstance(database, str):
|
|
65
|
-
return database.lower() == "voodoo"
|
|
66
|
-
if isinstance(database, dict) and database.get("provider"):
|
|
67
|
-
return str(database["provider"]).lower() == "voodoo"
|
|
54
|
+
Kept temporarily for compatibility with internal callers while the 2.x SQL
|
|
55
|
+
compatibility modules are retired. Public Model persistence is Store-only.
|
|
56
|
+
"""
|
|
68
57
|
return True
|
|
69
58
|
|
|
70
59
|
|
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
"""Store-native public data model for Voodoo applications.
|
|
2
|
+
|
|
3
|
+
The public ``Model`` API is backed directly by Voodoo Store Collections. SQL is
|
|
4
|
+
not part of this module's import graph. Optional SQL adapters live under
|
|
5
|
+
``voodoo.storage.database`` and are loaded only when explicitly imported.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import asyncio
|
|
11
|
+
from collections.abc import Callable
|
|
12
|
+
from typing import Any, get_type_hints
|
|
13
|
+
|
|
14
|
+
from voodoo.data.store_backend import (
|
|
15
|
+
delete_record,
|
|
16
|
+
get_record,
|
|
17
|
+
insert_record,
|
|
18
|
+
put_record,
|
|
19
|
+
scan_records,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
__all__ = [
|
|
23
|
+
"BaseModel",
|
|
24
|
+
"FK",
|
|
25
|
+
"Model",
|
|
26
|
+
"ModelMeta",
|
|
27
|
+
"StoreQuery",
|
|
28
|
+
"_get_table_name",
|
|
29
|
+
"_models",
|
|
30
|
+
"_rls_policies",
|
|
31
|
+
"_triggers",
|
|
32
|
+
"on_insert",
|
|
33
|
+
"on_update",
|
|
34
|
+
"rls_policy",
|
|
35
|
+
]
|
|
36
|
+
|
|
37
|
+
_models: list[type] = []
|
|
38
|
+
_triggers: dict[str, dict[str, list[Callable[..., Any]]]] = {}
|
|
39
|
+
_rls_policies: dict[str, Callable[..., Any]] = {}
|
|
40
|
+
_cascades: dict[str, list[tuple[str, str]]] = {}
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class _FKRef:
|
|
44
|
+
__slots__ = ("target",)
|
|
45
|
+
|
|
46
|
+
def __init__(self, target: type) -> None:
|
|
47
|
+
self.target = target
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class FK:
|
|
51
|
+
"""Field annotation declaring a Store-native cascade relationship."""
|
|
52
|
+
|
|
53
|
+
def __class_getitem__(cls, target: type) -> _FKRef: # noqa: N805
|
|
54
|
+
if not isinstance(target, type):
|
|
55
|
+
raise TypeError("FK[...] requires a model class")
|
|
56
|
+
return _FKRef(target)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def _get_table_name(cls_or_obj: Any) -> str:
|
|
60
|
+
cls = cls_or_obj if isinstance(cls_or_obj, type) else cls_or_obj.__class__
|
|
61
|
+
name = getattr(cls, "__tablename__", None)
|
|
62
|
+
return str(name) if name else cls.__name__.lower()
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def _register_foreign_keys(cls: type) -> None:
|
|
66
|
+
try:
|
|
67
|
+
hints = get_type_hints(cls)
|
|
68
|
+
except Exception:
|
|
69
|
+
hints = getattr(cls, "__annotations__", {})
|
|
70
|
+
for col_name, col_type in hints.items():
|
|
71
|
+
if isinstance(col_type, _FKRef):
|
|
72
|
+
parent = _get_table_name(col_type.target)
|
|
73
|
+
_cascades.setdefault(parent, []).append((_get_table_name(cls), col_name))
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def _clear_cascades() -> None:
|
|
77
|
+
_cascades.clear()
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
class ModelMeta(type):
|
|
81
|
+
def __init__(
|
|
82
|
+
cls, name: str, bases: tuple[type, ...], attrs: dict[str, Any]
|
|
83
|
+
) -> None:
|
|
84
|
+
super().__init__(name, bases, attrs)
|
|
85
|
+
if name not in ("BaseModel", "Model"):
|
|
86
|
+
_models.append(cls)
|
|
87
|
+
_register_foreign_keys(cls)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def on_insert(model_cls: type) -> Callable[[Callable[..., Any]], Callable[..., Any]]:
|
|
91
|
+
def decorator(func: Callable[..., Any]) -> Callable[..., Any]:
|
|
92
|
+
table = _get_table_name(model_cls)
|
|
93
|
+
_triggers.setdefault(table, {"insert": [], "update": []})["insert"].append(func)
|
|
94
|
+
return func
|
|
95
|
+
|
|
96
|
+
return decorator
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def on_update(model_cls: type) -> Callable[[Callable[..., Any]], Callable[..., Any]]:
|
|
100
|
+
def decorator(func: Callable[..., Any]) -> Callable[..., Any]:
|
|
101
|
+
table = _get_table_name(model_cls)
|
|
102
|
+
_triggers.setdefault(table, {"insert": [], "update": []})["update"].append(func)
|
|
103
|
+
return func
|
|
104
|
+
|
|
105
|
+
return decorator
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def rls_policy(model_cls: type) -> Callable[[Callable[..., Any]], Callable[..., Any]]:
|
|
109
|
+
"""Register a Store-native row policy accepting ``(row, context)``."""
|
|
110
|
+
|
|
111
|
+
def decorator(func: Callable[..., Any]) -> Callable[..., Any]:
|
|
112
|
+
_rls_policies[_get_table_name(model_cls)] = func
|
|
113
|
+
return func
|
|
114
|
+
|
|
115
|
+
return decorator
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def _model_values(obj: Any, *, include_id: bool = False) -> dict[str, Any]:
|
|
119
|
+
values: dict[str, Any] = {}
|
|
120
|
+
try:
|
|
121
|
+
hints = get_type_hints(obj.__class__)
|
|
122
|
+
except Exception:
|
|
123
|
+
hints = getattr(obj.__class__, "__annotations__", {})
|
|
124
|
+
for name in hints:
|
|
125
|
+
if name.startswith("__") or (name == "id" and not include_id):
|
|
126
|
+
continue
|
|
127
|
+
if hasattr(obj, name):
|
|
128
|
+
values[name] = getattr(obj, name)
|
|
129
|
+
return values
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
def _hydrate(model: type[Any], row: dict[str, Any]) -> Any:
|
|
133
|
+
obj = model()
|
|
134
|
+
try:
|
|
135
|
+
hints = get_type_hints(model)
|
|
136
|
+
except Exception:
|
|
137
|
+
hints = getattr(model, "__annotations__", {})
|
|
138
|
+
for key, value in row.items():
|
|
139
|
+
if hints.get(key) is bool:
|
|
140
|
+
value = bool(value)
|
|
141
|
+
setattr(obj, key, value)
|
|
142
|
+
return obj
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
def _fire_hooks(table: str, event: str, obj: Any) -> None:
|
|
146
|
+
for hook in _triggers.get(table, {}).get(event, []):
|
|
147
|
+
if asyncio.iscoroutinefunction(hook):
|
|
148
|
+
asyncio.create_task(hook(obj))
|
|
149
|
+
else:
|
|
150
|
+
hook(obj)
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
def _identity_context() -> dict[str, Any] | None:
|
|
154
|
+
try:
|
|
155
|
+
from voodoo.auth import current_user
|
|
156
|
+
|
|
157
|
+
user = current_user.get()
|
|
158
|
+
except Exception:
|
|
159
|
+
return None
|
|
160
|
+
if not user or not user.is_authenticated:
|
|
161
|
+
return None
|
|
162
|
+
return user.to_dict()
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
class BaseModel(metaclass=ModelMeta):
|
|
166
|
+
"""Store-native persistence base.
|
|
167
|
+
|
|
168
|
+
``BaseModel`` remains available as a compatibility spelling, but no longer
|
|
169
|
+
implies SQL. New code should prefer ``Model``.
|
|
170
|
+
"""
|
|
171
|
+
|
|
172
|
+
id: int
|
|
173
|
+
__tablename__: str | None = None
|
|
174
|
+
|
|
175
|
+
@classmethod
|
|
176
|
+
async def _create_table(cls) -> None:
|
|
177
|
+
"""Ensure the model collection exists in Voodoo Store.
|
|
178
|
+
|
|
179
|
+
The historical method name is retained as a Store-native collection
|
|
180
|
+
initializer; it does not create SQL tables or import a SQL adapter.
|
|
181
|
+
"""
|
|
182
|
+
scan_records(_get_table_name(cls))
|
|
183
|
+
|
|
184
|
+
@classmethod
|
|
185
|
+
async def find_all(cls, user_context: dict | None = None) -> list[Any]:
|
|
186
|
+
table = _get_table_name(cls)
|
|
187
|
+
context = user_context if user_context is not None else _identity_context()
|
|
188
|
+
rows = scan_records(table)
|
|
189
|
+
if table not in _rls_policies or context is None:
|
|
190
|
+
return [_hydrate(cls, row) for row in rows]
|
|
191
|
+
|
|
192
|
+
predicate = _rls_policies[table]
|
|
193
|
+
selected: list[Any] = []
|
|
194
|
+
for row in rows:
|
|
195
|
+
try:
|
|
196
|
+
allowed = predicate(row, context)
|
|
197
|
+
except TypeError:
|
|
198
|
+
raise RuntimeError(
|
|
199
|
+
"Store-native rls_policy callbacks must accept (row, context) "
|
|
200
|
+
"and return bool; SQL policy strings are not supported."
|
|
201
|
+
) from None
|
|
202
|
+
if allowed:
|
|
203
|
+
selected.append(_hydrate(cls, row))
|
|
204
|
+
return selected
|
|
205
|
+
|
|
206
|
+
async def insert(self) -> BaseModel:
|
|
207
|
+
table = _get_table_name(self)
|
|
208
|
+
self.id = insert_record(table, _model_values(self))
|
|
209
|
+
_fire_hooks(table, "insert", self)
|
|
210
|
+
return self
|
|
211
|
+
|
|
212
|
+
async def update(self) -> BaseModel:
|
|
213
|
+
if not getattr(self, "id", None):
|
|
214
|
+
raise ValueError("Cannot update a model without an id")
|
|
215
|
+
table = _get_table_name(self)
|
|
216
|
+
put_record(table, self.id, _model_values(self))
|
|
217
|
+
_fire_hooks(table, "update", self)
|
|
218
|
+
return self
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
class Model(BaseModel):
|
|
222
|
+
"""Async CRUD facade backed exclusively by Voodoo Store."""
|
|
223
|
+
|
|
224
|
+
@classmethod
|
|
225
|
+
async def create(cls, **kwargs: Any) -> Model:
|
|
226
|
+
obj = cls()
|
|
227
|
+
for key, value in kwargs.items():
|
|
228
|
+
setattr(obj, key, value)
|
|
229
|
+
await obj.insert()
|
|
230
|
+
return obj
|
|
231
|
+
|
|
232
|
+
@classmethod
|
|
233
|
+
async def get(cls, id: int) -> Model | None:
|
|
234
|
+
row = get_record(_get_table_name(cls), id)
|
|
235
|
+
return None if row is None else _hydrate(cls, row)
|
|
236
|
+
|
|
237
|
+
@classmethod
|
|
238
|
+
async def all(cls, user_context: dict | None = None) -> list[Model]:
|
|
239
|
+
return await cls.find_all(user_context=user_context)
|
|
240
|
+
|
|
241
|
+
@classmethod
|
|
242
|
+
def where(cls, **filters: Any) -> StoreQuery:
|
|
243
|
+
return StoreQuery(cls, filters)
|
|
244
|
+
|
|
245
|
+
@classmethod
|
|
246
|
+
async def count(cls, **filters: Any) -> int:
|
|
247
|
+
return await cls.where(**filters).count()
|
|
248
|
+
|
|
249
|
+
@classmethod
|
|
250
|
+
async def first(cls, **filters: Any) -> Model | None:
|
|
251
|
+
return await cls.where(**filters).order_by("id").first()
|
|
252
|
+
|
|
253
|
+
@classmethod
|
|
254
|
+
async def delete_where(cls, **filters: Any) -> int:
|
|
255
|
+
return await cls.where(**filters).delete()
|
|
256
|
+
|
|
257
|
+
async def save(self) -> Model:
|
|
258
|
+
if getattr(self, "id", None):
|
|
259
|
+
await self.update()
|
|
260
|
+
else:
|
|
261
|
+
await self.insert()
|
|
262
|
+
return self
|
|
263
|
+
|
|
264
|
+
async def delete(self) -> None:
|
|
265
|
+
table = _get_table_name(self)
|
|
266
|
+
for child_table, fk_col in _cascades.get(table, []):
|
|
267
|
+
for child in scan_records(child_table):
|
|
268
|
+
if child.get(fk_col) == self.id:
|
|
269
|
+
delete_record(child_table, int(child["id"]))
|
|
270
|
+
delete_record(table, self.id)
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
class StoreQuery:
|
|
274
|
+
"""Lazy query over one Voodoo Store collection."""
|
|
275
|
+
|
|
276
|
+
def __init__(self, model: type[Model], filters: dict[str, Any]) -> None:
|
|
277
|
+
self._model = model
|
|
278
|
+
self._filters = dict(filters)
|
|
279
|
+
self._order_by: list[str] = []
|
|
280
|
+
self._limit: int | None = None
|
|
281
|
+
self._offset: int | None = None
|
|
282
|
+
|
|
283
|
+
def _clone(self) -> StoreQuery:
|
|
284
|
+
query = StoreQuery(self._model, self._filters)
|
|
285
|
+
query._order_by = list(self._order_by)
|
|
286
|
+
query._limit = self._limit
|
|
287
|
+
query._offset = self._offset
|
|
288
|
+
return query
|
|
289
|
+
|
|
290
|
+
def where(self, **filters: Any) -> StoreQuery:
|
|
291
|
+
query = self._clone()
|
|
292
|
+
query._filters.update(filters)
|
|
293
|
+
return query
|
|
294
|
+
|
|
295
|
+
def order_by(self, *columns: str) -> StoreQuery:
|
|
296
|
+
query = self._clone()
|
|
297
|
+
query._order_by.extend(columns)
|
|
298
|
+
return query
|
|
299
|
+
|
|
300
|
+
def limit(self, n: int) -> StoreQuery:
|
|
301
|
+
query = self._clone()
|
|
302
|
+
query._limit = n
|
|
303
|
+
return query
|
|
304
|
+
|
|
305
|
+
def offset(self, n: int) -> StoreQuery:
|
|
306
|
+
query = self._clone()
|
|
307
|
+
query._offset = n
|
|
308
|
+
return query
|
|
309
|
+
|
|
310
|
+
def _rows(self) -> list[dict[str, Any]]:
|
|
311
|
+
rows = scan_records(_get_table_name(self._model))
|
|
312
|
+
for key, expected in self._filters.items():
|
|
313
|
+
rows = [row for row in rows if row.get(key) == expected]
|
|
314
|
+
for column in reversed(self._order_by):
|
|
315
|
+
descending = column.startswith("-")
|
|
316
|
+
name = column[1:] if descending else column
|
|
317
|
+
rows.sort(key=lambda row: row.get(name), reverse=descending)
|
|
318
|
+
if self._offset is not None:
|
|
319
|
+
rows = rows[self._offset :]
|
|
320
|
+
if self._limit is not None:
|
|
321
|
+
rows = rows[: self._limit]
|
|
322
|
+
return rows
|
|
323
|
+
|
|
324
|
+
async def first(self) -> Model | None:
|
|
325
|
+
rows = self.limit(1)._rows()
|
|
326
|
+
return None if not rows else _hydrate(self._model, rows[0])
|
|
327
|
+
|
|
328
|
+
async def count(self) -> int:
|
|
329
|
+
return len(self._rows())
|
|
330
|
+
|
|
331
|
+
async def delete(self) -> int:
|
|
332
|
+
if not self._filters:
|
|
333
|
+
raise ValueError(
|
|
334
|
+
"delete() requires at least one filter; use explicit where(...) before delete()."
|
|
335
|
+
)
|
|
336
|
+
rows = self._rows()
|
|
337
|
+
collection = _get_table_name(self._model)
|
|
338
|
+
for row in rows:
|
|
339
|
+
delete_record(collection, int(row["id"]))
|
|
340
|
+
return len(rows)
|
|
341
|
+
|
|
342
|
+
async def _execute(self) -> list[Model]:
|
|
343
|
+
return [_hydrate(self._model, row) for row in self._rows()]
|
|
344
|
+
|
|
345
|
+
def __await__(self):
|
|
346
|
+
return self._execute().__await__()
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"""Voodoo storage namespace.
|
|
2
|
+
|
|
3
|
+
The default package import is dependency-light. Store-native runtime paths do
|
|
4
|
+
not import SQLite, PostgreSQL, Redis, or S3 adapters. Compatibility adapters are
|
|
5
|
+
resolved lazily only when their public symbols are requested explicitly.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from importlib import import_module
|
|
11
|
+
from typing import Any
|
|
12
|
+
|
|
13
|
+
from voodoo.storage.manager import StorageManager, storage
|
|
14
|
+
|
|
15
|
+
__all__ = [
|
|
16
|
+
"StorageManager",
|
|
17
|
+
"storage",
|
|
18
|
+
"EventBusCapabilities",
|
|
19
|
+
"VoodooEventBus",
|
|
20
|
+
"VoodooStoreEventBus",
|
|
21
|
+
"LocalEventBus",
|
|
22
|
+
"SQLiteEventBus",
|
|
23
|
+
"PostgresEventStore",
|
|
24
|
+
"SQLiteExecutionStore",
|
|
25
|
+
"PostgresExecutionStore",
|
|
26
|
+
"VoodooStoreExecutionStore",
|
|
27
|
+
"VoodooQueue",
|
|
28
|
+
"VoodooStoreQueue",
|
|
29
|
+
"MemoryQueue",
|
|
30
|
+
"SQLiteQueue",
|
|
31
|
+
"PostgresQueue",
|
|
32
|
+
"RedisQueue",
|
|
33
|
+
"CacheCapabilities",
|
|
34
|
+
"VoodooCache",
|
|
35
|
+
"MemoryCache",
|
|
36
|
+
"RedisCache",
|
|
37
|
+
]
|
|
38
|
+
|
|
39
|
+
_LAZY_EXPORTS = {
|
|
40
|
+
"EventBusCapabilities": (
|
|
41
|
+
"voodoo.storage.events.interfaces",
|
|
42
|
+
"EventBusCapabilities",
|
|
43
|
+
),
|
|
44
|
+
"VoodooEventBus": ("voodoo.storage.events.interfaces", "VoodooEventBus"),
|
|
45
|
+
"VoodooStoreEventBus": ("voodoo.storage.events.store", "VoodooStoreEventBus"),
|
|
46
|
+
"LocalEventBus": ("voodoo.storage.events.local", "LocalEventBus"),
|
|
47
|
+
"SQLiteEventBus": ("voodoo.storage.events.sqlite", "SQLiteEventBus"),
|
|
48
|
+
"PostgresEventStore": ("voodoo.storage.events.postgres", "PostgresEventStore"),
|
|
49
|
+
"SQLiteExecutionStore": (
|
|
50
|
+
"voodoo.storage.execution.sqlite",
|
|
51
|
+
"SQLiteExecutionStore",
|
|
52
|
+
),
|
|
53
|
+
"PostgresExecutionStore": (
|
|
54
|
+
"voodoo.storage.execution.postgres",
|
|
55
|
+
"PostgresExecutionStore",
|
|
56
|
+
),
|
|
57
|
+
"VoodooStoreExecutionStore": (
|
|
58
|
+
"voodoo.storage.execution.store",
|
|
59
|
+
"VoodooStoreExecutionStore",
|
|
60
|
+
),
|
|
61
|
+
"VoodooQueue": ("voodoo.storage.queue.interfaces", "VoodooQueue"),
|
|
62
|
+
"VoodooStoreQueue": ("voodoo.storage.queue.store", "VoodooStoreQueue"),
|
|
63
|
+
"MemoryQueue": ("voodoo.storage.queue.memory", "MemoryQueue"),
|
|
64
|
+
"SQLiteQueue": ("voodoo.storage.queue.sqlite", "SQLiteQueue"),
|
|
65
|
+
"PostgresQueue": ("voodoo.storage.queue.postgres", "PostgresQueue"),
|
|
66
|
+
"RedisQueue": ("voodoo.storage.queue.redis", "RedisQueue"),
|
|
67
|
+
"CacheCapabilities": ("voodoo.storage.cache.interfaces", "CacheCapabilities"),
|
|
68
|
+
"VoodooCache": ("voodoo.storage.cache.interfaces", "VoodooCache"),
|
|
69
|
+
"MemoryCache": ("voodoo.storage.cache.memory", "MemoryCache"),
|
|
70
|
+
"RedisCache": ("voodoo.storage.cache.redis", "RedisCache"),
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def __getattr__(name: str) -> Any:
|
|
75
|
+
target = _LAZY_EXPORTS.get(name)
|
|
76
|
+
if target is None:
|
|
77
|
+
raise AttributeError(f"module 'voodoo.storage' has no attribute {name!r}")
|
|
78
|
+
module_name, symbol = target
|
|
79
|
+
value = getattr(import_module(module_name), symbol)
|
|
80
|
+
globals()[name] = value
|
|
81
|
+
return value
|