omnibase_infra 0.2.6__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 +101 -0
- omnibase_infra/adapters/adapter_onex_tool_execution.py +451 -0
- omnibase_infra/capabilities/__init__.py +15 -0
- omnibase_infra/capabilities/capability_inference_rules.py +211 -0
- omnibase_infra/capabilities/contract_capability_extractor.py +221 -0
- omnibase_infra/capabilities/intent_type_extractor.py +160 -0
- omnibase_infra/cli/__init__.py +1 -0
- omnibase_infra/cli/commands.py +216 -0
- omnibase_infra/clients/__init__.py +0 -0
- omnibase_infra/configs/widget_mapping.yaml +176 -0
- omnibase_infra/constants_topic_patterns.py +26 -0
- omnibase_infra/contracts/handlers/filesystem/handler_contract.yaml +264 -0
- omnibase_infra/contracts/handlers/mcp/handler_contract.yaml +141 -0
- omnibase_infra/decorators/__init__.py +29 -0
- omnibase_infra/decorators/allow_any.py +109 -0
- omnibase_infra/dlq/__init__.py +90 -0
- omnibase_infra/dlq/constants_dlq.py +57 -0
- omnibase_infra/dlq/models/__init__.py +26 -0
- omnibase_infra/dlq/models/enum_replay_status.py +37 -0
- omnibase_infra/dlq/models/model_dlq_replay_record.py +135 -0
- omnibase_infra/dlq/models/model_dlq_tracking_config.py +184 -0
- omnibase_infra/dlq/service_dlq_tracking.py +611 -0
- omnibase_infra/enums/__init__.py +132 -0
- omnibase_infra/enums/enum_any_type_violation.py +104 -0
- omnibase_infra/enums/enum_backend_type.py +27 -0
- omnibase_infra/enums/enum_capture_outcome.py +42 -0
- omnibase_infra/enums/enum_capture_state.py +88 -0
- omnibase_infra/enums/enum_chain_violation_type.py +119 -0
- omnibase_infra/enums/enum_circuit_state.py +51 -0
- omnibase_infra/enums/enum_confirmation_event_type.py +27 -0
- omnibase_infra/enums/enum_consumer_group_purpose.py +92 -0
- omnibase_infra/enums/enum_contract_type.py +84 -0
- omnibase_infra/enums/enum_dedupe_strategy.py +46 -0
- omnibase_infra/enums/enum_dispatch_status.py +191 -0
- omnibase_infra/enums/enum_environment.py +46 -0
- omnibase_infra/enums/enum_execution_shape_violation.py +103 -0
- omnibase_infra/enums/enum_handler_error_type.py +111 -0
- omnibase_infra/enums/enum_handler_loader_error.py +178 -0
- omnibase_infra/enums/enum_handler_source_mode.py +86 -0
- omnibase_infra/enums/enum_handler_source_type.py +87 -0
- omnibase_infra/enums/enum_handler_type.py +77 -0
- omnibase_infra/enums/enum_handler_type_category.py +61 -0
- omnibase_infra/enums/enum_infra_transport_type.py +73 -0
- omnibase_infra/enums/enum_introspection_reason.py +154 -0
- omnibase_infra/enums/enum_kafka_acks.py +99 -0
- omnibase_infra/enums/enum_message_category.py +213 -0
- omnibase_infra/enums/enum_node_archetype.py +74 -0
- omnibase_infra/enums/enum_node_output_type.py +185 -0
- omnibase_infra/enums/enum_non_retryable_error_category.py +224 -0
- omnibase_infra/enums/enum_policy_type.py +32 -0
- omnibase_infra/enums/enum_registration_state.py +261 -0
- omnibase_infra/enums/enum_registration_status.py +33 -0
- omnibase_infra/enums/enum_registry_response_status.py +28 -0
- omnibase_infra/enums/enum_response_status.py +26 -0
- omnibase_infra/enums/enum_retry_error_category.py +98 -0
- omnibase_infra/enums/enum_security_rule_id.py +103 -0
- omnibase_infra/enums/enum_selection_strategy.py +91 -0
- omnibase_infra/enums/enum_topic_standard.py +42 -0
- omnibase_infra/enums/enum_validation_severity.py +78 -0
- omnibase_infra/errors/__init__.py +160 -0
- omnibase_infra/errors/error_architecture_violation.py +152 -0
- omnibase_infra/errors/error_binding_resolution.py +128 -0
- omnibase_infra/errors/error_chain_propagation.py +188 -0
- omnibase_infra/errors/error_compute_registry.py +95 -0
- omnibase_infra/errors/error_consul.py +132 -0
- omnibase_infra/errors/error_container_wiring.py +243 -0
- omnibase_infra/errors/error_event_bus_registry.py +105 -0
- omnibase_infra/errors/error_infra.py +610 -0
- omnibase_infra/errors/error_message_type_registry.py +101 -0
- omnibase_infra/errors/error_policy_registry.py +115 -0
- omnibase_infra/errors/error_vault.py +123 -0
- omnibase_infra/event_bus/__init__.py +72 -0
- omnibase_infra/event_bus/configs/kafka_event_bus_config.yaml +84 -0
- omnibase_infra/event_bus/event_bus_inmemory.py +797 -0
- omnibase_infra/event_bus/event_bus_kafka.py +1716 -0
- omnibase_infra/event_bus/mixin_kafka_broadcast.py +180 -0
- omnibase_infra/event_bus/mixin_kafka_dlq.py +771 -0
- omnibase_infra/event_bus/models/__init__.py +29 -0
- omnibase_infra/event_bus/models/config/__init__.py +20 -0
- omnibase_infra/event_bus/models/config/model_kafka_event_bus_config.py +693 -0
- omnibase_infra/event_bus/models/model_dlq_event.py +206 -0
- omnibase_infra/event_bus/models/model_dlq_metrics.py +304 -0
- omnibase_infra/event_bus/models/model_event_headers.py +115 -0
- omnibase_infra/event_bus/models/model_event_message.py +60 -0
- omnibase_infra/event_bus/testing/__init__.py +26 -0
- omnibase_infra/event_bus/testing/adapter_protocol_event_publisher_inmemory.py +418 -0
- omnibase_infra/event_bus/testing/model_publisher_metrics.py +64 -0
- omnibase_infra/event_bus/topic_constants.py +376 -0
- omnibase_infra/handlers/__init__.py +82 -0
- omnibase_infra/handlers/filesystem/__init__.py +48 -0
- omnibase_infra/handlers/filesystem/enum_file_system_operation.py +35 -0
- omnibase_infra/handlers/filesystem/model_file_system_request.py +298 -0
- omnibase_infra/handlers/filesystem/model_file_system_result.py +166 -0
- omnibase_infra/handlers/handler_consul.py +795 -0
- omnibase_infra/handlers/handler_db.py +1046 -0
- omnibase_infra/handlers/handler_filesystem.py +1478 -0
- omnibase_infra/handlers/handler_graph.py +2015 -0
- omnibase_infra/handlers/handler_http.py +926 -0
- omnibase_infra/handlers/handler_intent.py +387 -0
- omnibase_infra/handlers/handler_manifest_persistence.contract.yaml +184 -0
- omnibase_infra/handlers/handler_manifest_persistence.py +1539 -0
- omnibase_infra/handlers/handler_mcp.py +1430 -0
- omnibase_infra/handlers/handler_qdrant.py +1076 -0
- omnibase_infra/handlers/handler_vault.py +428 -0
- omnibase_infra/handlers/mcp/__init__.py +19 -0
- omnibase_infra/handlers/mcp/adapter_onex_to_mcp.py +446 -0
- omnibase_infra/handlers/mcp/protocols.py +178 -0
- omnibase_infra/handlers/mcp/transport_streamable_http.py +352 -0
- omnibase_infra/handlers/mixins/__init__.py +47 -0
- omnibase_infra/handlers/mixins/mixin_consul_initialization.py +349 -0
- omnibase_infra/handlers/mixins/mixin_consul_kv.py +338 -0
- omnibase_infra/handlers/mixins/mixin_consul_service.py +542 -0
- omnibase_infra/handlers/mixins/mixin_consul_topic_index.py +585 -0
- omnibase_infra/handlers/mixins/mixin_vault_initialization.py +338 -0
- omnibase_infra/handlers/mixins/mixin_vault_retry.py +412 -0
- omnibase_infra/handlers/mixins/mixin_vault_secrets.py +450 -0
- omnibase_infra/handlers/mixins/mixin_vault_token.py +365 -0
- omnibase_infra/handlers/models/__init__.py +286 -0
- omnibase_infra/handlers/models/consul/__init__.py +81 -0
- omnibase_infra/handlers/models/consul/enum_consul_operation_type.py +57 -0
- omnibase_infra/handlers/models/consul/model_consul_deregister_payload.py +51 -0
- omnibase_infra/handlers/models/consul/model_consul_handler_config.py +153 -0
- omnibase_infra/handlers/models/consul/model_consul_handler_payload.py +89 -0
- omnibase_infra/handlers/models/consul/model_consul_kv_get_found_payload.py +55 -0
- omnibase_infra/handlers/models/consul/model_consul_kv_get_not_found_payload.py +49 -0
- omnibase_infra/handlers/models/consul/model_consul_kv_get_recurse_payload.py +50 -0
- omnibase_infra/handlers/models/consul/model_consul_kv_item.py +33 -0
- omnibase_infra/handlers/models/consul/model_consul_kv_put_payload.py +41 -0
- omnibase_infra/handlers/models/consul/model_consul_register_payload.py +53 -0
- omnibase_infra/handlers/models/consul/model_consul_retry_config.py +66 -0
- omnibase_infra/handlers/models/consul/model_payload_consul.py +66 -0
- omnibase_infra/handlers/models/consul/registry_payload_consul.py +214 -0
- omnibase_infra/handlers/models/graph/__init__.py +35 -0
- omnibase_infra/handlers/models/graph/enum_graph_operation_type.py +20 -0
- omnibase_infra/handlers/models/graph/model_graph_execute_payload.py +38 -0
- omnibase_infra/handlers/models/graph/model_graph_handler_config.py +54 -0
- omnibase_infra/handlers/models/graph/model_graph_handler_payload.py +44 -0
- omnibase_infra/handlers/models/graph/model_graph_query_payload.py +40 -0
- omnibase_infra/handlers/models/graph/model_graph_record.py +22 -0
- omnibase_infra/handlers/models/http/__init__.py +50 -0
- omnibase_infra/handlers/models/http/enum_http_operation_type.py +29 -0
- omnibase_infra/handlers/models/http/model_http_body_content.py +45 -0
- omnibase_infra/handlers/models/http/model_http_get_payload.py +88 -0
- omnibase_infra/handlers/models/http/model_http_handler_payload.py +90 -0
- omnibase_infra/handlers/models/http/model_http_post_payload.py +88 -0
- omnibase_infra/handlers/models/http/model_payload_http.py +66 -0
- omnibase_infra/handlers/models/http/registry_payload_http.py +212 -0
- omnibase_infra/handlers/models/mcp/__init__.py +23 -0
- omnibase_infra/handlers/models/mcp/enum_mcp_operation_type.py +24 -0
- omnibase_infra/handlers/models/mcp/model_mcp_handler_config.py +40 -0
- omnibase_infra/handlers/models/mcp/model_mcp_tool_call.py +32 -0
- omnibase_infra/handlers/models/mcp/model_mcp_tool_result.py +45 -0
- omnibase_infra/handlers/models/model_consul_handler_response.py +96 -0
- omnibase_infra/handlers/models/model_db_describe_response.py +83 -0
- omnibase_infra/handlers/models/model_db_query_payload.py +95 -0
- omnibase_infra/handlers/models/model_db_query_response.py +60 -0
- omnibase_infra/handlers/models/model_filesystem_config.py +98 -0
- omnibase_infra/handlers/models/model_filesystem_delete_payload.py +54 -0
- omnibase_infra/handlers/models/model_filesystem_delete_result.py +77 -0
- omnibase_infra/handlers/models/model_filesystem_directory_entry.py +75 -0
- omnibase_infra/handlers/models/model_filesystem_ensure_directory_payload.py +54 -0
- omnibase_infra/handlers/models/model_filesystem_ensure_directory_result.py +60 -0
- omnibase_infra/handlers/models/model_filesystem_list_directory_payload.py +60 -0
- omnibase_infra/handlers/models/model_filesystem_list_directory_result.py +68 -0
- omnibase_infra/handlers/models/model_filesystem_read_payload.py +62 -0
- omnibase_infra/handlers/models/model_filesystem_read_result.py +61 -0
- omnibase_infra/handlers/models/model_filesystem_write_payload.py +70 -0
- omnibase_infra/handlers/models/model_filesystem_write_result.py +55 -0
- omnibase_infra/handlers/models/model_graph_handler_response.py +98 -0
- omnibase_infra/handlers/models/model_handler_response.py +103 -0
- omnibase_infra/handlers/models/model_http_handler_response.py +101 -0
- omnibase_infra/handlers/models/model_manifest_metadata.py +75 -0
- omnibase_infra/handlers/models/model_manifest_persistence_config.py +62 -0
- omnibase_infra/handlers/models/model_manifest_query_payload.py +90 -0
- omnibase_infra/handlers/models/model_manifest_query_result.py +97 -0
- omnibase_infra/handlers/models/model_manifest_retrieve_payload.py +44 -0
- omnibase_infra/handlers/models/model_manifest_retrieve_result.py +98 -0
- omnibase_infra/handlers/models/model_manifest_store_payload.py +47 -0
- omnibase_infra/handlers/models/model_manifest_store_result.py +67 -0
- omnibase_infra/handlers/models/model_operation_context.py +187 -0
- omnibase_infra/handlers/models/model_qdrant_handler_response.py +98 -0
- omnibase_infra/handlers/models/model_retry_state.py +162 -0
- omnibase_infra/handlers/models/model_vault_handler_response.py +98 -0
- omnibase_infra/handlers/models/qdrant/__init__.py +44 -0
- omnibase_infra/handlers/models/qdrant/enum_qdrant_operation_type.py +26 -0
- omnibase_infra/handlers/models/qdrant/model_qdrant_collection_payload.py +42 -0
- omnibase_infra/handlers/models/qdrant/model_qdrant_delete_payload.py +36 -0
- omnibase_infra/handlers/models/qdrant/model_qdrant_handler_config.py +42 -0
- omnibase_infra/handlers/models/qdrant/model_qdrant_handler_payload.py +54 -0
- omnibase_infra/handlers/models/qdrant/model_qdrant_search_payload.py +42 -0
- omnibase_infra/handlers/models/qdrant/model_qdrant_search_result.py +30 -0
- omnibase_infra/handlers/models/qdrant/model_qdrant_upsert_payload.py +36 -0
- omnibase_infra/handlers/models/vault/__init__.py +69 -0
- omnibase_infra/handlers/models/vault/enum_vault_operation_type.py +35 -0
- omnibase_infra/handlers/models/vault/model_payload_vault.py +66 -0
- omnibase_infra/handlers/models/vault/model_vault_delete_payload.py +57 -0
- omnibase_infra/handlers/models/vault/model_vault_handler_config.py +148 -0
- omnibase_infra/handlers/models/vault/model_vault_handler_payload.py +101 -0
- omnibase_infra/handlers/models/vault/model_vault_list_payload.py +58 -0
- omnibase_infra/handlers/models/vault/model_vault_renew_token_payload.py +67 -0
- omnibase_infra/handlers/models/vault/model_vault_retry_config.py +66 -0
- omnibase_infra/handlers/models/vault/model_vault_secret_payload.py +106 -0
- omnibase_infra/handlers/models/vault/model_vault_write_payload.py +66 -0
- omnibase_infra/handlers/models/vault/registry_payload_vault.py +213 -0
- omnibase_infra/handlers/registration_storage/__init__.py +43 -0
- omnibase_infra/handlers/registration_storage/handler_registration_storage_mock.py +392 -0
- omnibase_infra/handlers/registration_storage/handler_registration_storage_postgres.py +922 -0
- omnibase_infra/handlers/registration_storage/models/__init__.py +23 -0
- omnibase_infra/handlers/registration_storage/models/model_delete_registration_request.py +58 -0
- omnibase_infra/handlers/registration_storage/models/model_update_registration_request.py +73 -0
- omnibase_infra/handlers/registration_storage/protocol_registration_persistence.py +191 -0
- omnibase_infra/handlers/service_discovery/__init__.py +43 -0
- omnibase_infra/handlers/service_discovery/handler_service_discovery_consul.py +1051 -0
- omnibase_infra/handlers/service_discovery/handler_service_discovery_mock.py +258 -0
- omnibase_infra/handlers/service_discovery/models/__init__.py +22 -0
- omnibase_infra/handlers/service_discovery/models/model_discovery_result.py +64 -0
- omnibase_infra/handlers/service_discovery/models/model_registration_result.py +138 -0
- omnibase_infra/handlers/service_discovery/models/model_service_info.py +109 -0
- omnibase_infra/handlers/service_discovery/protocol_discovery_operations.py +170 -0
- omnibase_infra/idempotency/__init__.py +94 -0
- omnibase_infra/idempotency/models/__init__.py +43 -0
- omnibase_infra/idempotency/models/model_idempotency_check_result.py +85 -0
- omnibase_infra/idempotency/models/model_idempotency_guard_config.py +130 -0
- omnibase_infra/idempotency/models/model_idempotency_record.py +86 -0
- omnibase_infra/idempotency/models/model_idempotency_store_health_check_result.py +81 -0
- omnibase_infra/idempotency/models/model_idempotency_store_metrics.py +140 -0
- omnibase_infra/idempotency/models/model_postgres_idempotency_store_config.py +299 -0
- omnibase_infra/idempotency/protocol_idempotency_store.py +184 -0
- omnibase_infra/idempotency/store_inmemory.py +265 -0
- omnibase_infra/idempotency/store_postgres.py +923 -0
- omnibase_infra/infrastructure/__init__.py +0 -0
- omnibase_infra/migrations/001_create_event_ledger.sql +166 -0
- omnibase_infra/migrations/001_drop_event_ledger.sql +18 -0
- omnibase_infra/mixins/__init__.py +71 -0
- omnibase_infra/mixins/mixin_async_circuit_breaker.py +656 -0
- omnibase_infra/mixins/mixin_dict_like_accessors.py +146 -0
- omnibase_infra/mixins/mixin_envelope_extraction.py +119 -0
- omnibase_infra/mixins/mixin_node_introspection.py +2670 -0
- omnibase_infra/mixins/mixin_retry_execution.py +386 -0
- omnibase_infra/mixins/protocol_circuit_breaker_aware.py +133 -0
- omnibase_infra/models/__init__.py +144 -0
- omnibase_infra/models/bindings/__init__.py +59 -0
- omnibase_infra/models/bindings/constants.py +144 -0
- omnibase_infra/models/bindings/model_binding_resolution_result.py +103 -0
- omnibase_infra/models/bindings/model_operation_binding.py +44 -0
- omnibase_infra/models/bindings/model_operation_bindings_subcontract.py +152 -0
- omnibase_infra/models/bindings/model_parsed_binding.py +52 -0
- omnibase_infra/models/corpus/__init__.py +17 -0
- omnibase_infra/models/corpus/model_capture_config.py +133 -0
- omnibase_infra/models/corpus/model_capture_result.py +86 -0
- omnibase_infra/models/discovery/__init__.py +42 -0
- omnibase_infra/models/discovery/model_dependency_spec.py +319 -0
- omnibase_infra/models/discovery/model_discovered_capabilities.py +50 -0
- omnibase_infra/models/discovery/model_introspection_config.py +330 -0
- omnibase_infra/models/discovery/model_introspection_performance_metrics.py +169 -0
- omnibase_infra/models/discovery/model_introspection_task_config.py +116 -0
- omnibase_infra/models/dispatch/__init__.py +155 -0
- omnibase_infra/models/dispatch/model_debug_trace_snapshot.py +114 -0
- omnibase_infra/models/dispatch/model_dispatch_context.py +439 -0
- omnibase_infra/models/dispatch/model_dispatch_error.py +336 -0
- omnibase_infra/models/dispatch/model_dispatch_log_context.py +400 -0
- omnibase_infra/models/dispatch/model_dispatch_metadata.py +228 -0
- omnibase_infra/models/dispatch/model_dispatch_metrics.py +496 -0
- omnibase_infra/models/dispatch/model_dispatch_outcome.py +317 -0
- omnibase_infra/models/dispatch/model_dispatch_outputs.py +231 -0
- omnibase_infra/models/dispatch/model_dispatch_result.py +436 -0
- omnibase_infra/models/dispatch/model_dispatch_route.py +279 -0
- omnibase_infra/models/dispatch/model_dispatcher_metrics.py +275 -0
- omnibase_infra/models/dispatch/model_dispatcher_registration.py +352 -0
- omnibase_infra/models/dispatch/model_materialized_dispatch.py +141 -0
- omnibase_infra/models/dispatch/model_parsed_topic.py +135 -0
- omnibase_infra/models/dispatch/model_topic_parser.py +725 -0
- omnibase_infra/models/dispatch/model_tracing_context.py +285 -0
- omnibase_infra/models/errors/__init__.py +45 -0
- omnibase_infra/models/errors/model_handler_validation_error.py +594 -0
- omnibase_infra/models/errors/model_infra_error_context.py +99 -0
- omnibase_infra/models/errors/model_message_type_registry_error_context.py +71 -0
- omnibase_infra/models/errors/model_timeout_error_context.py +110 -0
- omnibase_infra/models/handlers/__init__.py +80 -0
- omnibase_infra/models/handlers/model_bootstrap_handler_descriptor.py +162 -0
- omnibase_infra/models/handlers/model_contract_discovery_result.py +82 -0
- omnibase_infra/models/handlers/model_handler_descriptor.py +200 -0
- omnibase_infra/models/handlers/model_handler_identifier.py +215 -0
- omnibase_infra/models/handlers/model_handler_source_config.py +220 -0
- omnibase_infra/models/health/__init__.py +9 -0
- omnibase_infra/models/health/model_health_check_result.py +40 -0
- omnibase_infra/models/lifecycle/__init__.py +39 -0
- omnibase_infra/models/logging/__init__.py +51 -0
- omnibase_infra/models/logging/model_log_context.py +756 -0
- omnibase_infra/models/mcp/__init__.py +15 -0
- omnibase_infra/models/mcp/model_mcp_contract_config.py +80 -0
- omnibase_infra/models/mcp/model_mcp_server_config.py +67 -0
- omnibase_infra/models/mcp/model_mcp_tool_definition.py +73 -0
- omnibase_infra/models/mcp/model_mcp_tool_parameter.py +35 -0
- omnibase_infra/models/model_node_identity.py +126 -0
- omnibase_infra/models/model_retry_error_classification.py +78 -0
- omnibase_infra/models/projection/__init__.py +43 -0
- omnibase_infra/models/projection/model_capability_fields.py +112 -0
- omnibase_infra/models/projection/model_registration_projection.py +434 -0
- omnibase_infra/models/projection/model_registration_snapshot.py +322 -0
- omnibase_infra/models/projection/model_sequence_info.py +182 -0
- omnibase_infra/models/projection/model_snapshot_topic_config.py +591 -0
- omnibase_infra/models/projectors/__init__.py +41 -0
- omnibase_infra/models/projectors/model_projector_column.py +289 -0
- omnibase_infra/models/projectors/model_projector_discovery_result.py +65 -0
- omnibase_infra/models/projectors/model_projector_index.py +270 -0
- omnibase_infra/models/projectors/model_projector_schema.py +415 -0
- omnibase_infra/models/projectors/model_projector_validation_error.py +63 -0
- omnibase_infra/models/projectors/util_sql_identifiers.py +115 -0
- omnibase_infra/models/registration/__init__.py +68 -0
- omnibase_infra/models/registration/commands/__init__.py +15 -0
- omnibase_infra/models/registration/commands/model_node_registration_acked.py +108 -0
- omnibase_infra/models/registration/events/__init__.py +56 -0
- omnibase_infra/models/registration/events/model_node_became_active.py +103 -0
- omnibase_infra/models/registration/events/model_node_liveness_expired.py +103 -0
- omnibase_infra/models/registration/events/model_node_registration_accepted.py +98 -0
- omnibase_infra/models/registration/events/model_node_registration_ack_received.py +98 -0
- omnibase_infra/models/registration/events/model_node_registration_ack_timed_out.py +112 -0
- omnibase_infra/models/registration/events/model_node_registration_initiated.py +107 -0
- omnibase_infra/models/registration/events/model_node_registration_rejected.py +104 -0
- omnibase_infra/models/registration/model_event_bus_topic_entry.py +59 -0
- omnibase_infra/models/registration/model_introspection_metrics.py +253 -0
- omnibase_infra/models/registration/model_node_capabilities.py +190 -0
- omnibase_infra/models/registration/model_node_event_bus_config.py +99 -0
- omnibase_infra/models/registration/model_node_heartbeat_event.py +126 -0
- omnibase_infra/models/registration/model_node_introspection_event.py +195 -0
- omnibase_infra/models/registration/model_node_metadata.py +79 -0
- omnibase_infra/models/registration/model_node_registration.py +162 -0
- omnibase_infra/models/registration/model_node_registration_record.py +162 -0
- omnibase_infra/models/registry/__init__.py +29 -0
- omnibase_infra/models/registry/model_domain_constraint.py +202 -0
- omnibase_infra/models/registry/model_message_type_entry.py +271 -0
- omnibase_infra/models/resilience/__init__.py +9 -0
- omnibase_infra/models/resilience/model_circuit_breaker_config.py +227 -0
- omnibase_infra/models/routing/__init__.py +25 -0
- omnibase_infra/models/routing/model_routing_entry.py +52 -0
- omnibase_infra/models/routing/model_routing_subcontract.py +70 -0
- omnibase_infra/models/runtime/__init__.py +49 -0
- omnibase_infra/models/runtime/model_contract_security_config.py +41 -0
- omnibase_infra/models/runtime/model_discovery_error.py +81 -0
- omnibase_infra/models/runtime/model_discovery_result.py +162 -0
- omnibase_infra/models/runtime/model_discovery_warning.py +74 -0
- omnibase_infra/models/runtime/model_failed_plugin_load.py +63 -0
- omnibase_infra/models/runtime/model_handler_contract.py +296 -0
- omnibase_infra/models/runtime/model_loaded_handler.py +129 -0
- omnibase_infra/models/runtime/model_plugin_load_context.py +93 -0
- omnibase_infra/models/runtime/model_plugin_load_summary.py +124 -0
- omnibase_infra/models/security/__init__.py +50 -0
- omnibase_infra/models/security/classification_levels.py +99 -0
- omnibase_infra/models/security/model_environment_policy.py +145 -0
- omnibase_infra/models/security/model_handler_security_policy.py +107 -0
- omnibase_infra/models/security/model_security_error.py +81 -0
- omnibase_infra/models/security/model_security_validation_result.py +328 -0
- omnibase_infra/models/security/model_security_warning.py +67 -0
- omnibase_infra/models/snapshot/__init__.py +27 -0
- omnibase_infra/models/snapshot/model_field_change.py +65 -0
- omnibase_infra/models/snapshot/model_snapshot.py +270 -0
- omnibase_infra/models/snapshot/model_snapshot_diff.py +203 -0
- omnibase_infra/models/snapshot/model_subject_ref.py +81 -0
- omnibase_infra/models/types/__init__.py +71 -0
- omnibase_infra/models/validation/__init__.py +89 -0
- omnibase_infra/models/validation/model_any_type_validation_result.py +118 -0
- omnibase_infra/models/validation/model_any_type_violation.py +141 -0
- omnibase_infra/models/validation/model_category_match_result.py +345 -0
- omnibase_infra/models/validation/model_chain_violation.py +166 -0
- omnibase_infra/models/validation/model_coverage_metrics.py +316 -0
- omnibase_infra/models/validation/model_execution_shape_rule.py +159 -0
- omnibase_infra/models/validation/model_execution_shape_validation.py +208 -0
- omnibase_infra/models/validation/model_execution_shape_validation_result.py +294 -0
- omnibase_infra/models/validation/model_execution_shape_violation.py +122 -0
- omnibase_infra/models/validation/model_localhandler_validation_result.py +139 -0
- omnibase_infra/models/validation/model_localhandler_violation.py +100 -0
- omnibase_infra/models/validation/model_output_validation_params.py +74 -0
- omnibase_infra/models/validation/model_validate_and_raise_params.py +84 -0
- omnibase_infra/models/validation/model_validation_error_params.py +84 -0
- omnibase_infra/models/validation/model_validation_outcome.py +287 -0
- omnibase_infra/nodes/__init__.py +57 -0
- omnibase_infra/nodes/architecture_validator/__init__.py +79 -0
- omnibase_infra/nodes/architecture_validator/contract.yaml +252 -0
- omnibase_infra/nodes/architecture_validator/contract_architecture_validator.yaml +203 -0
- omnibase_infra/nodes/architecture_validator/mixins/__init__.py +16 -0
- omnibase_infra/nodes/architecture_validator/mixins/mixin_file_path_rule.py +92 -0
- omnibase_infra/nodes/architecture_validator/models/__init__.py +36 -0
- omnibase_infra/nodes/architecture_validator/models/model_architecture_validation_request.py +56 -0
- omnibase_infra/nodes/architecture_validator/models/model_architecture_validation_result.py +311 -0
- omnibase_infra/nodes/architecture_validator/models/model_architecture_violation.py +163 -0
- omnibase_infra/nodes/architecture_validator/models/model_rule_check_result.py +265 -0
- omnibase_infra/nodes/architecture_validator/models/model_validation_request.py +105 -0
- omnibase_infra/nodes/architecture_validator/models/model_validation_result.py +314 -0
- omnibase_infra/nodes/architecture_validator/node.py +262 -0
- omnibase_infra/nodes/architecture_validator/node_architecture_validator.py +383 -0
- omnibase_infra/nodes/architecture_validator/protocols/__init__.py +9 -0
- omnibase_infra/nodes/architecture_validator/protocols/protocol_architecture_rule.py +225 -0
- omnibase_infra/nodes/architecture_validator/registry/__init__.py +28 -0
- omnibase_infra/nodes/architecture_validator/registry/registry_infra_architecture_validator.py +106 -0
- omnibase_infra/nodes/architecture_validator/validators/__init__.py +104 -0
- omnibase_infra/nodes/architecture_validator/validators/validator_no_direct_dispatch.py +422 -0
- omnibase_infra/nodes/architecture_validator/validators/validator_no_handler_publishing.py +481 -0
- omnibase_infra/nodes/architecture_validator/validators/validator_no_orchestrator_fsm.py +491 -0
- omnibase_infra/nodes/contract_registry_reducer/__init__.py +29 -0
- omnibase_infra/nodes/contract_registry_reducer/contract.yaml +255 -0
- omnibase_infra/nodes/contract_registry_reducer/models/__init__.py +38 -0
- omnibase_infra/nodes/contract_registry_reducer/models/model_contract_registry_state.py +266 -0
- omnibase_infra/nodes/contract_registry_reducer/models/model_payload_cleanup_topic_references.py +55 -0
- omnibase_infra/nodes/contract_registry_reducer/models/model_payload_deactivate_contract.py +58 -0
- omnibase_infra/nodes/contract_registry_reducer/models/model_payload_mark_stale.py +49 -0
- omnibase_infra/nodes/contract_registry_reducer/models/model_payload_update_heartbeat.py +71 -0
- omnibase_infra/nodes/contract_registry_reducer/models/model_payload_update_topic.py +66 -0
- omnibase_infra/nodes/contract_registry_reducer/models/model_payload_upsert_contract.py +92 -0
- omnibase_infra/nodes/contract_registry_reducer/node.py +121 -0
- omnibase_infra/nodes/contract_registry_reducer/reducer.py +784 -0
- omnibase_infra/nodes/contract_registry_reducer/registry/__init__.py +9 -0
- omnibase_infra/nodes/contract_registry_reducer/registry/registry_infra_contract_registry_reducer.py +101 -0
- omnibase_infra/nodes/effects/README.md +358 -0
- omnibase_infra/nodes/effects/__init__.py +26 -0
- omnibase_infra/nodes/effects/contract.yaml +167 -0
- omnibase_infra/nodes/effects/models/__init__.py +32 -0
- omnibase_infra/nodes/effects/models/model_backend_result.py +190 -0
- omnibase_infra/nodes/effects/models/model_effect_idempotency_config.py +92 -0
- omnibase_infra/nodes/effects/models/model_registry_request.py +132 -0
- omnibase_infra/nodes/effects/models/model_registry_response.py +263 -0
- omnibase_infra/nodes/effects/protocol_consul_client.py +89 -0
- omnibase_infra/nodes/effects/protocol_effect_idempotency_store.py +143 -0
- omnibase_infra/nodes/effects/protocol_postgres_adapter.py +96 -0
- omnibase_infra/nodes/effects/registry_effect.py +525 -0
- omnibase_infra/nodes/effects/store_effect_idempotency_inmemory.py +425 -0
- omnibase_infra/nodes/handlers/consul/contract.yaml +85 -0
- omnibase_infra/nodes/handlers/db/contract.yaml +72 -0
- omnibase_infra/nodes/handlers/graph/contract.yaml +127 -0
- omnibase_infra/nodes/handlers/http/contract.yaml +74 -0
- omnibase_infra/nodes/handlers/intent/contract.yaml +66 -0
- omnibase_infra/nodes/handlers/mcp/contract.yaml +69 -0
- omnibase_infra/nodes/handlers/vault/contract.yaml +91 -0
- omnibase_infra/nodes/node_intent_storage_effect/__init__.py +50 -0
- omnibase_infra/nodes/node_intent_storage_effect/contract.yaml +194 -0
- omnibase_infra/nodes/node_intent_storage_effect/models/__init__.py +24 -0
- omnibase_infra/nodes/node_intent_storage_effect/models/model_intent_storage_input.py +141 -0
- omnibase_infra/nodes/node_intent_storage_effect/models/model_intent_storage_output.py +130 -0
- omnibase_infra/nodes/node_intent_storage_effect/node.py +94 -0
- omnibase_infra/nodes/node_intent_storage_effect/registry/__init__.py +35 -0
- omnibase_infra/nodes/node_intent_storage_effect/registry/registry_infra_intent_storage.py +294 -0
- omnibase_infra/nodes/node_ledger_projection_compute/__init__.py +50 -0
- omnibase_infra/nodes/node_ledger_projection_compute/contract.yaml +104 -0
- omnibase_infra/nodes/node_ledger_projection_compute/node.py +284 -0
- omnibase_infra/nodes/node_ledger_projection_compute/registry/__init__.py +29 -0
- omnibase_infra/nodes/node_ledger_projection_compute/registry/registry_infra_ledger_projection.py +118 -0
- omnibase_infra/nodes/node_ledger_write_effect/__init__.py +82 -0
- omnibase_infra/nodes/node_ledger_write_effect/contract.yaml +200 -0
- omnibase_infra/nodes/node_ledger_write_effect/handlers/__init__.py +22 -0
- omnibase_infra/nodes/node_ledger_write_effect/handlers/handler_ledger_append.py +372 -0
- omnibase_infra/nodes/node_ledger_write_effect/handlers/handler_ledger_query.py +597 -0
- omnibase_infra/nodes/node_ledger_write_effect/models/__init__.py +31 -0
- omnibase_infra/nodes/node_ledger_write_effect/models/model_ledger_append_result.py +54 -0
- omnibase_infra/nodes/node_ledger_write_effect/models/model_ledger_entry.py +92 -0
- omnibase_infra/nodes/node_ledger_write_effect/models/model_ledger_query.py +53 -0
- omnibase_infra/nodes/node_ledger_write_effect/models/model_ledger_query_result.py +41 -0
- omnibase_infra/nodes/node_ledger_write_effect/node.py +89 -0
- omnibase_infra/nodes/node_ledger_write_effect/protocols/__init__.py +13 -0
- omnibase_infra/nodes/node_ledger_write_effect/protocols/protocol_ledger_persistence.py +127 -0
- omnibase_infra/nodes/node_ledger_write_effect/registry/__init__.py +9 -0
- omnibase_infra/nodes/node_ledger_write_effect/registry/registry_infra_ledger_write.py +121 -0
- omnibase_infra/nodes/node_registration_orchestrator/README.md +542 -0
- omnibase_infra/nodes/node_registration_orchestrator/__init__.py +120 -0
- omnibase_infra/nodes/node_registration_orchestrator/contract.yaml +482 -0
- omnibase_infra/nodes/node_registration_orchestrator/dispatchers/__init__.py +53 -0
- omnibase_infra/nodes/node_registration_orchestrator/dispatchers/dispatcher_node_introspected.py +376 -0
- omnibase_infra/nodes/node_registration_orchestrator/dispatchers/dispatcher_node_registration_acked.py +376 -0
- omnibase_infra/nodes/node_registration_orchestrator/dispatchers/dispatcher_runtime_tick.py +373 -0
- omnibase_infra/nodes/node_registration_orchestrator/handlers/__init__.py +62 -0
- omnibase_infra/nodes/node_registration_orchestrator/handlers/handler_node_heartbeat.py +376 -0
- omnibase_infra/nodes/node_registration_orchestrator/handlers/handler_node_introspected.py +694 -0
- omnibase_infra/nodes/node_registration_orchestrator/handlers/handler_node_registration_acked.py +458 -0
- omnibase_infra/nodes/node_registration_orchestrator/handlers/handler_runtime_tick.py +364 -0
- omnibase_infra/nodes/node_registration_orchestrator/introspection_event_router.py +544 -0
- omnibase_infra/nodes/node_registration_orchestrator/models/__init__.py +75 -0
- omnibase_infra/nodes/node_registration_orchestrator/models/model_consul_intent_payload.py +194 -0
- omnibase_infra/nodes/node_registration_orchestrator/models/model_consul_registration_intent.py +67 -0
- omnibase_infra/nodes/node_registration_orchestrator/models/model_intent_execution_result.py +50 -0
- omnibase_infra/nodes/node_registration_orchestrator/models/model_node_liveness_expired.py +107 -0
- omnibase_infra/nodes/node_registration_orchestrator/models/model_orchestrator_config.py +67 -0
- omnibase_infra/nodes/node_registration_orchestrator/models/model_orchestrator_input.py +41 -0
- omnibase_infra/nodes/node_registration_orchestrator/models/model_orchestrator_output.py +166 -0
- omnibase_infra/nodes/node_registration_orchestrator/models/model_postgres_intent_payload.py +235 -0
- omnibase_infra/nodes/node_registration_orchestrator/models/model_postgres_upsert_intent.py +68 -0
- omnibase_infra/nodes/node_registration_orchestrator/models/model_reducer_execution_result.py +384 -0
- omnibase_infra/nodes/node_registration_orchestrator/models/model_reducer_state.py +60 -0
- omnibase_infra/nodes/node_registration_orchestrator/models/model_registration_intent.py +177 -0
- omnibase_infra/nodes/node_registration_orchestrator/models/model_registry_intent.py +247 -0
- omnibase_infra/nodes/node_registration_orchestrator/node.py +195 -0
- omnibase_infra/nodes/node_registration_orchestrator/plugin.py +909 -0
- omnibase_infra/nodes/node_registration_orchestrator/protocols.py +439 -0
- omnibase_infra/nodes/node_registration_orchestrator/registry/__init__.py +41 -0
- omnibase_infra/nodes/node_registration_orchestrator/registry/registry_infra_node_registration_orchestrator.py +528 -0
- omnibase_infra/nodes/node_registration_orchestrator/timeout_coordinator.py +393 -0
- omnibase_infra/nodes/node_registration_orchestrator/wiring.py +743 -0
- omnibase_infra/nodes/node_registration_reducer/__init__.py +15 -0
- omnibase_infra/nodes/node_registration_reducer/contract.yaml +301 -0
- omnibase_infra/nodes/node_registration_reducer/models/__init__.py +38 -0
- omnibase_infra/nodes/node_registration_reducer/models/model_validation_result.py +113 -0
- omnibase_infra/nodes/node_registration_reducer/node.py +139 -0
- omnibase_infra/nodes/node_registration_reducer/registry/__init__.py +9 -0
- omnibase_infra/nodes/node_registration_reducer/registry/registry_infra_node_registration_reducer.py +79 -0
- omnibase_infra/nodes/node_registration_storage_effect/__init__.py +41 -0
- omnibase_infra/nodes/node_registration_storage_effect/contract.yaml +220 -0
- omnibase_infra/nodes/node_registration_storage_effect/models/__init__.py +44 -0
- omnibase_infra/nodes/node_registration_storage_effect/models/model_delete_result.py +132 -0
- omnibase_infra/nodes/node_registration_storage_effect/models/model_registration_record.py +199 -0
- omnibase_infra/nodes/node_registration_storage_effect/models/model_registration_update.py +155 -0
- omnibase_infra/nodes/node_registration_storage_effect/models/model_storage_health_check_details.py +123 -0
- omnibase_infra/nodes/node_registration_storage_effect/models/model_storage_health_check_result.py +117 -0
- omnibase_infra/nodes/node_registration_storage_effect/models/model_storage_query.py +100 -0
- omnibase_infra/nodes/node_registration_storage_effect/models/model_storage_result.py +136 -0
- omnibase_infra/nodes/node_registration_storage_effect/models/model_upsert_result.py +127 -0
- omnibase_infra/nodes/node_registration_storage_effect/node.py +112 -0
- omnibase_infra/nodes/node_registration_storage_effect/protocols/__init__.py +22 -0
- omnibase_infra/nodes/node_registration_storage_effect/protocols/protocol_registration_persistence.py +333 -0
- omnibase_infra/nodes/node_registration_storage_effect/registry/__init__.py +23 -0
- omnibase_infra/nodes/node_registration_storage_effect/registry/registry_infra_registration_storage.py +215 -0
- omnibase_infra/nodes/node_registry_effect/__init__.py +85 -0
- omnibase_infra/nodes/node_registry_effect/contract.yaml +677 -0
- omnibase_infra/nodes/node_registry_effect/handlers/__init__.py +70 -0
- omnibase_infra/nodes/node_registry_effect/handlers/handler_consul_deregister.py +211 -0
- omnibase_infra/nodes/node_registry_effect/handlers/handler_consul_register.py +212 -0
- omnibase_infra/nodes/node_registry_effect/handlers/handler_partial_retry.py +417 -0
- omnibase_infra/nodes/node_registry_effect/handlers/handler_postgres_deactivate.py +215 -0
- omnibase_infra/nodes/node_registry_effect/handlers/handler_postgres_upsert.py +208 -0
- omnibase_infra/nodes/node_registry_effect/models/__init__.py +43 -0
- omnibase_infra/nodes/node_registry_effect/models/model_partial_retry_request.py +92 -0
- omnibase_infra/nodes/node_registry_effect/node.py +165 -0
- omnibase_infra/nodes/node_registry_effect/registry/__init__.py +27 -0
- omnibase_infra/nodes/node_registry_effect/registry/registry_infra_registry_effect.py +196 -0
- omnibase_infra/nodes/node_service_discovery_effect/__init__.py +111 -0
- omnibase_infra/nodes/node_service_discovery_effect/contract.yaml +246 -0
- omnibase_infra/nodes/node_service_discovery_effect/models/__init__.py +67 -0
- omnibase_infra/nodes/node_service_discovery_effect/models/enum_health_status.py +72 -0
- omnibase_infra/nodes/node_service_discovery_effect/models/enum_service_discovery_operation.py +58 -0
- omnibase_infra/nodes/node_service_discovery_effect/models/model_discovery_query.py +99 -0
- omnibase_infra/nodes/node_service_discovery_effect/models/model_discovery_result.py +98 -0
- omnibase_infra/nodes/node_service_discovery_effect/models/model_health_check_config.py +121 -0
- omnibase_infra/nodes/node_service_discovery_effect/models/model_query_metadata.py +63 -0
- omnibase_infra/nodes/node_service_discovery_effect/models/model_registration_result.py +130 -0
- omnibase_infra/nodes/node_service_discovery_effect/models/model_service_discovery_health_check_details.py +111 -0
- omnibase_infra/nodes/node_service_discovery_effect/models/model_service_discovery_health_check_result.py +119 -0
- omnibase_infra/nodes/node_service_discovery_effect/models/model_service_info.py +106 -0
- omnibase_infra/nodes/node_service_discovery_effect/models/model_service_registration.py +121 -0
- omnibase_infra/nodes/node_service_discovery_effect/node.py +111 -0
- omnibase_infra/nodes/node_service_discovery_effect/protocols/__init__.py +14 -0
- omnibase_infra/nodes/node_service_discovery_effect/protocols/protocol_discovery_operations.py +279 -0
- omnibase_infra/nodes/node_service_discovery_effect/registry/__init__.py +13 -0
- omnibase_infra/nodes/node_service_discovery_effect/registry/registry_infra_service_discovery.py +222 -0
- omnibase_infra/nodes/reducers/__init__.py +30 -0
- omnibase_infra/nodes/reducers/models/__init__.py +37 -0
- omnibase_infra/nodes/reducers/models/model_payload_consul_register.py +87 -0
- omnibase_infra/nodes/reducers/models/model_payload_ledger_append.py +133 -0
- omnibase_infra/nodes/reducers/models/model_payload_postgres_upsert_registration.py +60 -0
- omnibase_infra/nodes/reducers/models/model_registration_confirmation.py +166 -0
- omnibase_infra/nodes/reducers/models/model_registration_state.py +433 -0
- omnibase_infra/nodes/reducers/registration_reducer.py +1138 -0
- omnibase_infra/observability/__init__.py +143 -0
- omnibase_infra/observability/constants_metrics.py +91 -0
- omnibase_infra/observability/factory_observability_sink.py +525 -0
- omnibase_infra/observability/handlers/__init__.py +118 -0
- omnibase_infra/observability/handlers/handler_logging_structured.py +967 -0
- omnibase_infra/observability/handlers/handler_metrics_prometheus.py +1120 -0
- omnibase_infra/observability/handlers/model_logging_handler_config.py +71 -0
- omnibase_infra/observability/handlers/model_logging_handler_response.py +77 -0
- omnibase_infra/observability/handlers/model_metrics_handler_config.py +172 -0
- omnibase_infra/observability/handlers/model_metrics_handler_payload.py +135 -0
- omnibase_infra/observability/handlers/model_metrics_handler_response.py +101 -0
- omnibase_infra/observability/hooks/__init__.py +74 -0
- omnibase_infra/observability/hooks/hook_observability.py +1223 -0
- omnibase_infra/observability/models/__init__.py +30 -0
- omnibase_infra/observability/models/enum_required_log_context_key.py +77 -0
- omnibase_infra/observability/models/model_buffered_log_entry.py +117 -0
- omnibase_infra/observability/models/model_logging_sink_config.py +73 -0
- omnibase_infra/observability/models/model_metrics_sink_config.py +156 -0
- omnibase_infra/observability/sinks/__init__.py +69 -0
- omnibase_infra/observability/sinks/sink_logging_structured.py +809 -0
- omnibase_infra/observability/sinks/sink_metrics_prometheus.py +710 -0
- omnibase_infra/plugins/__init__.py +27 -0
- omnibase_infra/plugins/examples/__init__.py +28 -0
- omnibase_infra/plugins/examples/plugin_json_normalizer.py +271 -0
- omnibase_infra/plugins/examples/plugin_json_normalizer_error_handling.py +210 -0
- omnibase_infra/plugins/models/__init__.py +21 -0
- omnibase_infra/plugins/models/model_plugin_context.py +76 -0
- omnibase_infra/plugins/models/model_plugin_input_data.py +58 -0
- omnibase_infra/plugins/models/model_plugin_output_data.py +62 -0
- omnibase_infra/plugins/plugin_compute_base.py +449 -0
- omnibase_infra/projectors/__init__.py +30 -0
- omnibase_infra/projectors/contracts/__init__.py +63 -0
- omnibase_infra/projectors/contracts/registration_projector.yaml +370 -0
- omnibase_infra/projectors/projection_reader_registration.py +1559 -0
- omnibase_infra/projectors/snapshot_publisher_registration.py +1329 -0
- omnibase_infra/protocols/__init__.py +104 -0
- omnibase_infra/protocols/protocol_capability_projection.py +253 -0
- omnibase_infra/protocols/protocol_capability_query.py +251 -0
- omnibase_infra/protocols/protocol_container_aware.py +200 -0
- omnibase_infra/protocols/protocol_dispatch_engine.py +152 -0
- omnibase_infra/protocols/protocol_event_bus_like.py +127 -0
- omnibase_infra/protocols/protocol_event_projector.py +96 -0
- omnibase_infra/protocols/protocol_idempotency_store.py +142 -0
- omnibase_infra/protocols/protocol_message_dispatcher.py +247 -0
- omnibase_infra/protocols/protocol_message_type_registry.py +306 -0
- omnibase_infra/protocols/protocol_plugin_compute.py +368 -0
- omnibase_infra/protocols/protocol_projector_schema_validator.py +82 -0
- omnibase_infra/protocols/protocol_registry_metrics.py +215 -0
- omnibase_infra/protocols/protocol_snapshot_publisher.py +396 -0
- omnibase_infra/protocols/protocol_snapshot_store.py +567 -0
- omnibase_infra/runtime/__init__.py +445 -0
- omnibase_infra/runtime/binding_config_resolver.py +2771 -0
- omnibase_infra/runtime/binding_resolver.py +753 -0
- omnibase_infra/runtime/chain_aware_dispatch.py +467 -0
- omnibase_infra/runtime/constants_notification.py +75 -0
- omnibase_infra/runtime/constants_security.py +70 -0
- omnibase_infra/runtime/contract_handler_discovery.py +587 -0
- omnibase_infra/runtime/contract_loaders/__init__.py +51 -0
- omnibase_infra/runtime/contract_loaders/handler_routing_loader.py +464 -0
- omnibase_infra/runtime/contract_loaders/operation_bindings_loader.py +789 -0
- omnibase_infra/runtime/dispatch_context_enforcer.py +427 -0
- omnibase_infra/runtime/emit_daemon/__init__.py +97 -0
- omnibase_infra/runtime/emit_daemon/cli.py +844 -0
- omnibase_infra/runtime/emit_daemon/client.py +811 -0
- omnibase_infra/runtime/emit_daemon/config.py +535 -0
- omnibase_infra/runtime/emit_daemon/daemon.py +812 -0
- omnibase_infra/runtime/emit_daemon/event_registry.py +477 -0
- omnibase_infra/runtime/emit_daemon/model_daemon_request.py +139 -0
- omnibase_infra/runtime/emit_daemon/model_daemon_response.py +191 -0
- omnibase_infra/runtime/emit_daemon/queue.py +618 -0
- omnibase_infra/runtime/enums/__init__.py +18 -0
- omnibase_infra/runtime/enums/enum_config_ref_scheme.py +33 -0
- omnibase_infra/runtime/enums/enum_scheduler_status.py +170 -0
- omnibase_infra/runtime/envelope_validator.py +179 -0
- omnibase_infra/runtime/event_bus_subcontract_wiring.py +466 -0
- omnibase_infra/runtime/handler_bootstrap_source.py +507 -0
- omnibase_infra/runtime/handler_contract_config_loader.py +603 -0
- omnibase_infra/runtime/handler_contract_source.py +750 -0
- omnibase_infra/runtime/handler_identity.py +81 -0
- omnibase_infra/runtime/handler_plugin_loader.py +2046 -0
- omnibase_infra/runtime/handler_registry.py +329 -0
- omnibase_infra/runtime/handler_source_resolver.py +367 -0
- omnibase_infra/runtime/invocation_security_enforcer.py +427 -0
- omnibase_infra/runtime/kafka_contract_source.py +984 -0
- omnibase_infra/runtime/kernel.py +40 -0
- omnibase_infra/runtime/mixin_policy_validation.py +522 -0
- omnibase_infra/runtime/mixin_semver_cache.py +402 -0
- omnibase_infra/runtime/mixins/__init__.py +24 -0
- omnibase_infra/runtime/mixins/mixin_projector_notification_publishing.py +566 -0
- omnibase_infra/runtime/mixins/mixin_projector_sql_operations.py +778 -0
- omnibase_infra/runtime/models/__init__.py +229 -0
- omnibase_infra/runtime/models/model_batch_lifecycle_result.py +217 -0
- omnibase_infra/runtime/models/model_binding_config.py +168 -0
- omnibase_infra/runtime/models/model_binding_config_cache_stats.py +135 -0
- omnibase_infra/runtime/models/model_binding_config_resolver_config.py +329 -0
- omnibase_infra/runtime/models/model_cached_secret.py +138 -0
- omnibase_infra/runtime/models/model_compute_key.py +138 -0
- omnibase_infra/runtime/models/model_compute_registration.py +97 -0
- omnibase_infra/runtime/models/model_config_cache_entry.py +61 -0
- omnibase_infra/runtime/models/model_config_ref.py +331 -0
- omnibase_infra/runtime/models/model_config_ref_parse_result.py +125 -0
- omnibase_infra/runtime/models/model_contract_load_result.py +224 -0
- omnibase_infra/runtime/models/model_domain_plugin_config.py +92 -0
- omnibase_infra/runtime/models/model_domain_plugin_result.py +270 -0
- omnibase_infra/runtime/models/model_duplicate_response.py +54 -0
- omnibase_infra/runtime/models/model_enabled_protocols_config.py +61 -0
- omnibase_infra/runtime/models/model_event_bus_config.py +54 -0
- omnibase_infra/runtime/models/model_failed_component.py +55 -0
- omnibase_infra/runtime/models/model_health_check_response.py +168 -0
- omnibase_infra/runtime/models/model_health_check_result.py +229 -0
- omnibase_infra/runtime/models/model_lifecycle_result.py +245 -0
- omnibase_infra/runtime/models/model_logging_config.py +42 -0
- omnibase_infra/runtime/models/model_optional_correlation_id.py +167 -0
- omnibase_infra/runtime/models/model_optional_string.py +94 -0
- omnibase_infra/runtime/models/model_optional_uuid.py +110 -0
- omnibase_infra/runtime/models/model_policy_context.py +100 -0
- omnibase_infra/runtime/models/model_policy_key.py +138 -0
- omnibase_infra/runtime/models/model_policy_registration.py +139 -0
- omnibase_infra/runtime/models/model_policy_result.py +103 -0
- omnibase_infra/runtime/models/model_policy_type_filter.py +157 -0
- omnibase_infra/runtime/models/model_projector_notification_config.py +171 -0
- omnibase_infra/runtime/models/model_projector_plugin_loader_config.py +47 -0
- omnibase_infra/runtime/models/model_protocol_registration_config.py +65 -0
- omnibase_infra/runtime/models/model_retry_policy.py +105 -0
- omnibase_infra/runtime/models/model_runtime_config.py +150 -0
- omnibase_infra/runtime/models/model_runtime_contract_config.py +268 -0
- omnibase_infra/runtime/models/model_runtime_scheduler_config.py +625 -0
- omnibase_infra/runtime/models/model_runtime_scheduler_metrics.py +233 -0
- omnibase_infra/runtime/models/model_runtime_tick.py +193 -0
- omnibase_infra/runtime/models/model_secret_cache_stats.py +82 -0
- omnibase_infra/runtime/models/model_secret_mapping.py +63 -0
- omnibase_infra/runtime/models/model_secret_resolver_config.py +107 -0
- omnibase_infra/runtime/models/model_secret_resolver_metrics.py +111 -0
- omnibase_infra/runtime/models/model_secret_source_info.py +72 -0
- omnibase_infra/runtime/models/model_secret_source_spec.py +66 -0
- omnibase_infra/runtime/models/model_security_config.py +109 -0
- omnibase_infra/runtime/models/model_shutdown_batch_result.py +75 -0
- omnibase_infra/runtime/models/model_shutdown_config.py +94 -0
- omnibase_infra/runtime/models/model_transition_notification_outbox_config.py +112 -0
- omnibase_infra/runtime/models/model_transition_notification_outbox_metrics.py +140 -0
- omnibase_infra/runtime/models/model_transition_notification_publisher_metrics.py +357 -0
- omnibase_infra/runtime/projector_plugin_loader.py +1462 -0
- omnibase_infra/runtime/projector_schema_manager.py +565 -0
- omnibase_infra/runtime/projector_shell.py +1330 -0
- omnibase_infra/runtime/protocol_contract_descriptor.py +92 -0
- omnibase_infra/runtime/protocol_contract_source.py +92 -0
- omnibase_infra/runtime/protocol_domain_plugin.py +474 -0
- omnibase_infra/runtime/protocol_handler_discovery.py +221 -0
- omnibase_infra/runtime/protocol_handler_plugin_loader.py +327 -0
- omnibase_infra/runtime/protocol_lifecycle_executor.py +435 -0
- omnibase_infra/runtime/protocol_policy.py +366 -0
- omnibase_infra/runtime/protocols/__init__.py +37 -0
- omnibase_infra/runtime/protocols/protocol_runtime_scheduler.py +468 -0
- omnibase_infra/runtime/publisher_topic_scoped.py +294 -0
- omnibase_infra/runtime/registry/__init__.py +93 -0
- omnibase_infra/runtime/registry/mixin_message_type_query.py +326 -0
- omnibase_infra/runtime/registry/mixin_message_type_registration.py +354 -0
- omnibase_infra/runtime/registry/registry_event_bus_binding.py +268 -0
- omnibase_infra/runtime/registry/registry_message_type.py +542 -0
- omnibase_infra/runtime/registry/registry_protocol_binding.py +445 -0
- omnibase_infra/runtime/registry_compute.py +1143 -0
- omnibase_infra/runtime/registry_contract_source.py +693 -0
- omnibase_infra/runtime/registry_dispatcher.py +678 -0
- omnibase_infra/runtime/registry_policy.py +1185 -0
- omnibase_infra/runtime/runtime_contract_config_loader.py +406 -0
- omnibase_infra/runtime/runtime_scheduler.py +1070 -0
- omnibase_infra/runtime/secret_resolver.py +2112 -0
- omnibase_infra/runtime/security_metadata_validator.py +776 -0
- omnibase_infra/runtime/service_kernel.py +1651 -0
- omnibase_infra/runtime/service_message_dispatch_engine.py +2350 -0
- omnibase_infra/runtime/service_runtime_host_process.py +3493 -0
- omnibase_infra/runtime/transition_notification_outbox.py +1190 -0
- omnibase_infra/runtime/transition_notification_publisher.py +765 -0
- omnibase_infra/runtime/util_container_wiring.py +1124 -0
- omnibase_infra/runtime/util_validation.py +314 -0
- omnibase_infra/runtime/util_version.py +98 -0
- omnibase_infra/runtime/util_wiring.py +723 -0
- omnibase_infra/schemas/schema_registration_projection.sql +320 -0
- omnibase_infra/schemas/schema_transition_notification_outbox.sql +245 -0
- omnibase_infra/services/__init__.py +89 -0
- omnibase_infra/services/corpus_capture.py +684 -0
- omnibase_infra/services/mcp/__init__.py +31 -0
- omnibase_infra/services/mcp/mcp_server_lifecycle.py +449 -0
- omnibase_infra/services/mcp/service_mcp_tool_discovery.py +411 -0
- omnibase_infra/services/mcp/service_mcp_tool_registry.py +329 -0
- omnibase_infra/services/mcp/service_mcp_tool_sync.py +565 -0
- omnibase_infra/services/registry_api/__init__.py +40 -0
- omnibase_infra/services/registry_api/main.py +261 -0
- omnibase_infra/services/registry_api/models/__init__.py +66 -0
- omnibase_infra/services/registry_api/models/model_capability_widget_mapping.py +38 -0
- omnibase_infra/services/registry_api/models/model_pagination_info.py +48 -0
- omnibase_infra/services/registry_api/models/model_registry_discovery_response.py +73 -0
- omnibase_infra/services/registry_api/models/model_registry_health_response.py +49 -0
- omnibase_infra/services/registry_api/models/model_registry_instance_view.py +88 -0
- omnibase_infra/services/registry_api/models/model_registry_node_view.py +88 -0
- omnibase_infra/services/registry_api/models/model_registry_summary.py +60 -0
- omnibase_infra/services/registry_api/models/model_response_list_instances.py +43 -0
- omnibase_infra/services/registry_api/models/model_response_list_nodes.py +51 -0
- omnibase_infra/services/registry_api/models/model_warning.py +49 -0
- omnibase_infra/services/registry_api/models/model_widget_defaults.py +28 -0
- omnibase_infra/services/registry_api/models/model_widget_mapping.py +51 -0
- omnibase_infra/services/registry_api/routes.py +371 -0
- omnibase_infra/services/registry_api/service.py +837 -0
- omnibase_infra/services/service_capability_query.py +945 -0
- omnibase_infra/services/service_health.py +898 -0
- omnibase_infra/services/service_node_selector.py +530 -0
- omnibase_infra/services/service_timeout_emitter.py +699 -0
- omnibase_infra/services/service_timeout_scanner.py +394 -0
- omnibase_infra/services/session/__init__.py +56 -0
- omnibase_infra/services/session/config_consumer.py +137 -0
- omnibase_infra/services/session/config_store.py +139 -0
- omnibase_infra/services/session/consumer.py +1007 -0
- omnibase_infra/services/session/protocol_session_aggregator.py +117 -0
- omnibase_infra/services/session/store.py +997 -0
- omnibase_infra/services/snapshot/__init__.py +31 -0
- omnibase_infra/services/snapshot/service_snapshot.py +647 -0
- omnibase_infra/services/snapshot/store_inmemory.py +637 -0
- omnibase_infra/services/snapshot/store_postgres.py +1279 -0
- omnibase_infra/shared/__init__.py +8 -0
- omnibase_infra/testing/__init__.py +10 -0
- omnibase_infra/testing/utils.py +23 -0
- omnibase_infra/topics/__init__.py +45 -0
- omnibase_infra/topics/platform_topic_suffixes.py +140 -0
- omnibase_infra/topics/util_topic_composition.py +95 -0
- omnibase_infra/types/__init__.py +48 -0
- omnibase_infra/types/type_cache_info.py +49 -0
- omnibase_infra/types/type_dsn.py +173 -0
- omnibase_infra/types/type_infra_aliases.py +60 -0
- omnibase_infra/types/typed_dict/__init__.py +29 -0
- omnibase_infra/types/typed_dict/typed_dict_envelope_build_params.py +115 -0
- omnibase_infra/types/typed_dict/typed_dict_introspection_cache.py +128 -0
- omnibase_infra/types/typed_dict/typed_dict_performance_metrics_cache.py +140 -0
- omnibase_infra/types/typed_dict_capabilities.py +64 -0
- omnibase_infra/utils/__init__.py +117 -0
- omnibase_infra/utils/correlation.py +208 -0
- omnibase_infra/utils/util_atomic_file.py +261 -0
- omnibase_infra/utils/util_consumer_group.py +232 -0
- omnibase_infra/utils/util_datetime.py +372 -0
- omnibase_infra/utils/util_db_transaction.py +239 -0
- omnibase_infra/utils/util_dsn_validation.py +333 -0
- omnibase_infra/utils/util_env_parsing.py +264 -0
- omnibase_infra/utils/util_error_sanitization.py +457 -0
- omnibase_infra/utils/util_pydantic_validators.py +477 -0
- omnibase_infra/utils/util_retry_optimistic.py +281 -0
- omnibase_infra/utils/util_semver.py +233 -0
- omnibase_infra/validation/__init__.py +307 -0
- omnibase_infra/validation/contracts/security.validation.yaml +114 -0
- omnibase_infra/validation/enums/__init__.py +11 -0
- omnibase_infra/validation/enums/enum_contract_violation_severity.py +13 -0
- omnibase_infra/validation/infra_validators.py +1514 -0
- omnibase_infra/validation/linter_contract.py +907 -0
- omnibase_infra/validation/mixin_any_type_classification.py +120 -0
- omnibase_infra/validation/mixin_any_type_exemption.py +580 -0
- omnibase_infra/validation/mixin_any_type_reporting.py +106 -0
- omnibase_infra/validation/mixin_execution_shape_violation_checks.py +596 -0
- omnibase_infra/validation/mixin_node_archetype_detection.py +254 -0
- omnibase_infra/validation/models/__init__.py +15 -0
- omnibase_infra/validation/models/model_contract_lint_result.py +101 -0
- omnibase_infra/validation/models/model_contract_violation.py +41 -0
- omnibase_infra/validation/service_validation_aggregator.py +395 -0
- omnibase_infra/validation/validation_exemptions.yaml +2033 -0
- omnibase_infra/validation/validator_any_type.py +715 -0
- omnibase_infra/validation/validator_chain_propagation.py +839 -0
- omnibase_infra/validation/validator_execution_shape.py +465 -0
- omnibase_infra/validation/validator_localhandler.py +261 -0
- omnibase_infra/validation/validator_registration_security.py +410 -0
- omnibase_infra/validation/validator_routing_coverage.py +1020 -0
- omnibase_infra/validation/validator_runtime_shape.py +915 -0
- omnibase_infra/validation/validator_security.py +513 -0
- omnibase_infra/validation/validator_topic_category.py +1152 -0
- omnibase_infra-0.2.6.dist-info/METADATA +197 -0
- omnibase_infra-0.2.6.dist-info/RECORD +833 -0
- omnibase_infra-0.2.6.dist-info/WHEEL +4 -0
- omnibase_infra-0.2.6.dist-info/entry_points.txt +5 -0
- omnibase_infra-0.2.6.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
|
2
|
+
# Copyright (c) 2025 OmniNode Team
|
|
3
|
+
"""Datetime validation and normalization utilities.
|
|
4
|
+
|
|
5
|
+
This module provides utilities for ensuring datetime values are timezone-aware
|
|
6
|
+
before persisting to databases. Naive datetimes (without timezone info) can cause
|
|
7
|
+
subtle bugs when stored in PostgreSQL's TIMESTAMPTZ columns or when compared
|
|
8
|
+
across different timezones.
|
|
9
|
+
|
|
10
|
+
ONEX Datetime Guidelines:
|
|
11
|
+
- All datetimes should be timezone-aware (preferably UTC)
|
|
12
|
+
- Naive datetimes trigger warnings and are auto-converted to UTC
|
|
13
|
+
- Use datetime.now(UTC) instead of datetime.utcnow() (deprecated in Python 3.12+)
|
|
14
|
+
|
|
15
|
+
See Also:
|
|
16
|
+
- PostgreSQL TIMESTAMPTZ documentation
|
|
17
|
+
- Python datetime best practices (PEP 495)
|
|
18
|
+
- ONEX infrastructure datetime conventions
|
|
19
|
+
|
|
20
|
+
Example:
|
|
21
|
+
>>> from datetime import datetime, UTC
|
|
22
|
+
>>> from omnibase_infra.utils import ensure_timezone_aware
|
|
23
|
+
>>>
|
|
24
|
+
>>> # Aware datetime passes through unchanged
|
|
25
|
+
>>> aware_dt = datetime.now(UTC)
|
|
26
|
+
>>> result = ensure_timezone_aware(aware_dt)
|
|
27
|
+
>>> result == aware_dt
|
|
28
|
+
True
|
|
29
|
+
>>>
|
|
30
|
+
>>> # Naive datetime is converted to UTC with warning
|
|
31
|
+
>>> naive_dt = datetime(2025, 1, 15, 12, 0, 0)
|
|
32
|
+
>>> result = ensure_timezone_aware(naive_dt) # Logs warning
|
|
33
|
+
>>> result.tzinfo is not None
|
|
34
|
+
True
|
|
35
|
+
|
|
36
|
+
.. versionadded:: 0.8.0
|
|
37
|
+
Created as part of PR #146 datetime validation improvements.
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
from __future__ import annotations
|
|
41
|
+
|
|
42
|
+
import logging
|
|
43
|
+
from datetime import UTC, datetime
|
|
44
|
+
from typing import TYPE_CHECKING
|
|
45
|
+
from uuid import UUID, uuid4
|
|
46
|
+
|
|
47
|
+
if TYPE_CHECKING:
|
|
48
|
+
from omnibase_infra.errors import ModelInfraErrorContext
|
|
49
|
+
|
|
50
|
+
logger = logging.getLogger(__name__)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def ensure_timezone_aware(
|
|
54
|
+
dt: datetime,
|
|
55
|
+
*,
|
|
56
|
+
assume_utc: bool = True,
|
|
57
|
+
warn_on_naive: bool = True,
|
|
58
|
+
context: str | None = None,
|
|
59
|
+
) -> datetime:
|
|
60
|
+
"""Ensure a datetime is timezone-aware, converting naive datetimes to UTC.
|
|
61
|
+
|
|
62
|
+
This function validates that datetime values have timezone information before
|
|
63
|
+
they are persisted to the database. Naive datetimes (those without tzinfo)
|
|
64
|
+
are ambiguous and can cause subtle bugs when stored in TIMESTAMPTZ columns
|
|
65
|
+
or compared across timezones.
|
|
66
|
+
|
|
67
|
+
Behavior:
|
|
68
|
+
- Timezone-aware datetimes: Passed through unchanged
|
|
69
|
+
- Naive datetimes with assume_utc=True: Converted to UTC with warning
|
|
70
|
+
- Naive datetimes with assume_utc=False: Raises ProtocolConfigurationError
|
|
71
|
+
|
|
72
|
+
Args:
|
|
73
|
+
dt: The datetime to validate/normalize.
|
|
74
|
+
assume_utc: If True (default), naive datetimes are assumed to be UTC
|
|
75
|
+
and converted. If False, naive datetimes raise ValueError.
|
|
76
|
+
warn_on_naive: If True (default), logs a warning when a naive datetime
|
|
77
|
+
is converted. Set to False to suppress warnings (e.g., in migration
|
|
78
|
+
scripts where naive datetimes are expected).
|
|
79
|
+
context: Optional context string for the warning message (e.g., column
|
|
80
|
+
name, operation type). Helps identify the source of naive datetimes.
|
|
81
|
+
|
|
82
|
+
Returns:
|
|
83
|
+
A timezone-aware datetime. If the input was already aware, returns
|
|
84
|
+
the same datetime. If naive and assume_utc=True, returns a new
|
|
85
|
+
datetime with UTC timezone.
|
|
86
|
+
|
|
87
|
+
Raises:
|
|
88
|
+
ProtocolConfigurationError: If dt is naive and assume_utc=False.
|
|
89
|
+
|
|
90
|
+
Example:
|
|
91
|
+
>>> from datetime import datetime, UTC, timezone
|
|
92
|
+
>>> from omnibase_infra.utils.util_datetime import ensure_timezone_aware
|
|
93
|
+
>>>
|
|
94
|
+
>>> # Already aware - passes through unchanged
|
|
95
|
+
>>> aware = datetime(2025, 1, 15, 12, 0, 0, tzinfo=UTC)
|
|
96
|
+
>>> ensure_timezone_aware(aware) == aware
|
|
97
|
+
True
|
|
98
|
+
>>>
|
|
99
|
+
>>> # Naive datetime - converted to UTC with warning
|
|
100
|
+
>>> naive = datetime(2025, 1, 15, 12, 0, 0)
|
|
101
|
+
>>> result = ensure_timezone_aware(naive, context="updated_at")
|
|
102
|
+
>>> result.tzinfo == UTC
|
|
103
|
+
True
|
|
104
|
+
>>>
|
|
105
|
+
>>> # Strict mode - raises ProtocolConfigurationError for naive datetimes
|
|
106
|
+
>>> ensure_timezone_aware(naive, assume_utc=False) # doctest: +ELLIPSIS
|
|
107
|
+
Traceback (most recent call last):
|
|
108
|
+
...
|
|
109
|
+
omnibase_infra.errors...ProtocolConfigurationError: Naive datetime not allowed...
|
|
110
|
+
|
|
111
|
+
Warning:
|
|
112
|
+
Using assume_utc=True can silently mask timezone bugs in your code.
|
|
113
|
+
It's better to fix the source of naive datetimes than to rely on
|
|
114
|
+
automatic conversion. The warning log helps identify these issues.
|
|
115
|
+
|
|
116
|
+
Related:
|
|
117
|
+
- OMN-1170: Converting ProjectorRegistration to declarative contracts
|
|
118
|
+
- PR #146: Datetime validation improvements
|
|
119
|
+
"""
|
|
120
|
+
# Check if datetime is already timezone-aware
|
|
121
|
+
if is_timezone_aware(dt):
|
|
122
|
+
return dt
|
|
123
|
+
|
|
124
|
+
# Handle naive datetime
|
|
125
|
+
if not assume_utc:
|
|
126
|
+
# Lazy imports to avoid circular dependency (utils -> errors -> models -> utils)
|
|
127
|
+
from omnibase_infra.enums import EnumInfraTransportType
|
|
128
|
+
from omnibase_infra.errors import (
|
|
129
|
+
ModelInfraErrorContext,
|
|
130
|
+
ProtocolConfigurationError,
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
error_context = ModelInfraErrorContext(
|
|
134
|
+
transport_type=EnumInfraTransportType.RUNTIME,
|
|
135
|
+
operation="ensure_timezone_aware",
|
|
136
|
+
target_name=context,
|
|
137
|
+
correlation_id=uuid4(),
|
|
138
|
+
)
|
|
139
|
+
raise ProtocolConfigurationError(
|
|
140
|
+
"Naive datetime not allowed. "
|
|
141
|
+
"Use timezone-aware datetime (e.g., datetime.now(UTC)).",
|
|
142
|
+
context=error_context,
|
|
143
|
+
parameter="dt",
|
|
144
|
+
value=dt.isoformat(),
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
# Log warning if enabled
|
|
148
|
+
if warn_on_naive:
|
|
149
|
+
context_msg = f" for '{context}'" if context else ""
|
|
150
|
+
logger.warning(
|
|
151
|
+
"Converting naive datetime to UTC%s. "
|
|
152
|
+
"Consider using datetime.now(UTC) instead of datetime.utcnow() or naive datetime().",
|
|
153
|
+
context_msg,
|
|
154
|
+
extra={
|
|
155
|
+
"naive_datetime": dt.isoformat(),
|
|
156
|
+
"context": context,
|
|
157
|
+
"action": "converted_to_utc",
|
|
158
|
+
},
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
# Convert naive datetime to UTC by replacing tzinfo
|
|
162
|
+
# Using replace() instead of astimezone() because astimezone() interprets
|
|
163
|
+
# naive datetimes as local time, which we don't want
|
|
164
|
+
return dt.replace(tzinfo=UTC)
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
def is_timezone_aware(dt: datetime) -> bool:
|
|
168
|
+
"""Check if a datetime is timezone-aware.
|
|
169
|
+
|
|
170
|
+
A datetime is timezone-aware if it has a tzinfo attribute that is not None
|
|
171
|
+
AND returns a valid utcoffset(). Some tzinfo objects may be set but not
|
|
172
|
+
properly configured, so we check both conditions.
|
|
173
|
+
|
|
174
|
+
Args:
|
|
175
|
+
dt: The datetime to check.
|
|
176
|
+
|
|
177
|
+
Returns:
|
|
178
|
+
True if datetime is timezone-aware, False if naive.
|
|
179
|
+
|
|
180
|
+
Example:
|
|
181
|
+
>>> from datetime import datetime, UTC
|
|
182
|
+
>>> from omnibase_infra.utils.util_datetime import is_timezone_aware
|
|
183
|
+
>>>
|
|
184
|
+
>>> is_timezone_aware(datetime.now(UTC))
|
|
185
|
+
True
|
|
186
|
+
>>> is_timezone_aware(datetime.now()) # Naive
|
|
187
|
+
False
|
|
188
|
+
"""
|
|
189
|
+
return dt.tzinfo is not None and dt.utcoffset() is not None
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
def validate_timezone_aware_with_context(
|
|
193
|
+
dt: datetime,
|
|
194
|
+
context: ModelInfraErrorContext,
|
|
195
|
+
*,
|
|
196
|
+
field_name: str = "envelope_timestamp",
|
|
197
|
+
) -> datetime:
|
|
198
|
+
"""Validate that a datetime is timezone-aware, raising ProtocolConfigurationError if not.
|
|
199
|
+
|
|
200
|
+
This is the SINGLE SOURCE OF TRUTH for handler-level timezone validation.
|
|
201
|
+
Use this function when you need to validate datetime values in handlers
|
|
202
|
+
and raise structured errors with context information.
|
|
203
|
+
|
|
204
|
+
For Pydantic field validators, use :func:`validate_timezone_aware_datetime`
|
|
205
|
+
from ``util_pydantic_validators.py`` instead.
|
|
206
|
+
|
|
207
|
+
Args:
|
|
208
|
+
dt: The datetime to validate.
|
|
209
|
+
context: A ModelInfraErrorContext instance for error reporting.
|
|
210
|
+
The context provides transport_type, operation, target_name,
|
|
211
|
+
and correlation_id for the error.
|
|
212
|
+
field_name: Name of the field being validated, used in error message.
|
|
213
|
+
Defaults to "envelope_timestamp".
|
|
214
|
+
|
|
215
|
+
Returns:
|
|
216
|
+
The validated datetime (unchanged if valid).
|
|
217
|
+
|
|
218
|
+
Raises:
|
|
219
|
+
ProtocolConfigurationError: If datetime is naive (no timezone info).
|
|
220
|
+
|
|
221
|
+
Example:
|
|
222
|
+
>>> from datetime import datetime, UTC
|
|
223
|
+
>>> from uuid import uuid4
|
|
224
|
+
>>> from omnibase_infra.enums import EnumInfraTransportType
|
|
225
|
+
>>> from omnibase_infra.errors import ModelInfraErrorContext
|
|
226
|
+
>>> from omnibase_infra.utils import validate_timezone_aware_with_context
|
|
227
|
+
>>>
|
|
228
|
+
>>> ctx = ModelInfraErrorContext(
|
|
229
|
+
... transport_type=EnumInfraTransportType.RUNTIME,
|
|
230
|
+
... operation="handle_event",
|
|
231
|
+
... target_name="my_handler",
|
|
232
|
+
... correlation_id=uuid4(),
|
|
233
|
+
... )
|
|
234
|
+
>>>
|
|
235
|
+
>>> # Valid: timezone-aware datetime passes through
|
|
236
|
+
>>> aware = datetime.now(UTC)
|
|
237
|
+
>>> validate_timezone_aware_with_context(aware, ctx) == aware
|
|
238
|
+
True
|
|
239
|
+
>>>
|
|
240
|
+
>>> # Invalid: naive datetime raises ProtocolConfigurationError
|
|
241
|
+
>>> naive = datetime.now()
|
|
242
|
+
>>> validate_timezone_aware_with_context(naive, ctx) # doctest: +ELLIPSIS
|
|
243
|
+
Traceback (most recent call last):
|
|
244
|
+
...
|
|
245
|
+
omnibase_infra.errors...ProtocolConfigurationError: envelope_timestamp must be timezone-aware...
|
|
246
|
+
|
|
247
|
+
Related:
|
|
248
|
+
- OMN-1181: Replace RuntimeError with structured errors
|
|
249
|
+
- PR #158: Consolidate duplicate validation functions
|
|
250
|
+
|
|
251
|
+
.. versionadded:: 0.9.1
|
|
252
|
+
Created to consolidate duplicate timezone validation in handlers.
|
|
253
|
+
"""
|
|
254
|
+
if is_timezone_aware(dt):
|
|
255
|
+
return dt
|
|
256
|
+
|
|
257
|
+
# Lazy imports to avoid circular dependency (utils -> errors -> models -> utils)
|
|
258
|
+
from omnibase_infra.errors import ProtocolConfigurationError
|
|
259
|
+
|
|
260
|
+
raise ProtocolConfigurationError(
|
|
261
|
+
f"{field_name} must be timezone-aware. Use datetime.now(UTC) or "
|
|
262
|
+
"datetime(..., tzinfo=timezone.utc) instead of naive datetime.",
|
|
263
|
+
context=context,
|
|
264
|
+
parameter=field_name,
|
|
265
|
+
value=dt.isoformat(),
|
|
266
|
+
)
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
def warn_if_naive_datetime(
|
|
270
|
+
dt: datetime,
|
|
271
|
+
*,
|
|
272
|
+
field_name: str | None = None,
|
|
273
|
+
context: str | None = None,
|
|
274
|
+
correlation_id: UUID | None = None,
|
|
275
|
+
logger: logging.Logger | None = None,
|
|
276
|
+
) -> None:
|
|
277
|
+
"""Log a warning if the datetime is naive (lacks timezone info).
|
|
278
|
+
|
|
279
|
+
This is a WARNING-ONLY function that does not modify or convert the datetime.
|
|
280
|
+
Use this when you want to detect and log naive datetimes without changing
|
|
281
|
+
them, such as for auditing or gradual migration scenarios.
|
|
282
|
+
|
|
283
|
+
For automatic conversion of naive datetimes to UTC, use :func:`ensure_timezone_aware`
|
|
284
|
+
instead.
|
|
285
|
+
|
|
286
|
+
Args:
|
|
287
|
+
dt: The datetime to check for timezone awareness.
|
|
288
|
+
field_name: Optional name of the field/column containing the datetime.
|
|
289
|
+
Used in the warning message to identify the source.
|
|
290
|
+
context: Optional context string for the warning message (e.g., operation
|
|
291
|
+
name, handler name). Provides additional context for debugging.
|
|
292
|
+
correlation_id: Optional correlation ID for distributed tracing. Included
|
|
293
|
+
in the log extra dict when provided.
|
|
294
|
+
logger: Optional logger instance to use. If not provided, uses the
|
|
295
|
+
module-level logger (omnibase_infra.utils.util_datetime).
|
|
296
|
+
|
|
297
|
+
Returns:
|
|
298
|
+
None. This function only logs a warning and does not return a value.
|
|
299
|
+
|
|
300
|
+
Example:
|
|
301
|
+
>>> from datetime import datetime, UTC
|
|
302
|
+
>>> from uuid import uuid4
|
|
303
|
+
>>> from omnibase_infra.utils import warn_if_naive_datetime
|
|
304
|
+
>>>
|
|
305
|
+
>>> # Naive datetime triggers warning
|
|
306
|
+
>>> naive_dt = datetime(2025, 1, 15, 12, 0, 0)
|
|
307
|
+
>>> warn_if_naive_datetime(
|
|
308
|
+
... naive_dt,
|
|
309
|
+
... field_name="created_at",
|
|
310
|
+
... context="manifest_persistence",
|
|
311
|
+
... correlation_id=uuid4(),
|
|
312
|
+
... ) # Logs warning
|
|
313
|
+
>>>
|
|
314
|
+
>>> # Aware datetime - no warning logged
|
|
315
|
+
>>> aware_dt = datetime.now(UTC)
|
|
316
|
+
>>> warn_if_naive_datetime(aware_dt, field_name="updated_at") # Silent
|
|
317
|
+
|
|
318
|
+
Warning:
|
|
319
|
+
This function is intentionally warning-only. If you need to convert naive
|
|
320
|
+
datetimes to UTC, use :func:`ensure_timezone_aware` with ``assume_utc=True``.
|
|
321
|
+
The separation allows callers to choose between:
|
|
322
|
+
|
|
323
|
+
- **warn_if_naive_datetime**: Audit/detect without modification
|
|
324
|
+
- **ensure_timezone_aware**: Convert with optional warning
|
|
325
|
+
|
|
326
|
+
Related:
|
|
327
|
+
- OMN-1340: Extract datetime warning utility
|
|
328
|
+
- OMN-1163: Handler manifest persistence datetime handling
|
|
329
|
+
|
|
330
|
+
.. versionadded:: 0.9.0
|
|
331
|
+
Extracted from handler_manifest_persistence.py for reuse across codebase.
|
|
332
|
+
"""
|
|
333
|
+
# Use module logger if none provided
|
|
334
|
+
log = logger if logger is not None else globals()["logger"]
|
|
335
|
+
|
|
336
|
+
# Check if datetime is timezone-aware - if so, nothing to warn about
|
|
337
|
+
if is_timezone_aware(dt):
|
|
338
|
+
return
|
|
339
|
+
|
|
340
|
+
# Build context-aware message parts
|
|
341
|
+
location_parts: list[str] = []
|
|
342
|
+
if field_name:
|
|
343
|
+
location_parts.append(f"field '{field_name}'")
|
|
344
|
+
if context:
|
|
345
|
+
location_parts.append(f"context '{context}'")
|
|
346
|
+
|
|
347
|
+
location_str = " in ".join(location_parts) if location_parts else "datetime value"
|
|
348
|
+
|
|
349
|
+
# Build extra dict for structured logging
|
|
350
|
+
extra: dict[str, str | None] = {
|
|
351
|
+
"field_name": field_name,
|
|
352
|
+
"context": context,
|
|
353
|
+
"datetime_value": dt.isoformat(),
|
|
354
|
+
}
|
|
355
|
+
if correlation_id is not None:
|
|
356
|
+
extra["correlation_id"] = str(correlation_id)
|
|
357
|
+
|
|
358
|
+
log.warning(
|
|
359
|
+
"Naive datetime detected for %s. For accurate comparisons, use "
|
|
360
|
+
"timezone-aware datetimes (e.g., datetime.now(UTC)). "
|
|
361
|
+
"See util_datetime module docstring for timezone handling details.",
|
|
362
|
+
location_str,
|
|
363
|
+
extra=extra,
|
|
364
|
+
)
|
|
365
|
+
|
|
366
|
+
|
|
367
|
+
__all__: list[str] = [
|
|
368
|
+
"ensure_timezone_aware",
|
|
369
|
+
"is_timezone_aware",
|
|
370
|
+
"validate_timezone_aware_with_context",
|
|
371
|
+
"warn_if_naive_datetime",
|
|
372
|
+
]
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
|
2
|
+
# Copyright (c) 2025 OmniNode Team
|
|
3
|
+
"""Database transaction context manager for asyncpg.
|
|
4
|
+
|
|
5
|
+
This module provides a transaction context manager that properly wraps
|
|
6
|
+
database operations in transactions with configurable isolation levels,
|
|
7
|
+
readonly mode, and statement timeouts.
|
|
8
|
+
|
|
9
|
+
Critical Insight - Row Locks Require Explicit Transactions:
|
|
10
|
+
When using ``SELECT ... FOR UPDATE`` or similar locking constructs,
|
|
11
|
+
the locks are **released immediately after the SELECT** unless
|
|
12
|
+
executed within an explicit transaction context.
|
|
13
|
+
|
|
14
|
+
This is a subtle but critical behavior of PostgreSQL and asyncpg:
|
|
15
|
+
without ``conn.transaction()``, each statement runs in auto-commit
|
|
16
|
+
mode, causing locks to be acquired and immediately released.
|
|
17
|
+
|
|
18
|
+
Example of INCORRECT usage (locks NOT maintained):
|
|
19
|
+
```python
|
|
20
|
+
async with pool.acquire() as conn:
|
|
21
|
+
# Lock is acquired but immediately released!
|
|
22
|
+
rows = await conn.fetch(
|
|
23
|
+
"SELECT * FROM queue WHERE status = 'pending' FOR UPDATE SKIP LOCKED"
|
|
24
|
+
)
|
|
25
|
+
# By this point, another worker could process the same row
|
|
26
|
+
await conn.execute("UPDATE queue SET status = 'processing' WHERE id = $1", row_id)
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Example of CORRECT usage (locks maintained):
|
|
30
|
+
```python
|
|
31
|
+
async with pool.acquire() as conn:
|
|
32
|
+
async with conn.transaction():
|
|
33
|
+
# Lock is held until transaction commits
|
|
34
|
+
rows = await conn.fetch(
|
|
35
|
+
"SELECT * FROM queue WHERE status = 'pending' FOR UPDATE SKIP LOCKED"
|
|
36
|
+
)
|
|
37
|
+
# Lock still held - safe to update
|
|
38
|
+
await conn.execute("UPDATE queue SET status = 'processing' WHERE id = $1", row_id)
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
The ``transaction_context()`` function in this module encapsulates
|
|
42
|
+
this pattern, ensuring locks are properly maintained throughout
|
|
43
|
+
the transaction scope.
|
|
44
|
+
|
|
45
|
+
Related Implementations:
|
|
46
|
+
- TransitionNotificationOutbox (runtime/transition_notification_outbox.py):
|
|
47
|
+
Uses explicit transaction wrapping for SELECT FOR UPDATE SKIP LOCKED
|
|
48
|
+
to safely process pending notifications with concurrent workers.
|
|
49
|
+
|
|
50
|
+
See Also:
|
|
51
|
+
- PostgreSQL locking documentation: https://www.postgresql.org/docs/current/explicit-locking.html
|
|
52
|
+
- asyncpg transaction documentation: https://magicstack.github.io/asyncpg/current/api/index.html#asyncpg.connection.Connection.transaction
|
|
53
|
+
|
|
54
|
+
Example:
|
|
55
|
+
>>> import asyncpg
|
|
56
|
+
>>> from omnibase_infra.utils import transaction_context
|
|
57
|
+
>>>
|
|
58
|
+
>>> async with transaction_context(pool) as conn:
|
|
59
|
+
... await conn.execute("INSERT INTO logs (message) VALUES ($1)", "Hello")
|
|
60
|
+
>>>
|
|
61
|
+
>>> # With isolation level and timeout
|
|
62
|
+
>>> async with transaction_context(
|
|
63
|
+
... pool,
|
|
64
|
+
... isolation="serializable",
|
|
65
|
+
... timeout=5.0,
|
|
66
|
+
... ) as conn:
|
|
67
|
+
... await conn.execute("UPDATE accounts SET balance = balance - 100 WHERE id = $1", account_id)
|
|
68
|
+
|
|
69
|
+
.. versionadded:: 0.10.0
|
|
70
|
+
Created as part of database utility consolidation.
|
|
71
|
+
"""
|
|
72
|
+
|
|
73
|
+
from __future__ import annotations
|
|
74
|
+
|
|
75
|
+
import logging
|
|
76
|
+
from collections.abc import AsyncIterator
|
|
77
|
+
from contextlib import asynccontextmanager
|
|
78
|
+
from uuid import UUID
|
|
79
|
+
|
|
80
|
+
import asyncpg
|
|
81
|
+
|
|
82
|
+
logger = logging.getLogger(__name__)
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
@asynccontextmanager
|
|
86
|
+
async def transaction_context(
|
|
87
|
+
pool: asyncpg.Pool,
|
|
88
|
+
*,
|
|
89
|
+
isolation: str = "read_committed",
|
|
90
|
+
readonly: bool = False,
|
|
91
|
+
deferrable: bool = False,
|
|
92
|
+
timeout: float | None = None,
|
|
93
|
+
correlation_id: UUID | None = None,
|
|
94
|
+
) -> AsyncIterator[asyncpg.Connection]:
|
|
95
|
+
"""Async context manager for database transactions.
|
|
96
|
+
|
|
97
|
+
Acquires a connection from the pool and starts a transaction with the
|
|
98
|
+
specified isolation level and options. The connection is yielded for
|
|
99
|
+
use within the transaction scope.
|
|
100
|
+
|
|
101
|
+
Critical - Row Locks:
|
|
102
|
+
This context manager ensures that row locks (e.g., ``FOR UPDATE``,
|
|
103
|
+
``FOR UPDATE SKIP LOCKED``) are maintained throughout the transaction.
|
|
104
|
+
Without explicit transaction wrapping, asyncpg operates in auto-commit
|
|
105
|
+
mode where locks are released immediately after each statement.
|
|
106
|
+
|
|
107
|
+
Isolation Levels:
|
|
108
|
+
- ``read_committed`` (default): Each statement sees a snapshot of
|
|
109
|
+
committed data as of the start of that statement.
|
|
110
|
+
- ``repeatable_read``: All statements in the transaction see a
|
|
111
|
+
snapshot of committed data as of the transaction start.
|
|
112
|
+
- ``serializable``: Strictest isolation - transactions execute as
|
|
113
|
+
if they were run serially.
|
|
114
|
+
|
|
115
|
+
Args:
|
|
116
|
+
pool: asyncpg connection pool to acquire connection from.
|
|
117
|
+
isolation: Transaction isolation level. One of "read_committed",
|
|
118
|
+
"repeatable_read", or "serializable". Defaults to "read_committed".
|
|
119
|
+
readonly: If True, the transaction is marked as read-only.
|
|
120
|
+
Attempting to modify data will raise an error. Defaults to False.
|
|
121
|
+
deferrable: If True, the transaction is deferrable. Only valid when
|
|
122
|
+
both ``isolation="serializable"`` and ``readonly=True``.
|
|
123
|
+
A deferrable transaction may block when first acquiring its
|
|
124
|
+
snapshot until it can execute without conflicting with other
|
|
125
|
+
serializable transactions. Defaults to False.
|
|
126
|
+
timeout: Statement timeout in seconds. If provided, sets
|
|
127
|
+
``statement_timeout`` for the duration of the transaction.
|
|
128
|
+
Statements exceeding this timeout will be cancelled.
|
|
129
|
+
Defaults to None (no timeout).
|
|
130
|
+
correlation_id: Optional correlation ID for logging. When provided,
|
|
131
|
+
transaction start and commit/rollback events are logged with
|
|
132
|
+
this ID for distributed tracing.
|
|
133
|
+
|
|
134
|
+
Yields:
|
|
135
|
+
asyncpg.Connection: The acquired connection within the transaction
|
|
136
|
+
context. Use this connection for all queries within the transaction.
|
|
137
|
+
|
|
138
|
+
Raises:
|
|
139
|
+
asyncpg.PostgresError: For database-level errors.
|
|
140
|
+
TimeoutError: If a statement exceeds the configured timeout.
|
|
141
|
+
|
|
142
|
+
Example:
|
|
143
|
+
Basic usage:
|
|
144
|
+
|
|
145
|
+
>>> async with transaction_context(pool) as conn:
|
|
146
|
+
... await conn.execute("INSERT INTO users (name) VALUES ($1)", "Alice")
|
|
147
|
+
... await conn.execute("INSERT INTO audit_log (action) VALUES ($1)", "user_created")
|
|
148
|
+
|
|
149
|
+
With SELECT FOR UPDATE:
|
|
150
|
+
|
|
151
|
+
>>> async with transaction_context(pool) as conn:
|
|
152
|
+
... # Lock is held until transaction commits
|
|
153
|
+
... rows = await conn.fetch(
|
|
154
|
+
... "SELECT * FROM jobs WHERE status = 'pending' LIMIT 1 FOR UPDATE SKIP LOCKED"
|
|
155
|
+
... )
|
|
156
|
+
... if rows:
|
|
157
|
+
... await conn.execute(
|
|
158
|
+
... "UPDATE jobs SET status = 'processing' WHERE id = $1",
|
|
159
|
+
... rows[0]["id"]
|
|
160
|
+
... )
|
|
161
|
+
|
|
162
|
+
With isolation and timeout:
|
|
163
|
+
|
|
164
|
+
>>> async with transaction_context(
|
|
165
|
+
... pool,
|
|
166
|
+
... isolation="serializable",
|
|
167
|
+
... readonly=True,
|
|
168
|
+
... timeout=10.0,
|
|
169
|
+
... correlation_id=uuid4(),
|
|
170
|
+
... ) as conn:
|
|
171
|
+
... totals = await conn.fetchval("SELECT SUM(amount) FROM transactions")
|
|
172
|
+
|
|
173
|
+
Note:
|
|
174
|
+
The transaction is automatically committed on successful exit from
|
|
175
|
+
the context manager, or rolled back if an exception is raised.
|
|
176
|
+
|
|
177
|
+
Warning:
|
|
178
|
+
Asyncpg exception handling: This utility lets asyncpg exceptions
|
|
179
|
+
propagate naturally without wrapping them in ONEX errors. This is
|
|
180
|
+
intentional as it keeps the utility simple and composable. Callers
|
|
181
|
+
should handle asyncpg exceptions as appropriate for their use case.
|
|
182
|
+
|
|
183
|
+
Related:
|
|
184
|
+
- OMN-1139: TransitionNotificationOutbox uses this pattern for
|
|
185
|
+
SELECT FOR UPDATE SKIP LOCKED with concurrent workers.
|
|
186
|
+
"""
|
|
187
|
+
async with pool.acquire() as conn:
|
|
188
|
+
# Log transaction start if correlation_id provided
|
|
189
|
+
if correlation_id is not None:
|
|
190
|
+
logger.debug(
|
|
191
|
+
"Starting database transaction",
|
|
192
|
+
extra={
|
|
193
|
+
"correlation_id": str(correlation_id),
|
|
194
|
+
"isolation": isolation,
|
|
195
|
+
"readonly": readonly,
|
|
196
|
+
"deferrable": deferrable,
|
|
197
|
+
"timeout": timeout,
|
|
198
|
+
},
|
|
199
|
+
)
|
|
200
|
+
|
|
201
|
+
try:
|
|
202
|
+
async with conn.transaction(
|
|
203
|
+
isolation=isolation,
|
|
204
|
+
readonly=readonly,
|
|
205
|
+
deferrable=deferrable,
|
|
206
|
+
):
|
|
207
|
+
# Set statement timeout if provided
|
|
208
|
+
# Uses LOCAL to scope timeout to this transaction only
|
|
209
|
+
if timeout is not None:
|
|
210
|
+
timeout_ms = int(timeout * 1000)
|
|
211
|
+
await conn.execute("SET LOCAL statement_timeout = $1", timeout_ms)
|
|
212
|
+
|
|
213
|
+
yield conn
|
|
214
|
+
|
|
215
|
+
# Log successful commit if correlation_id provided
|
|
216
|
+
if correlation_id is not None:
|
|
217
|
+
logger.debug(
|
|
218
|
+
"Database transaction committed",
|
|
219
|
+
extra={
|
|
220
|
+
"correlation_id": str(correlation_id),
|
|
221
|
+
},
|
|
222
|
+
)
|
|
223
|
+
|
|
224
|
+
except Exception:
|
|
225
|
+
# Log rollback if correlation_id provided
|
|
226
|
+
# Transaction is automatically rolled back by asyncpg
|
|
227
|
+
if correlation_id is not None:
|
|
228
|
+
logger.debug(
|
|
229
|
+
"Database transaction rolled back",
|
|
230
|
+
extra={
|
|
231
|
+
"correlation_id": str(correlation_id),
|
|
232
|
+
},
|
|
233
|
+
)
|
|
234
|
+
raise
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
__all__: list[str] = [
|
|
238
|
+
"transaction_context",
|
|
239
|
+
]
|