Release Connectors v0.1.22 with service-desk federation
Module Package Release / publish-packages (push) Successful in 12s

This commit is contained in:
2026-08-22 16:11:07 +02:00
parent 79e2315e89
commit b277e8d7ac
22 changed files with 7348 additions and 13 deletions
+226
View File
@@ -112,6 +112,30 @@ from govoplan_connectors.backend.recovery import (
ConnectorRecoveryError,
begin_connector_read_snapshot,
)
from govoplan_connectors.backend.service_desk_connector import (
ServiceDeskConnectorError,
create_profile as create_service_desk_profile,
discover_profile as discover_service_desk_profile,
list_objects as list_service_desk_objects,
list_profiles as list_service_desk_profiles,
list_runs as list_service_desk_runs,
synchronize_profile as synchronize_service_desk_profile,
update_profile as update_service_desk_profile,
update_ticket as update_service_desk_ticket,
)
from govoplan_connectors.backend.service_desk_schemas import (
ServiceDeskDiscoveryResponse,
ServiceDeskObjectListResponse,
ServiceDeskProfileCreateRequest,
ServiceDeskProfileItem,
ServiceDeskProfileListResponse,
ServiceDeskProfileUpdateRequest,
ServiceDeskSyncRequest,
ServiceDeskSyncRunItem,
ServiceDeskSyncRunListResponse,
ServiceDeskTicketUpdateRequest,
ServiceDeskTicketUpdateResponse,
)
from govoplan_connectors.backend.sanctions_sources import (
SANCTIONS_READ_SCOPE,
SANCTIONS_REFRESH_SCOPE,
@@ -243,6 +267,38 @@ def _knowledge_http_error(exc: KnowledgeConnectorError) -> HTTPException:
)
def _service_desk_http_error(exc: ServiceDeskConnectorError) -> HTTPException:
if exc.code.endswith("_not_found"):
status_code = status.HTTP_404_NOT_FOUND
elif exc.code == "forbidden":
status_code = status.HTTP_403_FORBIDDEN
elif exc.code in {
"authority_mode_invalid",
"cursor_conflict",
"external_authoritative",
"external_revision_conflict",
"idempotency_conflict",
"operation_unresolved",
"profile_conflict",
"profile_paused",
"rediscovery_required",
"update_outcome_unknown",
}:
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,
@@ -1232,6 +1288,176 @@ def api_publish_knowledge_page(
raise _knowledge_http_error(exc) from exc
@router.get(
"/service-desk/profiles",
response_model=ServiceDeskProfileListResponse,
)
def api_list_service_desk_profiles(
session: Session = Depends(get_session),
principal: ApiPrincipal = Depends(get_api_principal),
) -> ServiceDeskProfileListResponse:
try:
return ServiceDeskProfileListResponse(
items=list(list_service_desk_profiles(session, principal))
)
except ServiceDeskConnectorError as exc:
raise _service_desk_http_error(exc) from exc
@router.post(
"/service-desk/profiles",
response_model=ServiceDeskProfileItem,
status_code=status.HTTP_201_CREATED,
)
def api_create_service_desk_profile(
payload: ServiceDeskProfileCreateRequest,
session: Session = Depends(get_session),
principal: ApiPrincipal = Depends(get_api_principal),
) -> ServiceDeskProfileItem:
try:
return create_service_desk_profile(session, principal, payload)
except ServiceDeskConnectorError as exc:
session.rollback()
raise _service_desk_http_error(exc) from exc
@router.put(
"/service-desk/profiles/{profile_id}",
response_model=ServiceDeskProfileItem,
)
def api_update_service_desk_profile(
profile_id: str,
payload: ServiceDeskProfileUpdateRequest,
session: Session = Depends(get_session),
principal: ApiPrincipal = Depends(get_api_principal),
) -> ServiceDeskProfileItem:
try:
return update_service_desk_profile(
session,
principal,
profile_id=profile_id,
payload=payload,
)
except ServiceDeskConnectorError as exc:
session.rollback()
raise _service_desk_http_error(exc) from exc
@router.post(
"/service-desk/profiles/{profile_id}/discover",
response_model=ServiceDeskDiscoveryResponse,
)
def api_discover_service_desk_profile(
profile_id: str,
session: Session = Depends(get_session),
principal: ApiPrincipal = Depends(get_api_principal),
) -> ServiceDeskDiscoveryResponse:
try:
return discover_service_desk_profile(
session,
principal,
profile_id=profile_id,
)
except ServiceDeskConnectorError as exc:
raise _service_desk_http_error(exc) from exc
@router.post(
"/service-desk/profiles/{profile_id}/sync",
response_model=ServiceDeskSyncRunItem,
)
def api_synchronize_service_desk_profile(
profile_id: str,
payload: ServiceDeskSyncRequest,
session: Session = Depends(get_session),
principal: ApiPrincipal = Depends(get_api_principal),
) -> ServiceDeskSyncRunItem:
try:
return synchronize_service_desk_profile(
session,
principal,
profile_id=profile_id,
payload=payload,
)
except ServiceDeskConnectorError as exc:
raise _service_desk_http_error(exc) from exc
@router.get(
"/service-desk/profiles/{profile_id}/objects",
response_model=ServiceDeskObjectListResponse,
)
def api_list_service_desk_objects(
profile_id: str,
cursor: str | None = Query(default=None, max_length=36),
limit: int = Query(default=100, ge=1, le=500),
session: Session = Depends(get_session),
principal: ApiPrincipal = Depends(get_api_principal),
) -> ServiceDeskObjectListResponse:
try:
items, next_cursor = list_service_desk_objects(
session,
principal,
profile_id=profile_id,
cursor=cursor,
limit=limit,
)
return ServiceDeskObjectListResponse(
items=list(items),
next_cursor=next_cursor,
)
except ServiceDeskConnectorError as exc:
raise _service_desk_http_error(exc) from exc
@router.get(
"/service-desk/runs",
response_model=ServiceDeskSyncRunListResponse,
)
def api_list_service_desk_runs(
profile_id: str | None = Query(default=None, max_length=36),
limit: int = Query(default=100, ge=1, le=500),
session: Session = Depends(get_session),
principal: ApiPrincipal = Depends(get_api_principal),
) -> ServiceDeskSyncRunListResponse:
try:
return ServiceDeskSyncRunListResponse(
items=list(
list_service_desk_runs(
session,
principal,
profile_id=profile_id,
limit=limit,
)
)
)
except ServiceDeskConnectorError as exc:
raise _service_desk_http_error(exc) from exc
@router.post(
"/service-desk/profiles/{profile_id}/tickets/{external_ticket_id}/update",
response_model=ServiceDeskTicketUpdateResponse,
)
def api_update_service_desk_ticket(
profile_id: str,
external_ticket_id: str,
payload: ServiceDeskTicketUpdateRequest,
session: Session = Depends(get_session),
principal: ApiPrincipal = Depends(get_api_principal),
) -> ServiceDeskTicketUpdateResponse:
try:
return update_service_desk_ticket(
session,
principal,
profile_id=profile_id,
external_ticket_id=external_ticket_id,
payload=payload,
)
except ServiceDeskConnectorError as exc:
raise _service_desk_http_error(exc) from exc
def _source_response(source: TabularSource) -> TabularSourceResponse:
return TabularSourceResponse(
ref=source.ref,