Files
govoplan-connectors/src/govoplan_connectors/backend/knowledge_schemas.py
T
zemion 79e2315e89
Module Package Release / publish-packages (push) Successful in 12s
Release Connectors v0.1.21 with external knowledge integration
2026-08-22 14:34:36 +02:00

304 lines
9.2 KiB
Python

from __future__ import annotations
from datetime import datetime
from typing import Any, Literal
from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator
KnowledgeMaturity = Literal[
"discover",
"link",
"search",
"read",
"publish",
"synchronize",
"migrate",
]
KnowledgeVisibility = Literal["tenant", "restricted"]
class KnowledgeNamespaceMapping(BaseModel):
model_config = ConfigDict(extra="forbid")
source_namespace_id: int
source_name: str = Field(default="", max_length=200)
target_space_ref: str = Field(min_length=1, max_length=255)
target_path_prefix: str = Field(default="", max_length=500)
include: bool = True
visibility: KnowledgeVisibility | None = None
acl_tokens: list[str] = Field(default_factory=list, max_length=500)
@field_validator("acl_tokens")
@classmethod
def normalize_acl_tokens(cls, values: list[str]) -> list[str]:
return _normalized_tokens(values)
@model_validator(mode="after")
def restricted_mapping_requires_acl(self) -> "KnowledgeNamespaceMapping":
if self.visibility == "restricted" and not self.acl_tokens:
raise ValueError("Restricted namespace mappings require ACL tokens")
return self
class KnowledgeProfileCreateRequest(BaseModel):
model_config = ConfigDict(extra="forbid")
configuration_id: str = Field(min_length=1, max_length=36)
desired_maturity: KnowledgeMaturity = "read"
source_authority_mode: Literal[
"external_authoritative",
"external_mirror",
"governed_sync",
"linked_reference",
] = "external_mirror"
default_visibility: KnowledgeVisibility = "restricted"
default_acl_tokens: list[str] = Field(default_factory=list, max_length=500)
namespace_mappings: list[KnowledgeNamespaceMapping] = Field(
min_length=1, max_length=500
)
@field_validator("default_acl_tokens")
@classmethod
def normalize_acl_tokens(cls, values: list[str]) -> list[str]:
return _normalized_tokens(values)
@model_validator(mode="after")
def restricted_profile_requires_acl(self) -> "KnowledgeProfileCreateRequest":
if self.default_visibility == "restricted" and not self.default_acl_tokens:
raise ValueError("Restricted knowledge profiles require default ACL tokens")
return self
class KnowledgeProfileUpdateRequest(BaseModel):
model_config = ConfigDict(extra="forbid")
expected_resource_revision: int = Field(ge=1)
status: Literal["active", "paused"] | None = None
desired_maturity: KnowledgeMaturity | None = None
source_authority_mode: Literal[
"external_authoritative",
"external_mirror",
"governed_sync",
"linked_reference",
] | None = None
default_visibility: KnowledgeVisibility | None = None
default_acl_tokens: list[str] | None = Field(default=None, max_length=500)
namespace_mappings: list[KnowledgeNamespaceMapping] | None = Field(
default=None, min_length=1, max_length=500
)
@field_validator("default_acl_tokens")
@classmethod
def normalize_acl_tokens(cls, values: list[str] | None) -> list[str] | None:
return _normalized_tokens(values) if values is not None else None
class KnowledgeProfileItem(BaseModel):
id: str
tenant_id: str
configuration_id: str
status: str
product: str
product_version: str | None = None
desired_maturity: str
discovered_maturity: str
source_authority_mode: str
default_visibility: str
default_acl_tokens: list[str]
namespace_mappings: list[dict[str, Any]]
capabilities: list[str]
discovery_revision: str | None = None
health_status: str
health_details: dict[str, Any]
discovered_at: datetime | None = None
last_sync_cursor: str | None = None
last_high_watermark: str | None = None
resource_revision: int
credential_reference_present: bool = False
endpoint_configured: bool = False
created_at: datetime
updated_at: datetime
class KnowledgeProfileListResponse(BaseModel):
items: list[KnowledgeProfileItem]
class KnowledgeDiagnostic(BaseModel):
severity: Literal["info", "warning", "error"]
code: str
message: str
object_ref: str | None = None
field: str | None = None
retryable: bool = False
details: dict[str, Any] = Field(default_factory=dict)
class KnowledgeDiscoveryResponse(BaseModel):
profile: KnowledgeProfileItem
product: str
product_version: str | None = None
api_version: str | None = None
capabilities: list[str]
namespaces: list[dict[str, Any]]
extensions: list[dict[str, Any]]
maturity: str
health_status: str
diagnostics: list[KnowledgeDiagnostic]
revision: str
class KnowledgeSyncRequest(BaseModel):
model_config = ConfigDict(extra="forbid")
idempotency_key: str = Field(min_length=1, max_length=255)
cursor: str | None = Field(default=None, max_length=500)
force_full: bool = False
limit: int = Field(default=100, ge=1, le=500)
class KnowledgeSyncRunItem(BaseModel):
id: str
tenant_id: str
profile_id: str
mode: str
idempotency_key: str
status: str
cursor_before: str | None = None
cursor_after: str | None = None
high_watermark: str | None = None
counts: dict[str, Any]
effects: list[dict[str, Any]]
diagnostics: list[KnowledgeDiagnostic]
provenance: dict[str, Any]
started_at: datetime
finished_at: datetime | None = None
created_at: datetime
class KnowledgeSyncRunListResponse(BaseModel):
items: list[KnowledgeSyncRunItem]
class KnowledgeExternalReferenceResponse(BaseModel):
system: str
object_type: str
object_id: str
maturity: str
authority_mode: str
connector_id: str | None = None
canonical_url: str | None = None
version: str | None = None
etag: str | None = None
observed_at: str | None = None
metadata: dict[str, Any]
class KnowledgeObjectItem(BaseModel):
id: str
profile_id: str
object_type: str
external_id: str
external_page_id: str | None = None
external_revision_id: str | None = None
namespace_id: int | None = None
title: str
canonical_url: str | None = None
status: str
redirect_target_external_id: str | None = None
source_revision: str
visibility: str
acl_tokens: list[str]
mapped_data: dict[str, Any]
external_reference: KnowledgeExternalReferenceResponse
source_updated_at: datetime | None = None
observed_at: datetime
resource_revision: int
class KnowledgeObjectListResponse(BaseModel):
items: list[KnowledgeObjectItem]
next_cursor: str | None = None
class KnowledgeMigrationTargetState(BaseModel):
model_config = ConfigDict(extra="forbid")
path: str = Field(min_length=1, max_length=500)
source_external_id: str | None = Field(default=None, max_length=255)
attachment_names: list[str] = Field(default_factory=list, max_length=500)
class KnowledgeMigrationDryRunRequest(BaseModel):
model_config = ConfigDict(extra="forbid")
idempotency_key: str = Field(min_length=1, max_length=255)
target_space_ref: str = Field(min_length=1, max_length=255)
max_items: int = Field(default=100, ge=1, le=500)
supported_macros: list[str] = Field(default_factory=list, max_length=200)
existing_targets: list[KnowledgeMigrationTargetState] = Field(
default_factory=list, max_length=5_000
)
class KnowledgeMigrationDryRunResponse(BaseModel):
run: KnowledgeSyncRunItem
target_space_ref: str
source_revision: str
source_fingerprint: str
summary: dict[str, int]
effects: list[dict[str, Any]]
diagnostics: list[KnowledgeDiagnostic]
truncated: bool
can_apply: bool
class KnowledgePublishRequest(BaseModel):
model_config = ConfigDict(extra="forbid")
idempotency_key: str = Field(min_length=1, max_length=255)
title: str = Field(min_length=1, max_length=500)
body: str = Field(max_length=200_000)
summary: str = Field(default="", max_length=500)
expected_external_revision: str | None = Field(default=None, max_length=255)
minor: bool = False
class KnowledgePublishResponse(BaseModel):
run: KnowledgeSyncRunItem
external_reference: KnowledgeExternalReferenceResponse
accepted: bool
outcome_unknown: bool = False
def _normalized_tokens(values: list[str]) -> list[str]:
normalized = [str(item).strip() for item in values]
if any(not item or len(item) > 500 for item in normalized):
raise ValueError("ACL tokens must contain 1 to 500 characters")
if len(normalized) != len(set(normalized)):
raise ValueError("ACL tokens must be unique")
return normalized
__all__ = [
"KnowledgeDiagnostic",
"KnowledgeDiscoveryResponse",
"KnowledgeExternalReferenceResponse",
"KnowledgeMigrationDryRunRequest",
"KnowledgeMigrationDryRunResponse",
"KnowledgeMigrationTargetState",
"KnowledgeNamespaceMapping",
"KnowledgeObjectItem",
"KnowledgeObjectListResponse",
"KnowledgeProfileCreateRequest",
"KnowledgeProfileItem",
"KnowledgeProfileListResponse",
"KnowledgeProfileUpdateRequest",
"KnowledgePublishRequest",
"KnowledgePublishResponse",
"KnowledgeSyncRequest",
"KnowledgeSyncRunItem",
"KnowledgeSyncRunListResponse",
]