feat: prepare ARR for controlled public deployment
This commit is contained in:
129
arr_web/processing_runtime.py
Normal file
129
arr_web/processing_runtime.py
Normal file
@@ -0,0 +1,129 @@
|
||||
"""Production composition for XML upload and Open Agent dispatch."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
from typing import Any, Callable, Optional
|
||||
|
||||
from agent_integration import (
|
||||
AgentConfig,
|
||||
OpenAgentAPIClient,
|
||||
OpenAgentService,
|
||||
SQLiteSessionStore,
|
||||
)
|
||||
from arr_ingestion.postgres import DatabaseConfig
|
||||
from arr_ingestion.direct_postgres import PostgresDirectIngestionRepository
|
||||
from arr_processing.config import ResultVerificationConfig
|
||||
from arr_processing.open_agent import OpenAgentProcessingTransport
|
||||
from arr_processing.postgres import PostgresProcessingState, ProcessingDatabaseConfig
|
||||
from arr_processing.runner import ProcessingRunner
|
||||
from arr_processing.source_message import OssProcessingMessageBuilder
|
||||
from arr_storage.aliyun_oss_v2 import AliyunOssConfig, AliyunOssV2Client
|
||||
from arr_storage.contracts import ObjectKeyPolicy
|
||||
from arr_storage.remote import CloudObjectBackend
|
||||
from arr_storage.store import ManagedObjectStore
|
||||
from arr_web.agent_writeback_runtime import load_processor_policy
|
||||
from arr_web.services import ObjectStoreUploadCoordinator
|
||||
|
||||
|
||||
@dataclass
|
||||
class ProcessingInputRuntime:
|
||||
coordinator: ObjectStoreUploadCoordinator
|
||||
api_client: OpenAgentAPIClient
|
||||
session_store: SQLiteSessionStore
|
||||
oss_client: AliyunOssV2Client
|
||||
|
||||
def close(self) -> None:
|
||||
errors = []
|
||||
for close in (
|
||||
self.api_client.close,
|
||||
self.session_store.close,
|
||||
self.oss_client.close,
|
||||
):
|
||||
try:
|
||||
close()
|
||||
except Exception as error: # pragma: no cover - best-effort shutdown
|
||||
errors.append(error)
|
||||
if errors:
|
||||
raise errors[0]
|
||||
|
||||
|
||||
def compose_oss_processing_input(
|
||||
*,
|
||||
project_root: Path,
|
||||
connect: Optional[Callable[[str], Any]] = None,
|
||||
) -> ProcessingInputRuntime:
|
||||
oss_client: Optional[AliyunOssV2Client] = None
|
||||
session_store: Optional[SQLiteSessionStore] = None
|
||||
api_client: Optional[OpenAgentAPIClient] = None
|
||||
try:
|
||||
agent_config = AgentConfig.from_env()
|
||||
verification = ResultVerificationConfig.from_environment()
|
||||
processor_policy = load_processor_policy(project_root)
|
||||
oss_config = AliyunOssConfig.from_environment()
|
||||
oss_client = AliyunOssV2Client(oss_config)
|
||||
oss_client.assert_immutable_writes_supported()
|
||||
object_store = ManagedObjectStore(
|
||||
CloudObjectBackend(oss_client),
|
||||
ObjectKeyPolicy(os.environ.get("ARR_OBJECT_PREFIX", "arr")),
|
||||
)
|
||||
processing_config = (
|
||||
ProcessingDatabaseConfig("controlled")
|
||||
if connect is not None
|
||||
else ProcessingDatabaseConfig.from_environment()
|
||||
)
|
||||
ingestion_config = (
|
||||
DatabaseConfig("controlled")
|
||||
if connect is not None
|
||||
else DatabaseConfig.from_environment()
|
||||
)
|
||||
session_store = SQLiteSessionStore(agent_config.session_db)
|
||||
if agent_config.api_key is None:
|
||||
raise ValueError("Agent API key is unavailable")
|
||||
api_client = OpenAgentAPIClient(
|
||||
base_url=agent_config.base_url,
|
||||
api_key=agent_config.api_key,
|
||||
auth_mode=agent_config.auth_mode,
|
||||
timeout=agent_config.timeout_seconds,
|
||||
connect_timeout=agent_config.connect_timeout_seconds,
|
||||
)
|
||||
service = OpenAgentService(api_client, session_store)
|
||||
processing_state = PostgresProcessingState(processing_config, connect=connect)
|
||||
runner = ProcessingRunner(
|
||||
OpenAgentProcessingTransport(
|
||||
service,
|
||||
message_builder=OssProcessingMessageBuilder(
|
||||
oss_config,
|
||||
processing_state,
|
||||
).message,
|
||||
),
|
||||
processing_state,
|
||||
verification.verifier(),
|
||||
)
|
||||
coordinator = ObjectStoreUploadCoordinator(
|
||||
object_store=object_store,
|
||||
ingestion_repository=PostgresDirectIngestionRepository(
|
||||
ingestion_config,
|
||||
connect=connect,
|
||||
),
|
||||
processing_starter=runner,
|
||||
processor_version=processor_policy.processor_version,
|
||||
rule_set_sha256=processor_policy.rule_set_sha256,
|
||||
)
|
||||
return ProcessingInputRuntime(
|
||||
coordinator,
|
||||
api_client,
|
||||
session_store,
|
||||
oss_client,
|
||||
)
|
||||
except Exception:
|
||||
for resource in (api_client, session_store, oss_client):
|
||||
if resource is None:
|
||||
continue
|
||||
try:
|
||||
resource.close()
|
||||
except Exception:
|
||||
pass
|
||||
raise
|
||||
Reference in New Issue
Block a user