Skip to content

Commit

Permalink
Add patch endpoint for attachment metadata #27
Browse files Browse the repository at this point in the history
  • Loading branch information
rowan04 committed Jan 16, 2025
1 parent d51376a commit 4c3d0c6
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 1 deletion.
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())

0 comments on commit 4c3d0c6

Please sign in to comment.