Skip to content

Commit 77a3fcf

Browse files
committed
Implements PR suggestions
1 parent 7540acc commit 77a3fcf

2 files changed

Lines changed: 319 additions & 48 deletions

File tree

vintasend_celery/services/notification_adapters/celery_adapter_factory.py

Lines changed: 46 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
from celery import Task # type: ignore
66
from vintasend.services.dataclasses import (
7+
AttachmentFile,
78
Notification,
89
NotificationContextDict,
910
OneOffNotification,
@@ -22,6 +23,44 @@
2223
T = TypeVar("T", bound=BaseNotificationTemplateRenderer)
2324

2425

26+
class PlaceholderAttachmentFile(AttachmentFile):
27+
"""
28+
Placeholder for AttachmentFile.
29+
All file operations raise NotImplementedError and must be handled by the caller.
30+
Use this class only when the actual file is expected to be retrieved by the backend.
31+
"""
32+
def __init__(self, attachment_id):
33+
self.attachment_id = attachment_id
34+
35+
def read(self) -> bytes:
36+
"""
37+
Attempting to read will raise NotImplementedError.
38+
Caller must handle this exception and retrieve the file from the backend.
39+
"""
40+
raise NotImplementedError("File must be retrieved from backend")
41+
42+
def stream(self):
43+
"""
44+
Attempting to stream will raise NotImplementedError.
45+
Caller must handle this exception and retrieve the file from the backend.
46+
"""
47+
raise NotImplementedError("File must be retrieved from backend")
48+
49+
def url(self, expires_in: int = 3600) -> str:
50+
"""
51+
Attempting to get a URL will raise NotImplementedError.
52+
Caller must handle this exception and retrieve the file from the backend.
53+
"""
54+
raise NotImplementedError("File must be retrieved from backend")
55+
56+
def delete(self) -> None:
57+
"""
58+
Attempting to delete will raise NotImplementedError.
59+
Caller must handle this exception and perform deletion via the backend.
60+
"""
61+
raise NotImplementedError("File must be retrieved from backend")
62+
63+
2564
class CeleryNotificationAdapter(Generic[B, T], AsyncBaseNotificationAdapter[B, T]):
2665
send_notification_task: Task
2766

@@ -61,15 +100,10 @@ def notification_to_dict(self, notification: "Notification | OneOffNotification"
61100
"one_off" if isinstance(notification, OneOffNotification) else "regular"
62101
)
63102

64-
# Add specific fields based on notification type
65-
if isinstance(notification, OneOffNotification):
66-
# Set adapter_extra_parameters if missing
67-
if "adapter_extra_parameters" not in serialized_notification:
68-
serialized_notification["adapter_extra_parameters"] = getattr(notification, 'adapter_extra_parameters', {})
69-
else:
70-
# For regular notifications, ensure adapter_extra_parameters exists
71-
if "adapter_extra_parameters" not in serialized_notification:
72-
serialized_notification["adapter_extra_parameters"] = getattr(notification, 'adapter_extra_parameters', None)
103+
# Ensure adapter_extra_parameters exists for all notification types
104+
if "adapter_extra_parameters" not in serialized_notification:
105+
default_value: dict[str, Any] | None = {} if isinstance(notification, OneOffNotification) else None
106+
serialized_notification["adapter_extra_parameters"] = getattr(notification, 'adapter_extra_parameters', default_value)
73107

74108
# Ensure context_used exists
75109
if "context_used" not in serialized_notification:
@@ -123,11 +157,11 @@ def _serialize_attachment(self, attachment) -> dict:
123157
size = 0
124158

125159
return {
126-
"id": f"temp_{hash(attachment.filename)}", # Temporary ID
160+
"id": f"temp_{uuid.uuid4()}", # Temporary ID, guaranteed unique
127161
"filename": attachment.filename,
128162
"content_type": attachment.content_type,
129163
"size": size,
130-
"checksum": "placeholder", # Will be calculated by backend
164+
"checksum": None, # Will be calculated by backend
131165
"created_at": datetime.datetime.now().isoformat(),
132166
"description": attachment.description,
133167
"is_inline": attachment.is_inline,
@@ -139,26 +173,7 @@ def _serialize_attachment(self, attachment) -> dict:
139173

140174
def _deserialize_attachment(self, attachment_dict: dict) -> StoredAttachment:
141175
"""Deserialize an attachment dictionary back to StoredAttachment."""
142-
# We need to create a placeholder AttachmentFile that can be resolved by the backend
143-
from vintasend.services.dataclasses import AttachmentFile
144-
145-
# Create a dummy AttachmentFile - the actual file will be retrieved by the backend
146-
class PlaceholderAttachmentFile(AttachmentFile):
147-
def __init__(self, attachment_id):
148-
self.attachment_id = attachment_id
149-
150-
def read(self) -> bytes:
151-
raise NotImplementedError("File must be retrieved from backend")
152-
153-
def stream(self):
154-
raise NotImplementedError("File must be retrieved from backend")
155-
156-
def url(self, expires_in: int = 3600) -> str:
157-
raise NotImplementedError("File must be retrieved from backend")
158-
159-
def delete(self) -> None:
160-
raise NotImplementedError("File must be retrieved from backend")
161-
176+
# WARNING: PlaceholderAttachmentFile methods raise NotImplementedError. Handle accordingly.
162177
return StoredAttachment(
163178
id=attachment_dict["id"],
164179
filename=attachment_dict["filename"],

0 commit comments

Comments
 (0)