Warnings cleanup

This commit is contained in:
2026-05-14 01:02:25 +02:00
parent 484a978795
commit 41bd662641
12 changed files with 331 additions and 41 deletions

View File

@@ -89,6 +89,7 @@ from kontextual_engine.services import (
API_VERSION = "v1"
OPENAPI_VERSION = "1.0.0"
CMIS_APPEND_MAX_COMPOSED_BYTES = 64 * 1024 * 1024
AGENT_OPERATION_CATALOG: tuple[dict[str, Any], ...] = (
@@ -1305,6 +1306,73 @@ class ServiceRuntime:
)
return self.cmis_object(access_point_id, object_id, context)
def cmis_append_content_stream(
self,
access_point_id: str,
object_id: str,
payload: dict[str, Any],
context: OperationContext,
) -> dict[str, Any]:
mapper = self._cmis_mapper(access_point_id)
decision = mapper.access_point.decide_action(CMISAction.SET_CONTENT_STREAM, context, resource=object_id)
if not decision.allowed:
raise _cmis_authorization_error(decision, "appendContentStream")
asset_id = _cmis_asset_id(object_id)
asset = self.repository.get_asset(asset_id)
if not mapper.access_point.exposes_asset(asset, context):
raise NotFoundError(
"CMIS object not found",
details={"object_id": object_id, "access_point_id": access_point_id},
)
expected = (
payload.get("expected_current_version_id")
or payload.get("changeToken")
or payload.get("change_token")
)
self._cmis_assert_change_token(asset, expected, operation="appendContentStream")
appended = _cmis_payload_bytes(payload.get("content", b""))
is_last_chunk = _cmis_form_bool(payload.get("isLastChunk") or payload.get("is_last_chunk"), default=True)
base = b""
kind = payload.get("kind", RepresentationKind.SOURCE.value)
media_type = _cmis_media_type(payload.get("media_type", "application/octet-stream"))
if self._cmis_asset_representations(asset):
stream = self.content_service().get_content_stream(asset_id, context)
base = stream.content
kind = stream.representation.kind.value
media_type = _cmis_media_type(payload.get("media_type") or stream.representation.media_type)
elif asset.metadata.get("cmis_content_deleted"):
metadata = dict(asset.metadata)
metadata.pop("cmis_content_deleted", None)
self.repository.save_asset(replace(asset, metadata=metadata))
composed_size = len(base) + len(appended)
if composed_size > CMIS_APPEND_MAX_COMPOSED_BYTES:
raise ValidationError(
"CMIS append content stream exceeds the composed append limit",
details={
"code": "cmis.append_content_limit_exceeded",
"cmis_exception": "constraint",
"operation": "appendContentStream",
"max_size_bytes": CMIS_APPEND_MAX_COMPOSED_BYTES,
"composed_size_bytes": composed_size,
},
)
self.content_service().add_representation_from_bytes(
asset_id,
kind,
media_type,
base + appended,
context,
expected_current_version_id=expected,
metadata={
"cmis": {
"operation": "appendContentStream",
"is_last_chunk": is_last_chunk,
"appended_bytes": len(appended),
}
},
)
return self.cmis_object(access_point_id, object_id, context)
def cmis_delete_content_stream(
self,
access_point_id: str,
@@ -3676,6 +3744,11 @@ def create_app(runtime: ServiceRuntime | None = None):
raise ValidationError("CMIS object id is required", details={"operation": "setContentStream"})
response(runtime.cmis_set_content_stream, access_point_id, object_id, payload, context)
return response(runtime.cmis_browser_object, access_point_id, object_id, context)
if action in {"appendContentStream", "appendContent"}:
if not object_id:
raise ValidationError("CMIS object id is required", details={"operation": "appendContentStream"})
response(runtime.cmis_append_content_stream, access_point_id, object_id, payload, context)
return response(runtime.cmis_browser_object, access_point_id, object_id, context)
if action in {"deleteContent", "deleteContentStream"}:
if not object_id:
raise ValidationError("CMIS object id is required", details={"operation": "deleteContentStream"})
@@ -3699,6 +3772,8 @@ def create_app(runtime: ServiceRuntime | None = None):
"move",
"setContentStream",
"setContent",
"appendContentStream",
"appendContent",
"deleteContent",
"deleteContentStream",
],
@@ -4632,6 +4707,24 @@ def _cmis_media_type(value: Any) -> str:
return media_type or "application/octet-stream"
def _cmis_payload_bytes(value: Any) -> bytes:
if value is None:
return b""
if isinstance(value, bytes):
return value
if isinstance(value, bytearray):
return bytes(value)
return str(value).encode("utf-8")
def _cmis_form_bool(value: Any, *, default: bool = False) -> bool:
if value in (None, ""):
return default
if isinstance(value, bool):
return value
return str(value).strip().lower() in {"1", "true", "yes", "on"}
def _cmis_value_list(value: Any) -> list[str]:
if value is None or value == "":
return []