feat(observatory): add portable calculation profiles
This commit is contained in:
+204
-31
@@ -47,20 +47,38 @@ from k1link.observatory.m49_queue_binding import (
|
||||
M49QueueBindingError,
|
||||
M49RecordedQueueBindingService,
|
||||
)
|
||||
from k1link.observatory.portable_queue_binding import (
|
||||
PortableQueueBindingError,
|
||||
PortableRecordedQueueBindingService,
|
||||
)
|
||||
from k1link.observatory.portable_result_contract import (
|
||||
PortableCalculationProfileRegistry,
|
||||
PortableResultContractValidatorRegistry,
|
||||
)
|
||||
from k1link.observatory.portable_result_publisher import (
|
||||
resolve_published_portable_calculation_profile,
|
||||
)
|
||||
from k1link.observatory.portable_run_definitions import (
|
||||
PortableRunDefinitionRegistry,
|
||||
PortableRunDefinitionRegistryError,
|
||||
)
|
||||
from k1link.observatory.portable_setup_projection import (
|
||||
PORTABLE_LAB_V1_SETUP_ID,
|
||||
PortableLabV1SetupProjector,
|
||||
PortableSetupProjectionError,
|
||||
PortableSetupProjector,
|
||||
portable_calculation_profile_registry,
|
||||
)
|
||||
from k1link.observatory.portable_worker_integration import (
|
||||
PortableObservatoryWorkerIntegration,
|
||||
PortableWorkerIntegrationError,
|
||||
PortableWorkerStorageRoots,
|
||||
build_portable_observatory_worker_integration,
|
||||
portable_result_validator_registry,
|
||||
)
|
||||
from k1link.observatory.recorded_jobs import (
|
||||
ObservatoryRecordedJobQueue,
|
||||
ObservatoryRecordedQueueError,
|
||||
RecordedRunDefinitionRegistry,
|
||||
)
|
||||
from k1link.observatory.source_admission import RecordedK1SourceAdmissionService
|
||||
from k1link.sessions import (
|
||||
MaterializedRecording,
|
||||
RecordedCameraFrameService,
|
||||
@@ -73,6 +91,7 @@ from k1link.sessions import (
|
||||
SessionRecordingPreparationManager,
|
||||
SessionStore,
|
||||
)
|
||||
from k1link.sessions.models import SessionSummary
|
||||
from k1link.simulation.projects import SimulationProjectService, SimulationProjectStore
|
||||
from k1link.web.advanced_laboratory_api import build_advanced_laboratory_router
|
||||
from k1link.web.artifact_health_api import build_artifact_health_router
|
||||
@@ -261,6 +280,55 @@ plugin_catalog: DevicePluginCatalog = plugin_environment.catalog
|
||||
plugin_dispatcher: DevicePluginDispatcher = plugin_environment.dispatcher
|
||||
session_store = SessionStore(REPOSITORY_ROOT)
|
||||
|
||||
OBSERVATORY_PORTABLE_DEFINITION_REGISTRY: PortableRunDefinitionRegistry | None
|
||||
OBSERVATORY_PORTABLE_DEFINITION_REGISTRY_ERROR: str | None
|
||||
OBSERVATORY_PORTABLE_CALCULATION_PROFILES: PortableCalculationProfileRegistry | None
|
||||
OBSERVATORY_PORTABLE_RESULT_VALIDATORS: PortableResultContractValidatorRegistry | None
|
||||
try:
|
||||
OBSERVATORY_PORTABLE_DEFINITION_REGISTRY = PortableRunDefinitionRegistry.from_file(
|
||||
REPOSITORY_ROOT / "config" / "observatory-portable-run-definitions.json"
|
||||
)
|
||||
OBSERVATORY_PORTABLE_CALCULATION_PROFILES = portable_calculation_profile_registry(
|
||||
OBSERVATORY_PORTABLE_DEFINITION_REGISTRY
|
||||
)
|
||||
OBSERVATORY_PORTABLE_RESULT_VALIDATORS = portable_result_validator_registry(
|
||||
OBSERVATORY_PORTABLE_DEFINITION_REGISTRY
|
||||
)
|
||||
OBSERVATORY_PORTABLE_DEFINITION_REGISTRY_ERROR = None
|
||||
except (
|
||||
PortableRunDefinitionRegistryError,
|
||||
PortableWorkerIntegrationError,
|
||||
OSError,
|
||||
ValueError,
|
||||
) as exc:
|
||||
# Portable definitions are an optional observation-only slice. Registry
|
||||
# drift cannot affect K1, Simulation, legacy LAB, or the exact M49 binding.
|
||||
OBSERVATORY_PORTABLE_DEFINITION_REGISTRY = None
|
||||
OBSERVATORY_PORTABLE_CALCULATION_PROFILES = None
|
||||
OBSERVATORY_PORTABLE_RESULT_VALIDATORS = None
|
||||
OBSERVATORY_PORTABLE_DEFINITION_REGISTRY_ERROR = str(exc)
|
||||
|
||||
|
||||
def _resolve_observatory_calculation_profile(
|
||||
summary: SessionSummary,
|
||||
) -> dict[str, object] | None:
|
||||
if OBSERVATORY_LABORATORY_SETUP_REGISTRY is not None:
|
||||
legacy = OBSERVATORY_LABORATORY_SETUP_REGISTRY.observatory_calculation_profile(
|
||||
summary
|
||||
)
|
||||
if legacy is not None:
|
||||
return legacy
|
||||
if (
|
||||
OBSERVATORY_PORTABLE_DEFINITION_REGISTRY is None
|
||||
or OBSERVATORY_PORTABLE_CALCULATION_PROFILES is None
|
||||
):
|
||||
return None
|
||||
return resolve_published_portable_calculation_profile(
|
||||
summary,
|
||||
definitions=OBSERVATORY_PORTABLE_DEFINITION_REGISTRY,
|
||||
calculation_profiles=OBSERVATORY_PORTABLE_CALCULATION_PROFILES,
|
||||
)
|
||||
|
||||
|
||||
def _load_optional_observatory_worker_authentication(
|
||||
recorded_job_queue: ObservatoryRecordedJobQueue | None,
|
||||
@@ -299,9 +367,14 @@ try:
|
||||
REPOSITORY_ROOT / "config" / "observatory-m49-recorded-queue-binding.json"
|
||||
),
|
||||
)
|
||||
recorded_definitions = list(OBSERVATORY_RECORDED_BINDING_SERVICE.definitions.definitions)
|
||||
if OBSERVATORY_PORTABLE_DEFINITION_REGISTRY is not None:
|
||||
recorded_definitions.extend(
|
||||
OBSERVATORY_PORTABLE_DEFINITION_REGISTRY.ready_recorded_definitions()
|
||||
)
|
||||
OBSERVATORY_RECORDED_JOB_QUEUE = ObservatoryRecordedJobQueue(
|
||||
session_store.data_dir,
|
||||
definitions=OBSERVATORY_RECORDED_BINDING_SERVICE.definitions,
|
||||
definitions=RecordedRunDefinitionRegistry(tuple(recorded_definitions)),
|
||||
)
|
||||
OBSERVATORY_RECORDED_JOB_QUEUE_ERROR = None
|
||||
except (M49QueueBindingError, ObservatoryRecordedQueueError, OSError, ValueError) as exc:
|
||||
@@ -316,11 +389,14 @@ OBSERVATORY_WORKER_CLAIM_LEASE_READY = False
|
||||
OBSERVATORY_WORKER_VERIFIED_RESULT_PUBLISHER_READY = False
|
||||
OBSERVATORY_WORKER_PRODUCTION_API_ENABLED = False
|
||||
OBSERVATORY_WORKER_AUTHENTICATION: ObservatoryWorkerAuthentication | None
|
||||
OBSERVATORY_WORKER_AUTHENTICATION_ERROR: str | None
|
||||
OBSERVATORY_WORKER_API_ERROR: str | None
|
||||
OBSERVATORY_WORKER_AUTHENTICATION = None
|
||||
OBSERVATORY_WORKER_API_ERROR = (
|
||||
"Worker pull API is hard-disabled until claim leases and a verified "
|
||||
"Observatory result publisher are implemented and accepted"
|
||||
(
|
||||
OBSERVATORY_WORKER_AUTHENTICATION,
|
||||
OBSERVATORY_WORKER_AUTHENTICATION_ERROR,
|
||||
) = _load_optional_observatory_worker_authentication(
|
||||
OBSERVATORY_RECORDED_JOB_QUEUE,
|
||||
token_path=OBSERVATORY_WORKER_TOKEN_PATH,
|
||||
)
|
||||
simulation_project_store = SimulationProjectStore(session_store.data_dir)
|
||||
simulation_project_service = SimulationProjectService(simulation_project_store)
|
||||
@@ -336,37 +412,122 @@ session_recording_materializer = SessionRecordingMaterializer(
|
||||
session_recorded_media_inspector = RecordedMediaInspector(
|
||||
session_store.data_dir / "recorded-media-preparations"
|
||||
)
|
||||
OBSERVATORY_PORTABLE_SETUP_PROJECTOR: PortableLabV1SetupProjector | None
|
||||
OBSERVATORY_PORTABLE_WORKER_INTEGRATION: PortableObservatoryWorkerIntegration | None
|
||||
OBSERVATORY_PORTABLE_WORKER_INTEGRATION_ERROR: str | None
|
||||
OBSERVATORY_PORTABLE_WORKER_STORAGE_ROOTS: PortableWorkerStorageRoots | None = None
|
||||
try:
|
||||
if OBSERVATORY_PORTABLE_DEFINITION_REGISTRY is None:
|
||||
raise PortableWorkerIntegrationError(
|
||||
OBSERVATORY_PORTABLE_DEFINITION_REGISTRY_ERROR
|
||||
or "portable definition registry is unavailable"
|
||||
)
|
||||
if OBSERVATORY_PORTABLE_CALCULATION_PROFILES is None:
|
||||
raise PortableWorkerIntegrationError(
|
||||
"portable calculation profile registry is unavailable"
|
||||
)
|
||||
if OBSERVATORY_PORTABLE_RESULT_VALIDATORS is None:
|
||||
raise PortableWorkerIntegrationError(
|
||||
"portable result validator registry is unavailable"
|
||||
)
|
||||
if OBSERVATORY_RECORDED_JOB_QUEUE is None:
|
||||
raise PortableWorkerIntegrationError(
|
||||
OBSERVATORY_RECORDED_JOB_QUEUE_ERROR
|
||||
or "Observatory recorded-job queue is unavailable"
|
||||
)
|
||||
if session_artifact_gateway is None:
|
||||
raise PortableWorkerIntegrationError(
|
||||
"central artifact store is not configured"
|
||||
)
|
||||
if session_artifact_gateway.status().central_status != "ready":
|
||||
raise PortableWorkerIntegrationError(
|
||||
"central artifact store is unavailable"
|
||||
)
|
||||
OBSERVATORY_PORTABLE_WORKER_STORAGE_ROOTS = (
|
||||
PortableWorkerStorageRoots.from_environment(
|
||||
artifact_store_root=session_artifact_gateway.store.root,
|
||||
)
|
||||
)
|
||||
OBSERVATORY_PORTABLE_WORKER_INTEGRATION = (
|
||||
build_portable_observatory_worker_integration(
|
||||
queue=OBSERVATORY_RECORDED_JOB_QUEUE,
|
||||
session_store=session_store,
|
||||
media_inspector=session_recorded_media_inspector,
|
||||
definitions=OBSERVATORY_PORTABLE_DEFINITION_REGISTRY,
|
||||
artifact_store=session_artifact_gateway.store,
|
||||
calculation_profiles=OBSERVATORY_PORTABLE_CALCULATION_PROFILES,
|
||||
validators=OBSERVATORY_PORTABLE_RESULT_VALIDATORS,
|
||||
source_cas_root=(
|
||||
OBSERVATORY_PORTABLE_WORKER_STORAGE_ROOTS.source_cas_root
|
||||
),
|
||||
result_staging_root=(
|
||||
OBSERVATORY_PORTABLE_WORKER_STORAGE_ROOTS.result_staging_root
|
||||
),
|
||||
)
|
||||
)
|
||||
OBSERVATORY_PORTABLE_WORKER_INTEGRATION_ERROR = None
|
||||
except (PortableWorkerIntegrationError, OSError, ValueError) as exc:
|
||||
# Constructing this dormant foundation does not enable the Worker router.
|
||||
# Failure remains isolated from K1, Simulation and legacy LAB.
|
||||
OBSERVATORY_PORTABLE_WORKER_INTEGRATION = None
|
||||
OBSERVATORY_PORTABLE_WORKER_INTEGRATION_ERROR = str(exc)
|
||||
OBSERVATORY_WORKER_API_ERROR = (
|
||||
"Worker pull API is hard-disabled pending sealed installed executors, "
|
||||
"a configured Worker credential, explicit integration acceptance and the "
|
||||
"production gate"
|
||||
+ (
|
||||
""
|
||||
if OBSERVATORY_WORKER_AUTHENTICATION_ERROR is None
|
||||
else (
|
||||
"; authentication unavailable: "
|
||||
f"{OBSERVATORY_WORKER_AUTHENTICATION_ERROR}"
|
||||
)
|
||||
)
|
||||
+ (
|
||||
""
|
||||
if OBSERVATORY_PORTABLE_WORKER_INTEGRATION_ERROR is None
|
||||
else f"; integration unavailable: {OBSERVATORY_PORTABLE_WORKER_INTEGRATION_ERROR}"
|
||||
)
|
||||
)
|
||||
OBSERVATORY_WORKER_DISPATCH_READY = (
|
||||
OBSERVATORY_WORKER_PRODUCTION_API_ENABLED
|
||||
and OBSERVATORY_WORKER_CLAIM_LEASE_READY
|
||||
and OBSERVATORY_WORKER_VERIFIED_RESULT_PUBLISHER_READY
|
||||
and OBSERVATORY_RECORDED_JOB_QUEUE is not None
|
||||
and OBSERVATORY_WORKER_AUTHENTICATION is not None
|
||||
and OBSERVATORY_PORTABLE_WORKER_INTEGRATION is not None
|
||||
)
|
||||
OBSERVATORY_PORTABLE_BINDING_SERVICE: PortableRecordedQueueBindingService | None
|
||||
OBSERVATORY_PORTABLE_SETUP_PROJECTOR: PortableSetupProjector | None
|
||||
OBSERVATORY_PORTABLE_SETUP_PROJECTOR_ERROR: str | None
|
||||
try:
|
||||
portable_definition_registry = PortableRunDefinitionRegistry.from_file(
|
||||
REPOSITORY_ROOT / "config" / "observatory-portable-run-definitions.json"
|
||||
)
|
||||
portable_lab_v1_definition = next(
|
||||
definition
|
||||
for definition in portable_definition_registry.definitions
|
||||
if definition.setup_id == PORTABLE_LAB_V1_SETUP_ID
|
||||
)
|
||||
portable_source_capability_service = RecordedK1SourceAdmissionService(
|
||||
if OBSERVATORY_PORTABLE_DEFINITION_REGISTRY is None:
|
||||
raise PortableSetupProjectionError(
|
||||
OBSERVATORY_PORTABLE_DEFINITION_REGISTRY_ERROR
|
||||
or "portable definition registry is unavailable"
|
||||
)
|
||||
OBSERVATORY_PORTABLE_BINDING_SERVICE = PortableRecordedQueueBindingService(
|
||||
data_dir=session_store.data_dir,
|
||||
session_store=session_store,
|
||||
media_inspector=session_recorded_media_inspector,
|
||||
requirements=portable_lab_v1_definition.to_source_admission_requirements(),
|
||||
definitions=OBSERVATORY_PORTABLE_DEFINITION_REGISTRY,
|
||||
queue=OBSERVATORY_RECORDED_JOB_QUEUE,
|
||||
)
|
||||
OBSERVATORY_PORTABLE_SETUP_PROJECTOR = PortableLabV1SetupProjector(
|
||||
registry=portable_definition_registry,
|
||||
capability_probe=portable_source_capability_service,
|
||||
OBSERVATORY_PORTABLE_SETUP_PROJECTOR = PortableSetupProjector(
|
||||
registry=OBSERVATORY_PORTABLE_DEFINITION_REGISTRY,
|
||||
capability_probe=OBSERVATORY_PORTABLE_BINDING_SERVICE,
|
||||
dispatch_available=OBSERVATORY_WORKER_DISPATCH_READY,
|
||||
)
|
||||
OBSERVATORY_PORTABLE_SETUP_PROJECTOR_ERROR = None
|
||||
except (
|
||||
PortableQueueBindingError,
|
||||
PortableRunDefinitionRegistryError,
|
||||
PortableSetupProjectionError,
|
||||
OSError,
|
||||
StopIteration,
|
||||
ValueError,
|
||||
) as exc:
|
||||
# Portable LAB V1 is an optional observation-only slice. A drifted
|
||||
# Portable setup execution is an optional observation-only slice. A drifted
|
||||
# registry cannot affect K1, Simulation, legacy LAB, or the exact M49 queue.
|
||||
OBSERVATORY_PORTABLE_BINDING_SERVICE = None
|
||||
OBSERVATORY_PORTABLE_SETUP_PROJECTOR = None
|
||||
OBSERVATORY_PORTABLE_SETUP_PROJECTOR_ERROR = str(exc)
|
||||
_ffmpeg = _resolve_media_tool("ffmpeg")
|
||||
@@ -829,6 +990,14 @@ app.include_router(
|
||||
perception_overlay_provider=session_perception_overlay_store,
|
||||
perception_media_provider=session_perception_epoch_store,
|
||||
point_color_renderers=plugin_environment.point_color_renderers,
|
||||
lab_calculation_profile_resolver=(
|
||||
None
|
||||
if (
|
||||
OBSERVATORY_LABORATORY_SETUP_REGISTRY is None
|
||||
and OBSERVATORY_PORTABLE_DEFINITION_REGISTRY is None
|
||||
)
|
||||
else _resolve_observatory_calculation_profile
|
||||
),
|
||||
)
|
||||
)
|
||||
app.include_router(
|
||||
@@ -843,19 +1012,23 @@ app.include_router(
|
||||
recorded_job_queue_error=OBSERVATORY_RECORDED_JOB_QUEUE_ERROR,
|
||||
portable_setup_projector=OBSERVATORY_PORTABLE_SETUP_PROJECTOR,
|
||||
portable_setup_projector_error=OBSERVATORY_PORTABLE_SETUP_PROJECTOR_ERROR,
|
||||
portable_binding_service=OBSERVATORY_PORTABLE_BINDING_SERVICE,
|
||||
)
|
||||
)
|
||||
if (
|
||||
OBSERVATORY_WORKER_PRODUCTION_API_ENABLED
|
||||
and OBSERVATORY_WORKER_CLAIM_LEASE_READY
|
||||
and OBSERVATORY_WORKER_VERIFIED_RESULT_PUBLISHER_READY
|
||||
and OBSERVATORY_RECORDED_JOB_QUEUE is not None
|
||||
and OBSERVATORY_WORKER_AUTHENTICATION is not None
|
||||
):
|
||||
if OBSERVATORY_WORKER_DISPATCH_READY:
|
||||
assert OBSERVATORY_RECORDED_JOB_QUEUE is not None
|
||||
assert OBSERVATORY_WORKER_AUTHENTICATION is not None
|
||||
assert OBSERVATORY_PORTABLE_WORKER_INTEGRATION is not None
|
||||
app.include_router(
|
||||
build_observatory_worker_router(
|
||||
OBSERVATORY_RECORDED_JOB_QUEUE,
|
||||
authentication=OBSERVATORY_WORKER_AUTHENTICATION,
|
||||
artifact_transport=(
|
||||
OBSERVATORY_PORTABLE_WORKER_INTEGRATION.artifact_transport
|
||||
),
|
||||
result_publisher=(
|
||||
OBSERVATORY_PORTABLE_WORKER_INTEGRATION.result_publisher
|
||||
),
|
||||
)
|
||||
)
|
||||
app.include_router(
|
||||
|
||||
Reference in New Issue
Block a user