omnibase_infra 0.2.8__py3-none-any.whl → 0.3.0__py3-none-any.whl
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.
- omnibase_infra/__init__.py +1 -1
- omnibase_infra/enums/__init__.py +4 -0
- omnibase_infra/enums/enum_declarative_node_violation.py +102 -0
- omnibase_infra/errors/__init__.py +18 -0
- omnibase_infra/errors/repository/__init__.py +78 -0
- omnibase_infra/errors/repository/errors_repository.py +424 -0
- omnibase_infra/event_bus/adapters/__init__.py +31 -0
- omnibase_infra/event_bus/adapters/adapter_protocol_event_publisher_kafka.py +517 -0
- omnibase_infra/mixins/mixin_async_circuit_breaker.py +113 -1
- omnibase_infra/models/__init__.py +9 -0
- omnibase_infra/models/event_bus/__init__.py +22 -0
- omnibase_infra/models/event_bus/model_consumer_retry_config.py +367 -0
- omnibase_infra/models/event_bus/model_dlq_config.py +177 -0
- omnibase_infra/models/event_bus/model_idempotency_config.py +131 -0
- omnibase_infra/models/event_bus/model_offset_policy_config.py +107 -0
- omnibase_infra/models/resilience/model_circuit_breaker_config.py +15 -0
- omnibase_infra/models/validation/__init__.py +8 -0
- omnibase_infra/models/validation/model_declarative_node_validation_result.py +139 -0
- omnibase_infra/models/validation/model_declarative_node_violation.py +169 -0
- omnibase_infra/nodes/architecture_validator/__init__.py +28 -7
- omnibase_infra/nodes/architecture_validator/constants.py +36 -0
- omnibase_infra/nodes/architecture_validator/handlers/__init__.py +28 -0
- omnibase_infra/nodes/architecture_validator/handlers/contract.yaml +120 -0
- omnibase_infra/nodes/architecture_validator/handlers/handler_architecture_validation.py +359 -0
- omnibase_infra/nodes/architecture_validator/node.py +1 -0
- omnibase_infra/nodes/architecture_validator/node_architecture_validator.py +48 -336
- omnibase_infra/nodes/contract_registry_reducer/reducer.py +12 -2
- omnibase_infra/nodes/node_ledger_projection_compute/__init__.py +16 -2
- omnibase_infra/nodes/node_ledger_projection_compute/contract.yaml +14 -4
- omnibase_infra/nodes/node_ledger_projection_compute/handlers/__init__.py +18 -0
- omnibase_infra/nodes/node_ledger_projection_compute/handlers/contract.yaml +53 -0
- omnibase_infra/nodes/node_ledger_projection_compute/handlers/handler_ledger_projection.py +354 -0
- omnibase_infra/nodes/node_ledger_projection_compute/node.py +20 -256
- omnibase_infra/nodes/node_registry_effect/node.py +20 -73
- omnibase_infra/protocols/protocol_dispatch_engine.py +90 -0
- omnibase_infra/runtime/__init__.py +11 -0
- omnibase_infra/runtime/baseline_subscriptions.py +150 -0
- omnibase_infra/runtime/db/__init__.py +73 -0
- omnibase_infra/runtime/db/models/__init__.py +41 -0
- omnibase_infra/runtime/db/models/model_repository_runtime_config.py +211 -0
- omnibase_infra/runtime/db/postgres_repository_runtime.py +545 -0
- omnibase_infra/runtime/event_bus_subcontract_wiring.py +455 -24
- omnibase_infra/runtime/kafka_contract_source.py +13 -5
- omnibase_infra/runtime/service_message_dispatch_engine.py +112 -0
- omnibase_infra/runtime/service_runtime_host_process.py +6 -11
- omnibase_infra/services/__init__.py +36 -0
- omnibase_infra/services/contract_publisher/__init__.py +95 -0
- omnibase_infra/services/contract_publisher/config.py +199 -0
- omnibase_infra/services/contract_publisher/errors.py +243 -0
- omnibase_infra/services/contract_publisher/models/__init__.py +28 -0
- omnibase_infra/services/contract_publisher/models/model_contract_error.py +67 -0
- omnibase_infra/services/contract_publisher/models/model_infra_error.py +62 -0
- omnibase_infra/services/contract_publisher/models/model_publish_result.py +112 -0
- omnibase_infra/services/contract_publisher/models/model_publish_stats.py +79 -0
- omnibase_infra/services/contract_publisher/service.py +617 -0
- omnibase_infra/services/contract_publisher/sources/__init__.py +52 -0
- omnibase_infra/services/contract_publisher/sources/model_discovered.py +155 -0
- omnibase_infra/services/contract_publisher/sources/protocol.py +101 -0
- omnibase_infra/services/contract_publisher/sources/source_composite.py +309 -0
- omnibase_infra/services/contract_publisher/sources/source_filesystem.py +174 -0
- omnibase_infra/services/contract_publisher/sources/source_package.py +221 -0
- omnibase_infra/services/observability/__init__.py +40 -0
- omnibase_infra/services/observability/agent_actions/__init__.py +64 -0
- omnibase_infra/services/observability/agent_actions/config.py +209 -0
- omnibase_infra/services/observability/agent_actions/consumer.py +1320 -0
- omnibase_infra/services/observability/agent_actions/models/__init__.py +87 -0
- omnibase_infra/services/observability/agent_actions/models/model_agent_action.py +142 -0
- omnibase_infra/services/observability/agent_actions/models/model_detection_failure.py +125 -0
- omnibase_infra/services/observability/agent_actions/models/model_envelope.py +85 -0
- omnibase_infra/services/observability/agent_actions/models/model_execution_log.py +159 -0
- omnibase_infra/services/observability/agent_actions/models/model_performance_metric.py +130 -0
- omnibase_infra/services/observability/agent_actions/models/model_routing_decision.py +138 -0
- omnibase_infra/services/observability/agent_actions/models/model_transformation_event.py +124 -0
- omnibase_infra/services/observability/agent_actions/tests/__init__.py +20 -0
- omnibase_infra/services/observability/agent_actions/tests/test_consumer.py +1154 -0
- omnibase_infra/services/observability/agent_actions/tests/test_models.py +645 -0
- omnibase_infra/services/observability/agent_actions/tests/test_writer.py +709 -0
- omnibase_infra/services/observability/agent_actions/writer_postgres.py +926 -0
- omnibase_infra/validation/__init__.py +12 -0
- omnibase_infra/validation/contracts/declarative_node.validation.yaml +143 -0
- omnibase_infra/validation/infra_validators.py +4 -1
- omnibase_infra/validation/validation_exemptions.yaml +111 -0
- omnibase_infra/validation/validator_declarative_node.py +850 -0
- {omnibase_infra-0.2.8.dist-info → omnibase_infra-0.3.0.dist-info}/METADATA +2 -2
- {omnibase_infra-0.2.8.dist-info → omnibase_infra-0.3.0.dist-info}/RECORD +88 -30
- {omnibase_infra-0.2.8.dist-info → omnibase_infra-0.3.0.dist-info}/WHEEL +0 -0
- {omnibase_infra-0.2.8.dist-info → omnibase_infra-0.3.0.dist-info}/entry_points.txt +0 -0
- {omnibase_infra-0.2.8.dist-info → omnibase_infra-0.3.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -22,17 +22,21 @@ Design Decisions:
|
|
|
22
22
|
- 100% Contract-Driven: All routing logic in YAML, not Python
|
|
23
23
|
- Zero Custom Routing: Base class handles handler dispatch via contract
|
|
24
24
|
- Declarative Handlers: handler_routing section defines dispatch rules
|
|
25
|
-
-
|
|
25
|
+
- Container DI: Backend adapters resolved via container, not setter methods
|
|
26
26
|
|
|
27
27
|
Node Responsibilities:
|
|
28
28
|
- Define I/O model contract (ModelRegistryRequest -> ModelRegistryResponse)
|
|
29
|
-
- Provide dependency injection points for backend clients
|
|
30
29
|
- Delegate all execution to handlers via base class
|
|
30
|
+
- NO custom logic - pure declarative shell
|
|
31
31
|
|
|
32
32
|
The actual handler execution and routing is performed by:
|
|
33
33
|
- NodeOrchestrator (for workflow coordination)
|
|
34
34
|
- Or direct handler invocation by callers
|
|
35
35
|
|
|
36
|
+
Handlers receive their dependencies directly via constructor injection:
|
|
37
|
+
- HandlerConsulRegister(consul_client)
|
|
38
|
+
- HandlerPostgresUpsert(postgres_adapter)
|
|
39
|
+
|
|
36
40
|
Coroutine Safety:
|
|
37
41
|
This node is async-safe. Handler coordination is performed by the
|
|
38
42
|
orchestrator layer, not by this effect node.
|
|
@@ -43,32 +47,24 @@ Related Modules:
|
|
|
43
47
|
- models/: Node-specific input/output models
|
|
44
48
|
- NodeRegistrationOrchestrator: Coordinates handler execution
|
|
45
49
|
|
|
46
|
-
Migration Notes (OMN-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
+
Migration Notes (OMN-1726):
|
|
51
|
+
Refactored from setter-based dependency injection to pure declarative shell.
|
|
52
|
+
Backend adapters are now resolved via container, not via set_* methods.
|
|
53
|
+
Handlers receive dependencies directly via their constructors.
|
|
50
54
|
"""
|
|
51
55
|
|
|
52
56
|
from __future__ import annotations
|
|
53
57
|
|
|
54
|
-
from typing import TYPE_CHECKING
|
|
55
|
-
|
|
56
58
|
from omnibase_core.nodes.node_effect import NodeEffect
|
|
57
59
|
|
|
58
|
-
if TYPE_CHECKING:
|
|
59
|
-
from omnibase_core.models.container.model_onex_container import ModelONEXContainer
|
|
60
|
-
from omnibase_infra.nodes.effects.protocol_consul_client import ProtocolConsulClient
|
|
61
|
-
from omnibase_infra.nodes.effects.protocol_postgres_adapter import (
|
|
62
|
-
ProtocolPostgresAdapter,
|
|
63
|
-
)
|
|
64
|
-
|
|
65
60
|
|
|
61
|
+
# ONEX_EXCLUDE: declarative_node - legacy effect node with direct adapter access (OMN-1725)
|
|
66
62
|
class NodeRegistryEffect(NodeEffect):
|
|
67
63
|
"""Declarative effect node for dual-backend node registration.
|
|
68
64
|
|
|
69
65
|
This effect node is a lightweight shell that defines the I/O contract
|
|
70
66
|
for registration operations. All routing and execution logic is driven
|
|
71
|
-
by contract.yaml - this class contains
|
|
67
|
+
by contract.yaml - this class contains NO custom routing code.
|
|
72
68
|
|
|
73
69
|
Handler coordination is performed by:
|
|
74
70
|
- NodeRegistrationOrchestrator for workflow-based execution
|
|
@@ -80,8 +76,9 @@ class NodeRegistryEffect(NodeEffect):
|
|
|
80
76
|
- retry_partial_failure: Retry a specific backend after partial failure
|
|
81
77
|
|
|
82
78
|
Dependency Injection:
|
|
83
|
-
Backend
|
|
84
|
-
|
|
79
|
+
Backend adapters (Consul, PostgreSQL) are resolved via container.
|
|
80
|
+
Handlers receive their dependencies directly via constructor injection.
|
|
81
|
+
This node contains NO instance variables for backend clients.
|
|
85
82
|
|
|
86
83
|
Example:
|
|
87
84
|
```python
|
|
@@ -92,15 +89,14 @@ class NodeRegistryEffect(NodeEffect):
|
|
|
92
89
|
HandlerPostgresUpsert,
|
|
93
90
|
)
|
|
94
91
|
|
|
95
|
-
# Create effect node
|
|
92
|
+
# Create effect node via container
|
|
96
93
|
container = ModelONEXContainer()
|
|
97
94
|
effect = NodeRegistryEffect(container)
|
|
98
95
|
|
|
99
|
-
#
|
|
100
|
-
|
|
101
|
-
|
|
96
|
+
# Handlers receive dependencies directly via constructor
|
|
97
|
+
consul_client = container.resolve(ProtocolConsulClient)
|
|
98
|
+
postgres_adapter = container.resolve(ProtocolPostgresAdapter)
|
|
102
99
|
|
|
103
|
-
# Execute via handlers directly
|
|
104
100
|
consul_handler = HandlerConsulRegister(consul_client)
|
|
105
101
|
postgres_handler = HandlerPostgresUpsert(postgres_adapter)
|
|
106
102
|
|
|
@@ -110,56 +106,7 @@ class NodeRegistryEffect(NodeEffect):
|
|
|
110
106
|
```
|
|
111
107
|
"""
|
|
112
108
|
|
|
113
|
-
|
|
114
|
-
"""Initialize the effect node.
|
|
115
|
-
|
|
116
|
-
Args:
|
|
117
|
-
container: ONEX dependency injection container providing:
|
|
118
|
-
- Backend adapters (Consul client, PostgreSQL adapter)
|
|
119
|
-
- Handler instances
|
|
120
|
-
- Configuration
|
|
121
|
-
"""
|
|
122
|
-
super().__init__(container)
|
|
123
|
-
|
|
124
|
-
# Backend adapters (injected via setter methods)
|
|
125
|
-
self._consul_client: ProtocolConsulClient | None = None
|
|
126
|
-
self._postgres_adapter: ProtocolPostgresAdapter | None = None
|
|
127
|
-
|
|
128
|
-
def set_consul_client(self, client: ProtocolConsulClient) -> None:
|
|
129
|
-
"""Set the Consul client for service registration.
|
|
130
|
-
|
|
131
|
-
Args:
|
|
132
|
-
client: Protocol-compliant Consul client implementation.
|
|
133
|
-
"""
|
|
134
|
-
self._consul_client = client
|
|
135
|
-
|
|
136
|
-
def set_postgres_adapter(self, adapter: ProtocolPostgresAdapter) -> None:
|
|
137
|
-
"""Set the PostgreSQL adapter for registration persistence.
|
|
138
|
-
|
|
139
|
-
Args:
|
|
140
|
-
adapter: Protocol-compliant PostgreSQL adapter implementation.
|
|
141
|
-
"""
|
|
142
|
-
self._postgres_adapter = adapter
|
|
143
|
-
|
|
144
|
-
@property
|
|
145
|
-
def consul_client(self) -> ProtocolConsulClient | None:
|
|
146
|
-
"""Get the Consul client if configured."""
|
|
147
|
-
return self._consul_client
|
|
148
|
-
|
|
149
|
-
@property
|
|
150
|
-
def postgres_adapter(self) -> ProtocolPostgresAdapter | None:
|
|
151
|
-
"""Get the PostgreSQL adapter if configured."""
|
|
152
|
-
return self._postgres_adapter
|
|
153
|
-
|
|
154
|
-
@property
|
|
155
|
-
def has_consul_client(self) -> bool:
|
|
156
|
-
"""Check if Consul client is configured."""
|
|
157
|
-
return self._consul_client is not None
|
|
158
|
-
|
|
159
|
-
@property
|
|
160
|
-
def has_postgres_adapter(self) -> bool:
|
|
161
|
-
"""Check if PostgreSQL adapter is configured."""
|
|
162
|
-
return self._postgres_adapter is not None
|
|
109
|
+
# Pure declarative shell - all behavior defined in contract.yaml
|
|
163
110
|
|
|
164
111
|
|
|
165
112
|
__all__ = ["NodeRegistryEffect"]
|
|
@@ -150,3 +150,93 @@ class ProtocolDispatchEngine(Protocol):
|
|
|
150
150
|
await dispatch_engine.dispatch(topic, envelope)
|
|
151
151
|
"""
|
|
152
152
|
...
|
|
153
|
+
|
|
154
|
+
async def dispatch_with_transaction(
|
|
155
|
+
self,
|
|
156
|
+
*,
|
|
157
|
+
topic: str,
|
|
158
|
+
envelope: ModelEventEnvelope[object],
|
|
159
|
+
tx: object,
|
|
160
|
+
) -> ModelDispatchResult | None:
|
|
161
|
+
"""Dispatch an event envelope with database transaction context.
|
|
162
|
+
|
|
163
|
+
This method enables transaction-scoped dispatch for correct idempotency
|
|
164
|
+
semantics. The transaction parameter allows handlers to participate in
|
|
165
|
+
the same database transaction as the idempotency insert, ensuring
|
|
166
|
+
exactly-once processing.
|
|
167
|
+
|
|
168
|
+
Design Decision:
|
|
169
|
+
The ``tx`` parameter is typed as ``object`` rather than a specific
|
|
170
|
+
database type (e.g., ``asyncpg.Connection``) to avoid leaking
|
|
171
|
+
infrastructure types into the protocol. This keeps the protocol
|
|
172
|
+
generic and allows future flexibility for different database backends.
|
|
173
|
+
|
|
174
|
+
Implementers should type-narrow ``tx`` via duck-typing (checking for
|
|
175
|
+
required methods) rather than isinstance checks, per ONEX conventions:
|
|
176
|
+
|
|
177
|
+
.. code-block:: python
|
|
178
|
+
|
|
179
|
+
from omnibase_core.errors import OnexError
|
|
180
|
+
|
|
181
|
+
async def dispatch_with_transaction(
|
|
182
|
+
self,
|
|
183
|
+
*,
|
|
184
|
+
topic: str,
|
|
185
|
+
envelope: ModelEventEnvelope[object],
|
|
186
|
+
tx: object,
|
|
187
|
+
) -> ModelDispatchResult | None:
|
|
188
|
+
# Duck-type check for required database connection methods
|
|
189
|
+
if not (hasattr(tx, 'execute') and callable(tx.execute)):
|
|
190
|
+
raise OnexError(
|
|
191
|
+
"Transaction object must implement execute() method"
|
|
192
|
+
)
|
|
193
|
+
# Use tx with duck-typed interface...
|
|
194
|
+
|
|
195
|
+
Thread Safety:
|
|
196
|
+
This method MUST be safe for concurrent calls from multiple
|
|
197
|
+
coroutines. The transaction context (``tx``) is typically
|
|
198
|
+
connection-scoped and should not be shared across coroutines.
|
|
199
|
+
|
|
200
|
+
Args:
|
|
201
|
+
topic: The full topic name from which the envelope was consumed.
|
|
202
|
+
Used for routing and logging context.
|
|
203
|
+
Example: "dev.onex.evt.node.introspected.v1"
|
|
204
|
+
envelope: The deserialized event envelope containing the payload.
|
|
205
|
+
The payload type varies by topic/event type.
|
|
206
|
+
tx: Database transaction/connection context. Typed as ``object``
|
|
207
|
+
to avoid infrastructure type leakage; implementations should
|
|
208
|
+
type-narrow based on their database backend (e.g.,
|
|
209
|
+
``asyncpg.Connection``, ``aiosqlite.Connection``).
|
|
210
|
+
|
|
211
|
+
Returns:
|
|
212
|
+
ModelDispatchResult if the implementation returns dispatch metrics/results,
|
|
213
|
+
None if the implementation does not track results. Callers should not
|
|
214
|
+
depend on the return value for correctness.
|
|
215
|
+
|
|
216
|
+
Raises:
|
|
217
|
+
InfraDispatchError: If no handler is registered for the topic/message type.
|
|
218
|
+
OnexError: For handler execution failures or if ``tx`` does not implement
|
|
219
|
+
the required database connection interface (duck-type validation).
|
|
220
|
+
|
|
221
|
+
Example:
|
|
222
|
+
.. code-block:: python
|
|
223
|
+
|
|
224
|
+
# Idempotency consumer with transaction context
|
|
225
|
+
async with pool.acquire() as conn:
|
|
226
|
+
async with conn.transaction():
|
|
227
|
+
# Insert idempotency record and dispatch in same transaction
|
|
228
|
+
await insert_idempotency_record(conn, message_id)
|
|
229
|
+
await dispatch_engine.dispatch_with_transaction(
|
|
230
|
+
topic=topic,
|
|
231
|
+
envelope=envelope,
|
|
232
|
+
tx=conn,
|
|
233
|
+
)
|
|
234
|
+
# Both committed atomically
|
|
235
|
+
|
|
236
|
+
Related:
|
|
237
|
+
- OMN-1740: Transaction-scoped dispatch for idempotency
|
|
238
|
+
- dispatch(): Non-transactional dispatch method
|
|
239
|
+
|
|
240
|
+
.. versionadded:: 0.2.9
|
|
241
|
+
"""
|
|
242
|
+
...
|
|
@@ -272,6 +272,13 @@ from omnibase_infra.runtime.registry_contract_source import (
|
|
|
272
272
|
# Kafka contract source (OMN-1654)
|
|
273
273
|
from omnibase_infra.runtime.kafka_contract_source import KafkaContractSource
|
|
274
274
|
|
|
275
|
+
# Baseline subscriptions (OMN-1696)
|
|
276
|
+
from omnibase_infra.runtime.baseline_subscriptions import (
|
|
277
|
+
BASELINE_CONTRACT_TOPICS,
|
|
278
|
+
BASELINE_PLATFORM_TOPICS,
|
|
279
|
+
get_baseline_topics,
|
|
280
|
+
)
|
|
281
|
+
|
|
275
282
|
# Chain-aware dispatch (OMN-951) - must be imported LAST to avoid circular import
|
|
276
283
|
from omnibase_infra.runtime.chain_aware_dispatch import (
|
|
277
284
|
ChainAwareDispatcher,
|
|
@@ -442,4 +449,8 @@ __all__: list[str] = [
|
|
|
442
449
|
"store_contract_in_consul",
|
|
443
450
|
# Kafka contract source (OMN-1654)
|
|
444
451
|
"KafkaContractSource",
|
|
452
|
+
# Baseline subscriptions (OMN-1696)
|
|
453
|
+
"BASELINE_CONTRACT_TOPICS",
|
|
454
|
+
"BASELINE_PLATFORM_TOPICS",
|
|
455
|
+
"get_baseline_topics",
|
|
445
456
|
]
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
|
2
|
+
# Copyright (c) 2025 OmniNode Team
|
|
3
|
+
"""Baseline Subscriptions Assembly Module.
|
|
4
|
+
|
|
5
|
+
Aggregates platform baseline topic constants from omnibase_core for use
|
|
6
|
+
by the ONEX runtime when wiring Kafka subscriptions.
|
|
7
|
+
|
|
8
|
+
Part of OMN-1696: Wire baseline topic constants from omnibase_core into
|
|
9
|
+
omnibase_infra runtime subscription assembly.
|
|
10
|
+
|
|
11
|
+
Platform Baseline Topics:
|
|
12
|
+
These topics are automatically subscribed to by the runtime during
|
|
13
|
+
initialization, providing core platform functionality:
|
|
14
|
+
|
|
15
|
+
- **Contract Registered**: Notifies when a new handler contract is registered.
|
|
16
|
+
Used by KafkaContractSource for dynamic contract discovery.
|
|
17
|
+
|
|
18
|
+
- **Contract Deregistered**: Notifies when a handler contract is removed.
|
|
19
|
+
Used by KafkaContractSource for cache invalidation.
|
|
20
|
+
|
|
21
|
+
- **Node Heartbeat**: Periodic health signals from running nodes.
|
|
22
|
+
Used for liveness monitoring and service discovery.
|
|
23
|
+
|
|
24
|
+
Usage:
|
|
25
|
+
>>> from omnibase_infra.runtime.baseline_subscriptions import (
|
|
26
|
+
... BASELINE_CONTRACT_TOPICS,
|
|
27
|
+
... BASELINE_PLATFORM_TOPICS,
|
|
28
|
+
... get_baseline_topics,
|
|
29
|
+
... )
|
|
30
|
+
>>>
|
|
31
|
+
>>> # Get contract-only topics (registration/deregistration)
|
|
32
|
+
>>> contract_topics = get_baseline_topics(include_heartbeat=False)
|
|
33
|
+
>>>
|
|
34
|
+
>>> # Get all platform baseline topics (including heartbeat)
|
|
35
|
+
>>> all_topics = get_baseline_topics(include_heartbeat=True)
|
|
36
|
+
|
|
37
|
+
Related:
|
|
38
|
+
- KafkaContractSource: Consumes contract registration events
|
|
39
|
+
- RuntimeHostProcess: Wires baseline subscriptions on startup
|
|
40
|
+
- omnibase_core.constants: Source of truth for topic suffix constants
|
|
41
|
+
|
|
42
|
+
Related Tickets:
|
|
43
|
+
- OMN-1696: Wire baseline topic constants from omnibase_core
|
|
44
|
+
- OMN-1652: Define platform baseline topic suffixes in omnibase_core
|
|
45
|
+
- OMN-1654: KafkaContractSource (cache + discovery)
|
|
46
|
+
|
|
47
|
+
.. versionadded:: 0.2.9
|
|
48
|
+
Created as part of OMN-1696 baseline subscription wiring.
|
|
49
|
+
"""
|
|
50
|
+
|
|
51
|
+
from __future__ import annotations
|
|
52
|
+
|
|
53
|
+
from omnibase_core.constants import (
|
|
54
|
+
PLATFORM_BASELINE_TOPIC_SUFFIXES,
|
|
55
|
+
TOPIC_SUFFIX_CONTRACT_DEREGISTERED,
|
|
56
|
+
TOPIC_SUFFIX_CONTRACT_REGISTERED,
|
|
57
|
+
TOPIC_SUFFIX_NODE_HEARTBEAT,
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
# Contract registration/deregistration topics only.
|
|
61
|
+
# Use when you need to track contract lifecycle events but not node health.
|
|
62
|
+
BASELINE_CONTRACT_TOPICS: frozenset[str] = frozenset(
|
|
63
|
+
{
|
|
64
|
+
TOPIC_SUFFIX_CONTRACT_REGISTERED,
|
|
65
|
+
TOPIC_SUFFIX_CONTRACT_DEREGISTERED,
|
|
66
|
+
}
|
|
67
|
+
)
|
|
68
|
+
"""Contract lifecycle topics (registration and deregistration).
|
|
69
|
+
|
|
70
|
+
This subset excludes heartbeat topics and is appropriate when:
|
|
71
|
+
- You only need to track contract changes
|
|
72
|
+
- Heartbeat processing is handled separately
|
|
73
|
+
- You want to minimize subscription overhead
|
|
74
|
+
|
|
75
|
+
Example:
|
|
76
|
+
>>> for topic_suffix in BASELINE_CONTRACT_TOPICS:
|
|
77
|
+
... full_topic = f"{environment}.{topic_suffix}"
|
|
78
|
+
... subscribe(full_topic)
|
|
79
|
+
"""
|
|
80
|
+
|
|
81
|
+
# All platform baseline topics including heartbeat.
|
|
82
|
+
# Use when you need complete platform observability.
|
|
83
|
+
BASELINE_PLATFORM_TOPICS: frozenset[str] = frozenset(PLATFORM_BASELINE_TOPIC_SUFFIXES)
|
|
84
|
+
"""All platform baseline topics including heartbeat.
|
|
85
|
+
|
|
86
|
+
This is the full set of platform-reserved topics that the runtime
|
|
87
|
+
subscribes to automatically during initialization.
|
|
88
|
+
|
|
89
|
+
Includes:
|
|
90
|
+
- Contract registered events
|
|
91
|
+
- Contract deregistered events
|
|
92
|
+
- Node heartbeat events
|
|
93
|
+
|
|
94
|
+
Example:
|
|
95
|
+
>>> for topic_suffix in BASELINE_PLATFORM_TOPICS:
|
|
96
|
+
... full_topic = f"{environment}.{topic_suffix}"
|
|
97
|
+
... subscribe(full_topic)
|
|
98
|
+
"""
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def get_baseline_topics(*, include_heartbeat: bool = True) -> frozenset[str]:
|
|
102
|
+
"""Return the appropriate set of baseline topic suffixes.
|
|
103
|
+
|
|
104
|
+
This helper function provides a convenient way to select between
|
|
105
|
+
the full platform topic set or contract-only topics based on
|
|
106
|
+
runtime requirements.
|
|
107
|
+
|
|
108
|
+
Args:
|
|
109
|
+
include_heartbeat: If True (default), returns all platform baseline
|
|
110
|
+
topics including node heartbeat. If False, returns only contract
|
|
111
|
+
registration/deregistration topics.
|
|
112
|
+
|
|
113
|
+
Returns:
|
|
114
|
+
A frozenset of topic suffix strings. These are suffixes that should
|
|
115
|
+
be prefixed with the environment name to form complete topic names.
|
|
116
|
+
|
|
117
|
+
Example:
|
|
118
|
+
>>> # For full platform observability
|
|
119
|
+
>>> topics = get_baseline_topics(include_heartbeat=True)
|
|
120
|
+
>>> assert TOPIC_SUFFIX_NODE_HEARTBEAT in topics
|
|
121
|
+
>>>
|
|
122
|
+
>>> # For contract-only tracking
|
|
123
|
+
>>> topics = get_baseline_topics(include_heartbeat=False)
|
|
124
|
+
>>> assert TOPIC_SUFFIX_NODE_HEARTBEAT not in topics
|
|
125
|
+
>>> assert TOPIC_SUFFIX_CONTRACT_REGISTERED in topics
|
|
126
|
+
|
|
127
|
+
Note:
|
|
128
|
+
The returned frozenset is immutable and can be safely shared
|
|
129
|
+
across threads without synchronization.
|
|
130
|
+
|
|
131
|
+
.. versionadded:: 0.2.9
|
|
132
|
+
Created as part of OMN-1696.
|
|
133
|
+
"""
|
|
134
|
+
if include_heartbeat:
|
|
135
|
+
return BASELINE_PLATFORM_TOPICS
|
|
136
|
+
return BASELINE_CONTRACT_TOPICS
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
__all__: list[str] = [
|
|
140
|
+
# Topic sets
|
|
141
|
+
"BASELINE_CONTRACT_TOPICS",
|
|
142
|
+
"BASELINE_PLATFORM_TOPICS",
|
|
143
|
+
# Helper function
|
|
144
|
+
"get_baseline_topics",
|
|
145
|
+
# Re-exported constants from omnibase_core for convenience
|
|
146
|
+
"PLATFORM_BASELINE_TOPIC_SUFFIXES",
|
|
147
|
+
"TOPIC_SUFFIX_CONTRACT_DEREGISTERED",
|
|
148
|
+
"TOPIC_SUFFIX_CONTRACT_REGISTERED",
|
|
149
|
+
"TOPIC_SUFFIX_NODE_HEARTBEAT",
|
|
150
|
+
]
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
|
2
|
+
# Copyright (c) 2025 OmniNode Team
|
|
3
|
+
"""Database runtime module for omnibase_infra.
|
|
4
|
+
|
|
5
|
+
This module provides the PostgresRepositoryRuntime and associated models for
|
|
6
|
+
database operations with safety constraints and deterministic query behavior.
|
|
7
|
+
|
|
8
|
+
Components:
|
|
9
|
+
- PostgresRepositoryRuntime: Generic Postgres runtime for contract execution
|
|
10
|
+
- ModelRepositoryRuntimeConfig: Configuration for runtime behavior
|
|
11
|
+
- ModelDbRepositoryContract: Repository contract specification
|
|
12
|
+
- ModelDbOperation: Database operation specification
|
|
13
|
+
- ModelDbReturn: Return type specification
|
|
14
|
+
|
|
15
|
+
The db module enables safe, configurable database operations with:
|
|
16
|
+
- Contract-driven operations (all ops defined in ModelDbRepositoryContract)
|
|
17
|
+
- Operation allowlisting (select, insert, update, upsert)
|
|
18
|
+
- Row limits for multi-row selects
|
|
19
|
+
- Query timeouts with asyncio.wait_for()
|
|
20
|
+
- Deterministic ORDER BY injection
|
|
21
|
+
- Metrics emission
|
|
22
|
+
|
|
23
|
+
Example:
|
|
24
|
+
>>> import asyncpg
|
|
25
|
+
>>> from omnibase_infra.runtime.db import (
|
|
26
|
+
... PostgresRepositoryRuntime,
|
|
27
|
+
... ModelDbRepositoryContract,
|
|
28
|
+
... ModelDbOperation,
|
|
29
|
+
... ModelDbReturn,
|
|
30
|
+
... ModelRepositoryRuntimeConfig,
|
|
31
|
+
... )
|
|
32
|
+
>>>
|
|
33
|
+
>>> # Define contract
|
|
34
|
+
>>> contract = ModelDbRepositoryContract(
|
|
35
|
+
... name="users",
|
|
36
|
+
... database_ref="primary",
|
|
37
|
+
... ops={
|
|
38
|
+
... "find_by_id": ModelDbOperation(
|
|
39
|
+
... mode="select",
|
|
40
|
+
... sql="SELECT * FROM users WHERE id = $1",
|
|
41
|
+
... params=["user_id"],
|
|
42
|
+
... returns=ModelDbReturn(many=False),
|
|
43
|
+
... ),
|
|
44
|
+
... },
|
|
45
|
+
... )
|
|
46
|
+
>>>
|
|
47
|
+
>>> # Create runtime with pool
|
|
48
|
+
>>> pool = await asyncpg.create_pool(...)
|
|
49
|
+
>>> runtime = PostgresRepositoryRuntime(pool, contract)
|
|
50
|
+
>>>
|
|
51
|
+
>>> # Execute operation
|
|
52
|
+
>>> user = await runtime.call("find_by_id", 123)
|
|
53
|
+
"""
|
|
54
|
+
|
|
55
|
+
from __future__ import annotations
|
|
56
|
+
|
|
57
|
+
from omnibase_infra.runtime.db.models import (
|
|
58
|
+
ModelDbOperation,
|
|
59
|
+
ModelDbRepositoryContract,
|
|
60
|
+
ModelDbReturn,
|
|
61
|
+
ModelRepositoryRuntimeConfig,
|
|
62
|
+
)
|
|
63
|
+
from omnibase_infra.runtime.db.postgres_repository_runtime import (
|
|
64
|
+
PostgresRepositoryRuntime,
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
__all__: list[str] = [
|
|
68
|
+
"ModelDbOperation",
|
|
69
|
+
"ModelDbRepositoryContract",
|
|
70
|
+
"ModelDbReturn",
|
|
71
|
+
"ModelRepositoryRuntimeConfig",
|
|
72
|
+
"PostgresRepositoryRuntime",
|
|
73
|
+
]
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
|
2
|
+
# Copyright (c) 2025 OmniNode Team
|
|
3
|
+
"""Database Runtime Models Module.
|
|
4
|
+
|
|
5
|
+
This module exports Pydantic models for database runtime configuration.
|
|
6
|
+
Contract models (ModelDbRepositoryContract, ModelDbOperation, ModelDbReturn)
|
|
7
|
+
are imported from omnibase_core.models.contracts.
|
|
8
|
+
|
|
9
|
+
Exports:
|
|
10
|
+
ModelRepositoryRuntimeConfig: Configuration for PostgresRepositoryRuntime
|
|
11
|
+
- Safety constraints (max_row_limit, timeout_ms)
|
|
12
|
+
- Operation allowlisting (select, insert, update, upsert)
|
|
13
|
+
- Feature flags (allow_raw_operations, allow_delete_operations)
|
|
14
|
+
- Determinism controls (primary_key_column, default_order_by)
|
|
15
|
+
- Metrics emission configuration
|
|
16
|
+
|
|
17
|
+
ModelDbRepositoryContract: (re-export from omnibase_core)
|
|
18
|
+
ModelDbOperation: (re-export from omnibase_core)
|
|
19
|
+
ModelDbReturn: (re-export from omnibase_core)
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
from __future__ import annotations
|
|
23
|
+
|
|
24
|
+
# Contract models from omnibase_core (canonical source)
|
|
25
|
+
from omnibase_core.models.contracts import (
|
|
26
|
+
ModelDbOperation,
|
|
27
|
+
ModelDbRepositoryContract,
|
|
28
|
+
ModelDbReturn,
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
# Runtime config is local to omnibase_infra
|
|
32
|
+
from omnibase_infra.runtime.db.models.model_repository_runtime_config import (
|
|
33
|
+
ModelRepositoryRuntimeConfig,
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
__all__: list[str] = [
|
|
37
|
+
"ModelDbOperation",
|
|
38
|
+
"ModelDbRepositoryContract",
|
|
39
|
+
"ModelDbReturn",
|
|
40
|
+
"ModelRepositoryRuntimeConfig",
|
|
41
|
+
]
|