feat(core): define durable datasource artifact contract
This commit is contained in:
@@ -23,6 +23,7 @@ CAPABILITY_DATASOURCE_CATALOGUE = "datasources.catalogue"
|
||||
CAPABILITY_DATASOURCE_LIFECYCLE = "datasources.lifecycle"
|
||||
CAPABILITY_DATASOURCE_PUBLICATION = "datasources.publication"
|
||||
CAPABILITY_DATASOURCE_ORIGINS = "connectors.datasourceOrigins"
|
||||
CAPABILITY_DATASOURCE_ARTIFACT_BACKENDS = "datasources.artifactBackends"
|
||||
|
||||
DatasourceMode = Literal["live", "cached", "static"]
|
||||
DatasourceKind = Literal[
|
||||
@@ -37,6 +38,11 @@ DatasourceKind = Literal[
|
||||
]
|
||||
DatasourceShape = Literal["tabular", "document", "binary", "directory", "stream"]
|
||||
DatasourceConsistency = Literal["current", "live", "frozen"]
|
||||
DatasourcePublicationStatus = Literal[
|
||||
"published",
|
||||
"published_with_warnings",
|
||||
"review_required",
|
||||
]
|
||||
|
||||
|
||||
class DatasourceError(ValueError):
|
||||
@@ -309,12 +315,73 @@ class DatasourceStageInput:
|
||||
governance: DatasourceGovernance | None = None
|
||||
|
||||
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class DatasourceArtifactReference:
|
||||
"""Immutable provider-neutral reference to a durable tabular payload.
|
||||
|
||||
The producer owns creation of the payload. Datasources pins its locator,
|
||||
checksum and declared shape without importing the artifact-owning module;
|
||||
a configured payload backend verifies integrity and provides bounded reads.
|
||||
"""
|
||||
|
||||
backend: str
|
||||
locator: str
|
||||
checksum: str
|
||||
row_count: int
|
||||
byte_count: int
|
||||
schema: tuple[DatasourceField, ...]
|
||||
fingerprint: str
|
||||
media_type: str = "application/x-ndjson"
|
||||
checkpoint: Mapping[str, object] = field(default_factory=dict)
|
||||
metadata: Mapping[str, object] = field(default_factory=dict)
|
||||
validation: Mapping[str, object] = field(default_factory=dict)
|
||||
|
||||
|
||||
@runtime_checkable
|
||||
class DatasourceArtifactBackend(Protocol):
|
||||
"""Storage-module boundary for immutable artifact-backed tabular data."""
|
||||
|
||||
backend: str
|
||||
|
||||
def verify(
|
||||
self,
|
||||
session: object,
|
||||
*,
|
||||
tenant_id: str,
|
||||
artifact: DatasourceArtifactReference,
|
||||
) -> None: ...
|
||||
|
||||
def read_rows(
|
||||
self,
|
||||
session: object,
|
||||
*,
|
||||
tenant_id: str,
|
||||
artifact: DatasourceArtifactReference,
|
||||
offset: int,
|
||||
limit: int,
|
||||
) -> Sequence[Mapping[str, object]]: ...
|
||||
|
||||
def delete(
|
||||
self,
|
||||
session: object,
|
||||
*,
|
||||
tenant_id: str,
|
||||
artifact: DatasourceArtifactReference,
|
||||
) -> None: ...
|
||||
|
||||
|
||||
@runtime_checkable
|
||||
class DatasourceArtifactBackendProvider(Protocol):
|
||||
def artifact_backends(self) -> Sequence[DatasourceArtifactBackend]: ...
|
||||
|
||||
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class DatasourcePublicationRequest:
|
||||
producer_module: str
|
||||
producer_run_ref: str
|
||||
idempotency_key: str
|
||||
rows: tuple[Mapping[str, object], ...]
|
||||
rows: tuple[Mapping[str, object], ...] | None = None
|
||||
artifact: DatasourceArtifactReference | None = None
|
||||
target_datasource_ref: str | None = None
|
||||
name: str | None = None
|
||||
source_name: str | None = None
|
||||
@@ -331,7 +398,7 @@ class DatasourcePublicationRequest:
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class DatasourcePublicationResult:
|
||||
ref: str
|
||||
status: str
|
||||
status: DatasourcePublicationStatus
|
||||
datasource: DatasourceDescriptor
|
||||
materialization: DatasourceMaterialization
|
||||
replayed: bool = False
|
||||
@@ -564,6 +631,17 @@ def datasource_catalogue(registry: object | None) -> DatasourceCatalogueProvider
|
||||
return capability if isinstance(capability, DatasourceCatalogueProvider) else None
|
||||
|
||||
|
||||
def datasource_artifact_backend_provider(
|
||||
registry: object | None,
|
||||
) -> DatasourceArtifactBackendProvider | None:
|
||||
capability = _capability(registry, CAPABILITY_DATASOURCE_ARTIFACT_BACKENDS)
|
||||
return (
|
||||
capability
|
||||
if isinstance(capability, DatasourceArtifactBackendProvider)
|
||||
else None
|
||||
)
|
||||
|
||||
|
||||
def datasource_lifecycle(registry: object | None) -> DatasourceLifecycleProvider | None:
|
||||
capability = _capability(registry, CAPABILITY_DATASOURCE_LIFECYCLE)
|
||||
return capability if isinstance(capability, DatasourceLifecycleProvider) else None
|
||||
@@ -613,9 +691,14 @@ def _governance_mapping(value: object) -> Mapping[str, object]:
|
||||
|
||||
__all__ = [
|
||||
"CAPABILITY_DATASOURCE_CATALOGUE",
|
||||
"CAPABILITY_DATASOURCE_ARTIFACT_BACKENDS",
|
||||
"CAPABILITY_DATASOURCE_LIFECYCLE",
|
||||
"CAPABILITY_DATASOURCE_ORIGINS",
|
||||
"CAPABILITY_DATASOURCE_PUBLICATION",
|
||||
"DatasourceAccessError",
|
||||
"DatasourceArtifactReference",
|
||||
"DatasourceArtifactBackend",
|
||||
"DatasourceArtifactBackendProvider",
|
||||
"DatasourceCatalogueProvider",
|
||||
"DatasourceConsistency",
|
||||
"DatasourceDescriptor",
|
||||
@@ -631,6 +714,10 @@ __all__ = [
|
||||
"DatasourceOriginProvider",
|
||||
"DatasourceOriginReadRequest",
|
||||
"DatasourceOriginReadResult",
|
||||
"DatasourcePublicationProvider",
|
||||
"DatasourcePublicationRequest",
|
||||
"DatasourcePublicationResult",
|
||||
"DatasourcePublicationStatus",
|
||||
"DatasourceReadRequest",
|
||||
"DatasourceReadResult",
|
||||
"DatasourceShape",
|
||||
@@ -639,6 +726,8 @@ __all__ = [
|
||||
"DatasourceUnavailableError",
|
||||
"DatasourceValidationError",
|
||||
"datasource_catalogue",
|
||||
"datasource_artifact_backend_provider",
|
||||
"datasource_lifecycle",
|
||||
"datasource_origins",
|
||||
"datasource_publication",
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user