generated from coulomb/repo-seed
Warnings cleanup
This commit is contained in:
@@ -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 []
|
||||
|
||||
Reference in New Issue
Block a user