Bound connector source previews

This commit is contained in:
2026-08-04 12:05:27 +02:00
parent c33380b957
commit 20146ef8fe
8 changed files with 334 additions and 11 deletions
+46
View File
@@ -16,6 +16,7 @@ from govoplan_core.core.tabular_sources import (
TabularSourceAccessError,
TabularSourceError,
TabularSourceNotFoundError,
TabularSourceUnavailableError,
)
from govoplan_core.core.feeds import (
FeedCapabilityError,
@@ -38,6 +39,9 @@ from govoplan_connectors.backend.schemas import (
SanctionsSourceResponse,
SnapshotCreateRequest,
TabularColumnResponse,
TabularHealthResponse,
TabularPreviewDiagnosticResponse,
TabularPushdownResponse,
TabularSourceDeleteResponse,
TabularSourceListResponse,
TabularSourcePreviewResponse,
@@ -85,6 +89,11 @@ def _http_error(exc: TabularSourceError) -> HTTPException:
return HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(exc))
if isinstance(exc, TabularSourceAccessError):
return HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail=str(exc))
if isinstance(exc, TabularSourceUnavailableError):
return HTTPException(
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
detail=str(exc),
)
return HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_CONTENT, detail=str(exc))
@@ -377,6 +386,8 @@ def api_preview_tabular_source(
source_id: str,
limit: int = Query(default=100, ge=1, le=500),
offset: int = Query(default=0, ge=0),
max_bytes: int = Query(default=1_000_000, ge=2, le=5_000_000),
timeout_ms: int = Query(default=2_000, ge=1, le=10_000),
session: Session = Depends(get_session),
principal: ApiPrincipal = Depends(get_api_principal),
) -> TabularSourcePreviewResponse:
@@ -389,6 +400,8 @@ def api_preview_tabular_source(
source_ref=f"snapshot:{source_id}",
limit=limit,
offset=offset,
max_bytes=max_bytes,
timeout_ms=timeout_ms,
),
)
except TabularSourceError as exc:
@@ -398,6 +411,20 @@ def api_preview_tabular_source(
rows=[dict(row) for row in result.rows],
total_rows=result.total_rows,
truncated=result.truncated,
returned_bytes=result.returned_bytes,
elapsed_ms=result.elapsed_ms,
effective_row_limit=result.effective_row_limit,
effective_byte_limit=result.effective_byte_limit,
effective_timeout_ms=result.effective_timeout_ms,
diagnostics=[
TabularPreviewDiagnosticResponse(
severity=item.severity,
code=item.code,
message=item.message,
details=dict(item.details),
)
for item in result.diagnostics
],
)
@@ -604,6 +631,25 @@ def _source_response(source: TabularSource) -> TabularSourceResponse:
updated_at=source.updated_at.isoformat() if source.updated_at else None,
capabilities=list(source.capabilities),
metadata=dict(source.metadata),
source_mode=source.source_mode,
pushdown=TabularPushdownResponse(
projections=source.pushdown.projections,
pagination=source.pushdown.pagination,
filters=list(source.pushdown.filters),
aggregations=list(source.pushdown.aggregations),
sorting=list(source.pushdown.sorting),
),
health=TabularHealthResponse(
status=source.health.status,
code=source.health.code,
summary=source.health.summary,
checked_at=(
source.health.checked_at.isoformat()
if source.health.checked_at
else None
),
details=dict(source.health.details),
),
)