dirigent-core 0.9.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. dirigent_core-0.9.0/LICENSE +18 -0
  2. dirigent_core-0.9.0/PKG-INFO +29 -0
  3. dirigent_core-0.9.0/README.md +3 -0
  4. dirigent_core-0.9.0/pyproject.toml +38 -0
  5. dirigent_core-0.9.0/pyproject.toml.orig +37 -0
  6. dirigent_core-0.9.0/src/dirigent_core/__init__.py +26 -0
  7. dirigent_core-0.9.0/src/dirigent_core/alembic/env.py +71 -0
  8. dirigent_core-0.9.0/src/dirigent_core/alembic/script.py.mako +26 -0
  9. dirigent_core-0.9.0/src/dirigent_core/alembic/versions/0001_baseline_schema.py +1016 -0
  10. dirigent_core-0.9.0/src/dirigent_core/alerting.py +805 -0
  11. dirigent_core-0.9.0/src/dirigent_core/artifacts.py +73 -0
  12. dirigent_core-0.9.0/src/dirigent_core/auth.py +529 -0
  13. dirigent_core-0.9.0/src/dirigent_core/blockdocs.py +223 -0
  14. dirigent_core-0.9.0/src/dirigent_core/config.py +421 -0
  15. dirigent_core-0.9.0/src/dirigent_core/configdocs.py +134 -0
  16. dirigent_core-0.9.0/src/dirigent_core/database.py +177 -0
  17. dirigent_core-0.9.0/src/dirigent_core/directory.py +339 -0
  18. dirigent_core-0.9.0/src/dirigent_core/documents.py +878 -0
  19. dirigent_core-0.9.0/src/dirigent_core/documentschema.py +92 -0
  20. dirigent_core-0.9.0/src/dirigent_core/engine/__init__.py +120 -0
  21. dirigent_core-0.9.0/src/dirigent_core/engine/claim.py +156 -0
  22. dirigent_core-0.9.0/src/dirigent_core/engine/context.py +420 -0
  23. dirigent_core-0.9.0/src/dirigent_core/engine/definition.py +543 -0
  24. dirigent_core-0.9.0/src/dirigent_core/engine/executor.py +1029 -0
  25. dirigent_core-0.9.0/src/dirigent_core/engine/failure.py +71 -0
  26. dirigent_core-0.9.0/src/dirigent_core/engine/recovery.py +137 -0
  27. dirigent_core-0.9.0/src/dirigent_core/engine/references.py +239 -0
  28. dirigent_core-0.9.0/src/dirigent_core/engine/runs.py +865 -0
  29. dirigent_core-0.9.0/src/dirigent_core/engine/services.py +74 -0
  30. dirigent_core-0.9.0/src/dirigent_core/engine/state.py +434 -0
  31. dirigent_core-0.9.0/src/dirigent_core/ids.py +39 -0
  32. dirigent_core-0.9.0/src/dirigent_core/logging.py +310 -0
  33. dirigent_core-0.9.0/src/dirigent_core/migrations.py +98 -0
  34. dirigent_core-0.9.0/src/dirigent_core/models.py +626 -0
  35. dirigent_core-0.9.0/src/dirigent_core/pipelines.py +494 -0
  36. dirigent_core-0.9.0/src/dirigent_core/plugins.py +255 -0
  37. dirigent_core-0.9.0/src/dirigent_core/protocol.py +276 -0
  38. dirigent_core-0.9.0/src/dirigent_core/py.typed +0 -0
  39. dirigent_core-0.9.0/src/dirigent_core/ratelimit.py +42 -0
  40. dirigent_core-0.9.0/src/dirigent_core/registry.py +32 -0
  41. dirigent_core-0.9.0/src/dirigent_core/retention.py +293 -0
  42. dirigent_core-0.9.0/src/dirigent_core/scheduler.py +491 -0
  43. dirigent_core-0.9.0/src/dirigent_core/schemas.py +147 -0
  44. dirigent_core-0.9.0/src/dirigent_core/secrets.py +164 -0
  45. dirigent_core-0.9.0/src/dirigent_core/storage.py +349 -0
  46. dirigent_core-0.9.0/src/dirigent_core/telemetry.py +402 -0
  47. dirigent_core-0.9.0/src/dirigent_core/trigger_documents.py +193 -0
  48. dirigent_core-0.9.0/src/dirigent_core/triggers/__init__.py +117 -0
  49. dirigent_core-0.9.0/src/dirigent_core/triggers/backfill.py +131 -0
  50. dirigent_core-0.9.0/src/dirigent_core/triggers/materialize.py +218 -0
  51. dirigent_core-0.9.0/src/dirigent_core/triggers/schedules.py +531 -0
  52. dirigent_core-0.9.0/src/dirigent_core/triggers/webhooks.py +586 -0
  53. dirigent_core-0.9.0/src/dirigent_core/types.py +59 -0
  54. dirigent_core-0.9.0/src/dirigent_core/worker.py +350 -0
