Release Connectors v0.1.21 with external knowledge integration
Module Package Release / publish-packages (push) Successful in 12s

This commit is contained in:
2026-08-22 14:34:36 +02:00
parent 2c2b11f860
commit 79e2315e89
28 changed files with 6351 additions and 33 deletions
+246
View File
@@ -81,6 +81,33 @@ from govoplan_connectors.backend.governed_schemas import (
ConnectorRunListResponse,
ConnectorRunRequest,
)
from govoplan_connectors.backend.knowledge_connector import (
KnowledgeConnectorError,
create_profile,
discover_profile,
list_objects as list_knowledge_objects,
list_profiles as list_knowledge_profiles,
list_runs as list_knowledge_runs,
migration_dry_run,
publish_page,
synchronize_profile,
update_profile,
)
from govoplan_connectors.backend.knowledge_schemas import (
KnowledgeDiscoveryResponse,
KnowledgeMigrationDryRunRequest,
KnowledgeMigrationDryRunResponse,
KnowledgeObjectListResponse,
KnowledgeProfileCreateRequest,
KnowledgeProfileItem,
KnowledgeProfileListResponse,
KnowledgeProfileUpdateRequest,
KnowledgePublishRequest,
KnowledgePublishResponse,
KnowledgeSyncRequest,
KnowledgeSyncRunItem,
KnowledgeSyncRunListResponse,
)
from govoplan_connectors.backend.recovery import (
ConnectorRecoveryError,
begin_connector_read_snapshot,
@@ -188,6 +215,34 @@ def _governed_http_error(exc: GovernedConnectorError) -> HTTPException:
)
def _knowledge_http_error(exc: KnowledgeConnectorError) -> HTTPException:
if exc.code.endswith("_not_found"):
status_code = status.HTTP_404_NOT_FOUND
elif exc.code == "access_denied":
status_code = status.HTTP_403_FORBIDDEN
elif exc.code in {
"idempotency_conflict",
"operation_unresolved",
"profile_conflict",
"profile_paused",
"publication_conflict",
"publication_reconciliation_required",
}:
status_code = status.HTTP_409_CONFLICT
elif exc.retryable or exc.code.endswith("_unavailable"):
status_code = status.HTTP_503_SERVICE_UNAVAILABLE
else:
status_code = status.HTTP_422_UNPROCESSABLE_CONTENT
return HTTPException(
status_code=status_code,
detail={
"code": exc.code,
"message": str(exc),
"retryable": exc.retryable,
},
)
@router.post("/feeds/preview", response_model=FeedDocumentResponse)
def api_preview_feed(
payload: FeedAcquireRequest,
@@ -986,6 +1041,197 @@ def api_review_governed_run(
raise _governed_http_error(exc) from exc
@router.get(
"/knowledge/profiles",
response_model=KnowledgeProfileListResponse,
)
def api_list_knowledge_profiles(
session: Session = Depends(get_session),
principal: ApiPrincipal = Depends(get_api_principal),
) -> KnowledgeProfileListResponse:
try:
return KnowledgeProfileListResponse(
items=list(list_knowledge_profiles(session, principal))
)
except KnowledgeConnectorError as exc:
raise _knowledge_http_error(exc) from exc
@router.post(
"/knowledge/profiles",
response_model=KnowledgeProfileItem,
status_code=status.HTTP_201_CREATED,
)
def api_create_knowledge_profile(
payload: KnowledgeProfileCreateRequest,
session: Session = Depends(get_session),
principal: ApiPrincipal = Depends(get_api_principal),
) -> KnowledgeProfileItem:
try:
return create_profile(session, principal, payload)
except KnowledgeConnectorError as exc:
session.rollback()
raise _knowledge_http_error(exc) from exc
@router.put(
"/knowledge/profiles/{profile_id}",
response_model=KnowledgeProfileItem,
)
def api_update_knowledge_profile(
profile_id: str,
payload: KnowledgeProfileUpdateRequest,
session: Session = Depends(get_session),
principal: ApiPrincipal = Depends(get_api_principal),
) -> KnowledgeProfileItem:
try:
return update_profile(
session,
principal,
profile_id=profile_id,
payload=payload,
)
except KnowledgeConnectorError as exc:
session.rollback()
raise _knowledge_http_error(exc) from exc
@router.post(
"/knowledge/profiles/{profile_id}/discover",
response_model=KnowledgeDiscoveryResponse,
)
def api_discover_knowledge_profile(
profile_id: str,
session: Session = Depends(get_session),
principal: ApiPrincipal = Depends(get_api_principal),
) -> KnowledgeDiscoveryResponse:
try:
return discover_profile(
session,
principal,
profile_id=profile_id,
)
except KnowledgeConnectorError as exc:
raise _knowledge_http_error(exc) from exc
@router.post(
"/knowledge/profiles/{profile_id}/sync",
response_model=KnowledgeSyncRunItem,
)
def api_synchronize_knowledge_profile(
profile_id: str,
payload: KnowledgeSyncRequest,
session: Session = Depends(get_session),
principal: ApiPrincipal = Depends(get_api_principal),
) -> KnowledgeSyncRunItem:
try:
return synchronize_profile(
session,
principal,
profile_id=profile_id,
payload=payload,
)
except KnowledgeConnectorError as exc:
raise _knowledge_http_error(exc) from exc
@router.get(
"/knowledge/profiles/{profile_id}/objects",
response_model=KnowledgeObjectListResponse,
)
def api_list_knowledge_objects(
profile_id: str,
cursor: str | None = Query(default=None, max_length=500),
limit: int = Query(default=100, ge=1, le=500),
session: Session = Depends(get_session),
principal: ApiPrincipal = Depends(get_api_principal),
) -> KnowledgeObjectListResponse:
try:
items, next_cursor = list_knowledge_objects(
session,
principal,
profile_id=profile_id,
cursor=cursor,
limit=limit,
)
return KnowledgeObjectListResponse(
items=list(items),
next_cursor=next_cursor,
)
except KnowledgeConnectorError as exc:
raise _knowledge_http_error(exc) from exc
@router.get(
"/knowledge/runs",
response_model=KnowledgeSyncRunListResponse,
)
def api_list_knowledge_runs(
profile_id: str | None = Query(default=None),
limit: int = Query(default=100, ge=1, le=500),
session: Session = Depends(get_session),
principal: ApiPrincipal = Depends(get_api_principal),
) -> KnowledgeSyncRunListResponse:
try:
return KnowledgeSyncRunListResponse(
items=list(
list_knowledge_runs(
session,
principal,
profile_id=profile_id,
limit=limit,
)
)
)
except KnowledgeConnectorError as exc:
raise _knowledge_http_error(exc) from exc
@router.post(
"/knowledge/profiles/{profile_id}/migration-dry-runs",
response_model=KnowledgeMigrationDryRunResponse,
)
def api_preview_knowledge_migration(
profile_id: str,
payload: KnowledgeMigrationDryRunRequest,
session: Session = Depends(get_session),
principal: ApiPrincipal = Depends(get_api_principal),
) -> KnowledgeMigrationDryRunResponse:
try:
return migration_dry_run(
session,
principal,
profile_id=profile_id,
payload=payload,
)
except KnowledgeConnectorError as exc:
raise _knowledge_http_error(exc) from exc
@router.post(
"/knowledge/profiles/{profile_id}/pages/{external_page_id}/publish",
response_model=KnowledgePublishResponse,
)
def api_publish_knowledge_page(
profile_id: str,
external_page_id: str,
payload: KnowledgePublishRequest,
session: Session = Depends(get_session),
principal: ApiPrincipal = Depends(get_api_principal),
) -> KnowledgePublishResponse:
try:
return publish_page(
session,
principal,
profile_id=profile_id,
external_page_id=external_page_id,
payload=payload,
)
except KnowledgeConnectorError as exc:
raise _knowledge_http_error(exc) from exc
def _source_response(source: TabularSource) -> TabularSourceResponse:
return TabularSourceResponse(
ref=source.ref,