feat: initialize governed datasources module

This commit is contained in:
2026-07-28 12:43:02 +02:00
commit 1cb6228442
37 changed files with 5910 additions and 0 deletions

View File

@@ -0,0 +1,181 @@
from __future__ import annotations
from typing import Any, Literal
from pydantic import BaseModel, Field, model_validator
DatasourceModeValue = Literal["live", "cached", "static"]
DatasourceKindValue = Literal[
"upload",
"database",
"http",
"rest",
"directory",
"file",
"feed",
"custom",
]
DatasourceShapeValue = Literal["tabular", "document", "binary", "directory", "stream"]
class DatasourceFieldResponse(BaseModel):
name: str
data_type: str
nullable: bool
class DatasourceResponse(BaseModel):
ref: str
source_name: str
name: str
description: str | None
kind: DatasourceKindValue
mode: DatasourceModeValue
shape: DatasourceShapeValue
status: str
provider: str | None
provider_ref: str | None
fields: list[DatasourceFieldResponse] = Field(alias="schema")
schema_version: str
fingerprint: str
current_materialization_ref: str | None
row_count: int | None
byte_count: int | None
updated_at: str | None
capabilities: list[str]
provenance: dict[str, Any]
metadata: dict[str, Any]
class DatasourceListResponse(BaseModel):
datasources: list[DatasourceResponse]
class DatasourceMaterializationResponse(BaseModel):
ref: str
datasource_ref: str
revision: int
state: str
fingerprint: str
fields: list[DatasourceFieldResponse] = Field(alias="schema")
row_count: int | None
byte_count: int | None
frozen_at: str | None
frozen_label: str | None
source_timestamp: str | None
created_at: str | None
provenance: dict[str, Any]
metadata: dict[str, Any]
class DatasourceMaterializationListResponse(BaseModel):
materializations: list[DatasourceMaterializationResponse]
class DatasourceStageResponse(BaseModel):
ref: str
name: str
source_name: str
kind: DatasourceKindValue
mode: DatasourceModeValue
shape: DatasourceShapeValue
state: str
target_datasource_ref: str | None
fingerprint: str
fields: list[DatasourceFieldResponse] = Field(alias="schema")
row_count: int | None
byte_count: int | None
validation: dict[str, Any]
created_at: str | None
promoted_at: str | None
promoted_materialization_ref: str | None
provenance: dict[str, Any]
metadata: dict[str, Any]
class DatasourceStageListResponse(BaseModel):
stages: list[DatasourceStageResponse]
class DatasourceStageCreateRequest(BaseModel):
name: str = Field(min_length=1, max_length=300)
source_name: str = Field(min_length=1, max_length=120)
description: str | None = Field(default=None, max_length=4_000)
kind: DatasourceKindValue = "upload"
mode: Literal["static", "cached"] = "static"
shape: Literal["tabular"] = "tabular"
format: Literal["json", "csv"] = "json"
rows: list[dict[str, Any]] | None = Field(default=None, max_length=10_000)
csv_text: str | None = Field(default=None, max_length=5_000_000)
delimiter: Literal[",", ";", "\t", "|"] = ","
target_datasource_ref: str | None = None
provenance: dict[str, Any] = Field(default_factory=dict)
metadata: dict[str, Any] = Field(default_factory=dict)
@model_validator(mode="after")
def matching_payload(self) -> "DatasourceStageCreateRequest":
if self.format == "json" and self.rows is None:
raise ValueError("JSON stages require rows.")
if self.format == "csv" and not self.csv_text:
raise ValueError("CSV stages require csv_text.")
return self
class DatasourceStagePromoteRequest(BaseModel):
freeze: bool = False
frozen_label: str | None = Field(default=None, max_length=300)
class DatasourceStagePromoteResponse(BaseModel):
datasource: DatasourceResponse
materialization: DatasourceMaterializationResponse
class DatasourceOriginResponse(BaseModel):
ref: str
source_name: str
name: str
description: str | None
kind: DatasourceKindValue
shape: DatasourceShapeValue
supported_modes: list[DatasourceModeValue]
provider: str
fields: list[DatasourceFieldResponse] = Field(alias="schema")
schema_version: str
fingerprint: str
row_count: int | None
byte_count: int | None
updated_at: str | None
capabilities: list[str]
metadata: dict[str, Any]
class DatasourceOriginListResponse(BaseModel):
available: bool
origins: list[DatasourceOriginResponse]
class DatasourceOriginRegisterRequest(BaseModel):
origin_ref: str = Field(min_length=1, max_length=500)
name: str = Field(min_length=1, max_length=300)
source_name: str = Field(min_length=1, max_length=120)
mode: Literal["live", "cached"]
description: str | None = Field(default=None, max_length=4_000)
class DatasourcePreviewResponse(BaseModel):
datasource: DatasourceResponse
rows: list[dict[str, Any]]
total_rows: int
truncated: bool
materialization: DatasourceMaterializationResponse | None
class DatasourceFreezeRequest(BaseModel):
label: str | None = Field(default=None, max_length=300)
class DatasourceRetireResponse(BaseModel):
retired: bool
datasource_ref: str