feat(datasources): publish durable artifact outputs
Module Package Release / publish-packages (push) Successful in 12s
Module Package Release / publish-packages (push) Successful in 12s
This commit is contained in:
@@ -9,6 +9,9 @@ from sqlalchemy import delete, func, insert, select
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from govoplan_core.core.datasources import (
|
||||
DatasourceArtifactBackend,
|
||||
DatasourceArtifactReference,
|
||||
DatasourceField,
|
||||
DatasourceUnavailableError,
|
||||
DatasourceValidationError,
|
||||
)
|
||||
@@ -116,6 +119,91 @@ class DatabaseRowsPayloadBackend:
|
||||
)
|
||||
|
||||
|
||||
class ExternalArtifactPayloadBackend:
|
||||
"""Adapts a Core artifact backend to persisted Datasources payload rows."""
|
||||
|
||||
def __init__(self, backend: DatasourceArtifactBackend) -> None:
|
||||
self._backend = backend
|
||||
self.backend = backend.backend
|
||||
|
||||
def read_rows(
|
||||
self,
|
||||
session: Session,
|
||||
payload: DatasourcePayloadRecord,
|
||||
*,
|
||||
offset: int,
|
||||
limit: int,
|
||||
) -> Sequence[Mapping[str, object]]:
|
||||
return self._backend.read_rows(
|
||||
session,
|
||||
tenant_id=payload.tenant_id,
|
||||
artifact=_artifact_from_payload(payload),
|
||||
offset=offset,
|
||||
limit=limit,
|
||||
)
|
||||
|
||||
def verify(
|
||||
self,
|
||||
session: Session,
|
||||
payload: DatasourcePayloadRecord,
|
||||
) -> None:
|
||||
self._backend.verify(
|
||||
session,
|
||||
tenant_id=payload.tenant_id,
|
||||
artifact=_artifact_from_payload(payload),
|
||||
)
|
||||
|
||||
def delete(
|
||||
self,
|
||||
session: Session,
|
||||
payload: DatasourcePayloadRecord,
|
||||
) -> None:
|
||||
self._backend.delete(
|
||||
session,
|
||||
tenant_id=payload.tenant_id,
|
||||
artifact=_artifact_from_payload(payload),
|
||||
)
|
||||
|
||||
|
||||
def _artifact_from_payload(
|
||||
payload: DatasourcePayloadRecord,
|
||||
) -> DatasourceArtifactReference:
|
||||
metadata = dict(payload.metadata_)
|
||||
raw_schema = metadata.get("artifact_schema")
|
||||
schema = tuple(
|
||||
DatasourceField(
|
||||
name=str(item.get("name") or ""),
|
||||
data_type=str(item.get("data_type") or "unknown"),
|
||||
nullable=bool(item.get("nullable", True)),
|
||||
)
|
||||
for item in raw_schema
|
||||
if isinstance(item, Mapping)
|
||||
) if isinstance(raw_schema, Sequence) and not isinstance(
|
||||
raw_schema, (str, bytes)
|
||||
) else ()
|
||||
return DatasourceArtifactReference(
|
||||
backend=payload.backend,
|
||||
locator=str(payload.locator or ""),
|
||||
checksum=payload.checksum,
|
||||
row_count=payload.row_count,
|
||||
byte_count=payload.byte_count,
|
||||
schema=schema,
|
||||
fingerprint=str(metadata.get("publication_fingerprint") or ""),
|
||||
media_type=payload.media_type,
|
||||
checkpoint=dict(payload.checkpoint_),
|
||||
metadata={
|
||||
str(key): value
|
||||
for key, value in metadata.items()
|
||||
if key not in {"artifact_schema", "artifact_validation"}
|
||||
},
|
||||
validation=(
|
||||
dict(metadata.get("artifact_validation"))
|
||||
if isinstance(metadata.get("artifact_validation"), Mapping)
|
||||
else {}
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
class PayloadBackendRegistry:
|
||||
def __init__(
|
||||
self,
|
||||
@@ -363,6 +451,7 @@ __all__ = [
|
||||
"DATABASE_ROWS_BACKEND",
|
||||
"DatabaseRowsPayloadBackend",
|
||||
"DatasourcePayloadBackend",
|
||||
"ExternalArtifactPayloadBackend",
|
||||
"PayloadBackendRegistry",
|
||||
"create_database_rows_payload",
|
||||
"create_external_payload_reference",
|
||||
|
||||
Reference in New Issue
Block a user