Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add patch endpoint for attachment metadata #27 #95

Draft
wants to merge 1 commit into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions object_storage_api/repositories/attachment.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,28 @@ def list(self, entity_id: Optional[str], session: Optional[ClientSession] = None

attachments = self._attachments_collection.find(query, session=session)
return [AttachmentOut(**attachment) for attachment in attachments]

def update(self, attachment_id: str, attachment: AttachmentIn, session: ClientSession = None) -> AttachmentOut:
"""
Updates an attachment by its ID in a MongoDB database.

:param attachment_id: The ID of the attachment to update.
:param attachment: The attachment containing the update data.
:param session: PyMongo ClientSession to use for database operations.
:return: The updated attachment.
:raises InvalidObjectIdError: If the supplied `attachment_id` is invalid.
"""

logger.info("Updating attachment metadata with ID: %s", attachment_id)

try:
attachment_id = CustomObjectId(attachment_id)
self._attachments_collection.update_one(
{"_id": attachment_id}, {"$set": attachment.model_dump(by_alias=True)}, session=session
)
except InvalidObjectIdError as exc:
exc.status_code = 404
exc.response_detail = "Attachment not found"
raise exc

return self.get(attachment_id=str(attachment_id), session=session)
20 changes: 19 additions & 1 deletion object_storage_api/routers/attachment.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@
import logging
from typing import Annotated, Optional

from fastapi import APIRouter, Depends, Query, status
from fastapi import APIRouter, Depends, Path, Query, status

from object_storage_api.schemas.attachment import (
AttachmentMetadataSchema,
AttachmentPatchMetadataSchema,
AttachmentPostResponseSchema,
AttachmentPostSchema,
)
Expand Down Expand Up @@ -55,3 +56,20 @@ def get_attachments(
logger.debug("Entity ID filter: '%s'", entity_id)

return attachment_service.list(entity_id)


@router.patch(
path="/{attachment_id}",
summary="Update an attachment partially by ID",
response_description="Attachment updated successfully",
)
def partial_update_attachment(
attachment: AttachmentPatchMetadataSchema,
attachment_id: Annotated[str, Path(description="ID of the attachment to update")],
attachment_service: AttachmentServiceDep,
) -> AttachmentMetadataSchema:
# pylint: disable=missing-function-docstring
logger.info("Partially updating attachment with ID: %s", attachment_id)
logger.debug("Attachment data: %s", attachment)

return attachment_service.update(attachment_id, attachment)
8 changes: 8 additions & 0 deletions object_storage_api/schemas/attachment.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@
from object_storage_api.schemas.mixins import CreatedModifiedSchemaMixin


class AttachmentPatchMetadataSchema(BaseModel):
"""Schema model for an attachment update request."""

title: Optional[str] = Field(default=None, description="Title of the attachment")
description: Optional[str] = Field(default=None, description="Description of the attachment")
file_name: Optional[str] = Field(default=None, description="File name of the attachment")


class AttachmentPostSchema(BaseModel):
"""
Schema model for an attachment creation request.
Expand Down
20 changes: 20 additions & 0 deletions object_storage_api/services/attachment.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from object_storage_api.repositories.attachment import AttachmentRepo
from object_storage_api.schemas.attachment import (
AttachmentMetadataSchema,
AttachmentPatchMetadataSchema,
AttachmentPostResponseSchema,
AttachmentPostSchema,
)
Expand Down Expand Up @@ -78,3 +79,22 @@ def list(self, entity_id: Optional[str] = None) -> list[AttachmentMetadataSchema
attachments = self._attachment_repository.list(entity_id)

return [AttachmentMetadataSchema(**attachment.model_dump()) for attachment in attachments]

def update(self, attachment_id: str, attachment: AttachmentPatchMetadataSchema) -> AttachmentMetadataSchema:
"""
Update an attachment by its ID.

:param attachment_id: The ID of the attachment to update.
:param attachment: The attachment containing the fields to be updated.
:return: The updated attachment.
"""

stored_attachment = self._attachment_repository.get(attachment_id=attachment_id)
update_data = attachment.model_dump(exclude_unset=True)

updated_attachment = self._attachment_repository.update(
attachment_id=attachment_id,
attachment=AttachmentIn(**{**stored_attachment.model_dump(), **update_data}),
)

return AttachmentMetadataSchema(**updated_attachment.model_dump())
Loading