@@ -0,0 +1,18 @@
1
+ Copyright (c) 2026 Morten Olav Hansen <morten@winterop.com>. All rights reserved.
2
+
3
+ This source code and accompanying documentation are the property of
4
+ Morten Olav Hansen. No license, express or implied, is granted to use, copy,
5
+ modify, merge, publish, distribute, sublicense, or sell copies of this
6
+ software or its derivatives.
7
+
8
+ The source is published for reference only. Any use beyond reading
9
+ requires written permission from the copyright holder.
10
+
11
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
12
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
13
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT.
14
+ IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES,
15
+ OR OTHER LIABILITY ARISING FROM THE USE OF THE SOFTWARE.
16
+
17
+ Third-party components redistributed with this software, and the licences they
18
+ carry, are listed in THIRD_PARTY_NOTICES.md.
@@ -0,0 +1,29 @@
1
+ Metadata-Version: 2.4
2
+ Name: dirigent-core
3
+ Version: 0.9.0
4
+ Summary: Dirigent engine core: schema, configuration, and plugin host.
5
+ License-Expression: LicenseRef-Proprietary
6
+ License-File: LICENSE
7
+ Requires-Dist: aiosqlite>=0.22.1
8
+ Requires-Dist: alembic>=1.19.1
9
+ Requires-Dist: argon2-cffi>=25.1.0
10
+ Requires-Dist: asyncpg>=0.31.0
11
+ Requires-Dist: cronsim>=2.7
12
+ Requires-Dist: cryptography>=46.0.5
13
+ Requires-Dist: dirigent-client
14
+ Requires-Dist: dirigent-common
15
+ Requires-Dist: dirigent-plugin
16
+ Requires-Dist: jsonschema>=4.26.0
17
+ Requires-Dist: opentelemetry-api>=1.44.0
18
+ Requires-Dist: pydantic-settings>=2.15.0
19
+ Requires-Dist: pyyaml>=6.0.3
20
+ Requires-Dist: sqlalchemy[asyncio]>=2.0.52
21
+ Requires-Dist: structlog>=25.5.0
22
+ Requires-Dist: opentelemetry-exporter-otlp-proto-http>=1.44.0 ; extra == 'otlp'
23
+ Requires-Python: >=3.13
24
+ Provides-Extra: otlp
25
+ Description-Content-Type: text/markdown
26
+
27
+ # dirigent-core
28
+
29
+ Dirigent engine core: schema, configuration, and plugin host.
@@ -0,0 +1,3 @@
1
+ # dirigent-core
2
+
3
+ Dirigent engine core: schema, configuration, and plugin host.
@@ -0,0 +1,38 @@
1
+ [project]
2
+ name = "dirigent-core"
3
+ version = "0.9.0"
4
+ description = "Dirigent engine core: schema, configuration, and plugin host."
5
+ readme = "README.md"
6
+ requires-python = ">=3.13"
7
+ license = "LicenseRef-Proprietary"
8
+ license-files = ["LICENSE"]
9
+ dependencies = [
10
+ "aiosqlite>=0.22.1",
11
+ "alembic>=1.19.1",
12
+ "argon2-cffi>=25.1.0",
13
+ "asyncpg>=0.31.0",
14
+ "cronsim>=2.7",
15
+ "cryptography>=46.0.5",
16
+ "dirigent-client",
17
+ "dirigent-common",
18
+ "dirigent-plugin",
19
+ "jsonschema>=4.26.0",
20
+ "opentelemetry-api>=1.44.0",
21
+ "pydantic-settings>=2.15.0",
22
+ "pyyaml>=6.0.3",
23
+ "sqlalchemy[asyncio]>=2.0.52",
24
+ "structlog>=25.5.0",
25
+ ]
26
+
27
+ [project.optional-dependencies]
28
+ otlp = ["opentelemetry-exporter-otlp-proto-http>=1.44.0"]
29
+
30
+ [build-system]
31
+ requires = ["uv_build>=0.12.0,<0.13.0"]
32
+ build-backend = "uv_build"
33
+
34
+ [tool.uv.sources.dirigent-client]
35
+ workspace = true
36
+
37
+ [tool.uv.sources.dirigent-plugin]
38
+ workspace = true
@@ -0,0 +1,37 @@
1
+ [project]
2
+ name = "dirigent-core"
3
+ version = "0.9.0"
4
+ description = "Dirigent engine core: schema, configuration, and plugin host."
5
+ readme = "README.md"
6
+ requires-python = ">=3.13"
7
+ license = "LicenseRef-Proprietary"
8
+ license-files = ["LICENSE"]
9
+ dependencies = [
10
+ "aiosqlite>=0.22.1",
11
+ "alembic>=1.19.1",
12
+ "argon2-cffi>=25.1.0",
13
+ "asyncpg>=0.31.0",
14
+ "cronsim>=2.7",
15
+ "cryptography>=46.0.5",
16
+ "dirigent-client",
17
+ "dirigent-common",
18
+ "dirigent-plugin",
19
+ "jsonschema>=4.26.0",
20
+ "opentelemetry-api>=1.44.0",
21
+ "pydantic-settings>=2.15.0",
22
+ "pyyaml>=6.0.3",
23
+ "sqlalchemy[asyncio]>=2.0.52",
24
+ "structlog>=25.5.0",
25
+ ]
26
+
27
+ [project.optional-dependencies]
28
+ # Telemetry is exporterless by default; installing this extra is what turns it on.
29
+ otlp = ["opentelemetry-exporter-otlp-proto-http>=1.44.0"]
30
+
31
+ [build-system]
32
+ requires = ["uv_build>=0.12.0,<0.13.0"]
33
+ build-backend = "uv_build"
34
+
35
+ [tool.uv.sources]
36
+ dirigent-client = { workspace = true }
37
+ dirigent-plugin = { workspace = true }
@@ -0,0 +1,26 @@
1
+ """Dirigent core: configuration, the baseline schema, and the migrations that create it."""
2
+
3
+ from importlib.metadata import PackageNotFoundError, version
4
+
5
+ from dirigent_core.config import Settings, get_settings, reset_settings_cache
6
+ from dirigent_core.database import create_engine, create_session_factory, ping, session_scope
7
+ from dirigent_core.ids import uuid7
8
+ from dirigent_core.models import Base
9
+
10
+ try:
11
+ __version__ = version("dirigent-core")
12
+ except PackageNotFoundError: # pragma: no cover - only when running from a source tree
13
+ __version__ = "0.0.0"
14
+
15
+ __all__ = [
16
+ "Base",
17
+ "Settings",
18
+ "__version__",
19
+ "create_engine",
20
+ "create_session_factory",
21
+ "get_settings",
22
+ "ping",
23
+ "reset_settings_cache",
24
+ "session_scope",
25
+ "uuid7",
26
+ ]
@@ -0,0 +1,71 @@
1
+ """Alembic environment: one migration history that runs on both PostgreSQL and SQLite."""
2
+
3
+ import asyncio
4
+ from typing import Any
5
+
6
+ from alembic import context
7
+ from sqlalchemy import Connection
8
+ from sqlalchemy.ext.asyncio import async_engine_from_config
9
+ from sqlalchemy.pool import NullPool
10
+
11
+ from dirigent_core.config import get_settings
12
+ from dirigent_core.models import Base
13
+
14
+ config = context.config
15
+ target_metadata = Base.metadata
16
+
17
+
18
+ def database_url() -> str:
19
+ """Resolve the URL to migrate: the Alembic config wins, then the instance settings."""
20
+ return config.get_main_option("sqlalchemy.url") or get_settings().database_url
21
+
22
+
23
+ def run_migrations_offline() -> None:
24
+ """Emit SQL for the configured URL without connecting to a database."""
25
+ context.configure(
26
+ url=database_url(),
27
+ target_metadata=target_metadata,
28
+ literal_binds=True,
29
+ dialect_opts={"paramstyle": "named"},
30
+ render_as_batch=True,
31
+ compare_type=True,
32
+ )
33
+ with context.begin_transaction():
34
+ context.run_migrations()
35
+
36
+
37
+ def do_run_migrations(connection: Connection) -> None:
38
+ """Run the migrations on an established synchronous connection."""
39
+ context.configure(
40
+ connection=connection,
41
+ target_metadata=target_metadata,
42
+ render_as_batch=connection.dialect.name == "sqlite",
43
+ compare_type=True,
44
+ )
45
+ with context.begin_transaction():
46
+ context.run_migrations()
47
+
48
+
49
+ async def run_async_migrations() -> None:
50
+ """Open the async engine and drive the migrations through it."""
51
+ section: dict[str, Any] = dict(config.get_section(config.config_ini_section) or {})
52
+ section["sqlalchemy.url"] = database_url()
53
+ engine = async_engine_from_config(section, prefix="sqlalchemy.", poolclass=NullPool)
54
+ async with engine.connect() as connection:
55
+ await connection.run_sync(do_run_migrations)
56
+ await engine.dispose()
57
+
58
+
59
+ def run_migrations_online() -> None:
60
+ """Run the migrations against a live database."""
61
+ connectable = config.attributes.get("connection", None)
62
+ if isinstance(connectable, Connection):
63
+ do_run_migrations(connectable)
64
+ return
65
+ asyncio.run(run_async_migrations())
66
+
67
+
68
+ if context.is_offline_mode():
69
+ run_migrations_offline()
70
+ else:
71
+ run_migrations_online()
@@ -0,0 +1,26 @@
1
+ """${message}.
2
+
3
+ Revision ID: ${up_revision}
4
+ Revises: ${down_revision | comma,n}
5
+ Create Date: ${create_date}
6
+ """
7
+
8
+ from collections.abc import Sequence
9
+
10
+ import sqlalchemy as sa
11
+ from alembic import op
12
+ ${imports if imports else ""}
13
+ revision: str = ${repr(up_revision)}
14
+ down_revision: str | None = ${repr(down_revision)}
15
+ branch_labels: str | Sequence[str] | None = ${repr(branch_labels)}
16
+ depends_on: str | Sequence[str] | None = ${repr(depends_on)}
17
+
18
+
19
+ def upgrade() -> None:
20
+ """Apply the migration."""
21
+ ${upgrades if upgrades else "pass"}
22
+
23
+
24
+ def downgrade() -> None:
25
+ """Revert the migration."""
26
+ ${downgrades if downgrades else "pass"}