notifyfork 0.1.2__tar.gz → 0.1.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {notifyfork-0.1.2 → notifyfork-0.1.3}/PKG-INFO +1 -1
- {notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/core/application/use_cases/send_notification.py +29 -8
- {notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/core/domain/entities/notification.py +4 -4
- {notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/core/domain/events/notification_events.py +4 -4
- notifyfork-0.1.3/notifyfork/core/infrastructure/admin.py +36 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/core/infrastructure/providers/twilio_provider.py +1 -1
- {notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/core/infrastructure/providers/whatsapp_provider.py +6 -2
- {notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/core/infrastructure/repositories/notification_repository.py +2 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/pyproject.toml +1 -1
- {notifyfork-0.1.2 → notifyfork-0.1.3}/.env.example +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/.github/workflows/auto-tag.yml +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/.github/workflows/ci.yml +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/.github/workflows/publish.yml +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/.gitignore +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/CHANGELOG.md +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/CONTRIBUTING.md +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/LICENSE +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/README.md +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/examples/README.md +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/examples/custom_provider/register_xpto_provider.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/examples/email/send_order_confirmed.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/examples/email/send_sendgrid_external.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/examples/push/send_flash_sale.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/examples/slack/send_system_error.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/examples/sms/send_otp.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/examples/whatsapp/send_order_shipped.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/__init__.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/api/__init__.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/api/urls.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/api/webhooks/__init__.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/api/webhooks/resend_webhook.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/api/webhooks/sendgrid_webhook.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/api/webhooks/tasks.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/api/webhooks/twilio_webhook.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/api/webhooks/urls.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/client.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/core/__init__.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/core/application/__init__.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/core/application/dtos/__init__.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/core/application/dtos/send_notification_dto.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/core/application/interfaces/__init__.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/core/application/interfaces/notification_provider.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/core/application/interfaces/notification_repository.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/core/application/interfaces/template_repository.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/core/application/use_cases/__init__.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/core/domain/__init__.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/core/domain/entities/__init__.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/core/domain/events/__init__.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/core/domain/value_objects/__init__.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/core/domain/value_objects/template.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/core/infrastructure/__init__.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/core/infrastructure/apps.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/core/infrastructure/container/__init__.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/core/infrastructure/container/providers.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/core/infrastructure/migrations/0001_initial.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/core/infrastructure/migrations/0002_seed_templates.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/core/infrastructure/migrations/0003_delivery_status.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/core/infrastructure/migrations/__init__.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/core/infrastructure/models/__init__.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/core/infrastructure/models/notification_model.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/core/infrastructure/providers/__init__.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/core/infrastructure/providers/firebase_provider.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/core/infrastructure/providers/resend_provider.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/core/infrastructure/providers/sendgrid_provider.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/core/infrastructure/providers/slack_provider.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/core/infrastructure/providers/smtp_provider.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/core/infrastructure/queue/__init__.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/core/infrastructure/queue/tasks.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/core/infrastructure/repositories/__init__.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/core/infrastructure/repositories/template_repository.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/shared/__init__.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/shared/exceptions/__init__.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/shared/exceptions/provider_exceptions.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/shared/logging/__init__.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/shared/logging/setup.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/shared/utils/__init__.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/requirements.txt +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/tests/__init__.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/tests/conftest.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/tests/integration/__init__.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/tests/unit/__init__.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/tests/unit/api/__init__.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/tests/unit/application/__init__.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/tests/unit/application/test_send_notification_use_case.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/tests/unit/conftest.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/tests/unit/domain/__init__.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/tests/unit/domain/test_notification_entity.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/tests/unit/domain/test_template_value_object.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/tests/unit/providers/__init__.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/tests/unit/providers/test_resend_provider.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/tests/unit/providers/test_sendgrid_provider.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/tests/unit/providers/test_slack_provider.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/tests/unit/providers/test_whatsapp_provider.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/tests/unit/test_client.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/tests/unit/test_container.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/tests/unit/test_custom_provider.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/tests/unit/webhooks/__init__.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/tests/unit/webhooks/test_delivery_status.py +0 -0
- {notifyfork-0.1.2 → notifyfork-0.1.3}/tests/urls.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: notifyfork
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.3
|
|
4
4
|
Summary: Provider-agnostic notification gateway for Django. Send to SMS, Email, WhatsApp, Push, and Slack via a single API.
|
|
5
5
|
Project-URL: Homepage, https://github.com/marioasaraujo/notifyfork
|
|
6
6
|
Project-URL: Documentation, https://github.com/marioasaraujo/notifyfork#readme
|
{notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/core/application/use_cases/send_notification.py
RENAMED
|
@@ -57,18 +57,39 @@ class SendNotificationUseCase:
|
|
|
57
57
|
|
|
58
58
|
error = "Unknown provider error"
|
|
59
59
|
for index, provider in enumerate(candidates):
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
60
|
+
has_fallback = index < len(candidates) - 1
|
|
61
|
+
try:
|
|
62
|
+
# Provider handles LOCAL vs EXTERNAL rendering internally
|
|
63
|
+
result = await provider.send_with_template(
|
|
64
|
+
recipient=dto.recipient,
|
|
65
|
+
template=template,
|
|
66
|
+
context=dto.context,
|
|
67
|
+
)
|
|
68
|
+
except Exception as exc:
|
|
69
|
+
# A provider raising instead of returning ProviderResult(success=False)
|
|
70
|
+
# must not escape this loop: an uncaught exception here propagates to
|
|
71
|
+
# the Celery task, which retries the whole use case from scratch
|
|
72
|
+
# (creating a brand-new Notification each time) and this notification
|
|
73
|
+
# is never saved as FAILED — it's left stuck in QUEUED forever, even
|
|
74
|
+
# after Celery's own retries are exhausted.
|
|
75
|
+
error = str(exc)
|
|
76
|
+
logger.warning(
|
|
77
|
+
"Provider raised an exception"
|
|
78
|
+
+ (", falling back to next provider" if has_fallback else ""),
|
|
79
|
+
extra={
|
|
80
|
+
"provider": provider.name,
|
|
81
|
+
"channel": dto.channel,
|
|
82
|
+
"error": error,
|
|
83
|
+
"fallback_available": has_fallback,
|
|
84
|
+
},
|
|
85
|
+
)
|
|
86
|
+
continue
|
|
87
|
+
|
|
66
88
|
if result.success:
|
|
67
|
-
notification.mark_sent(provider.name)
|
|
89
|
+
notification.mark_sent(provider.name, result.external_id)
|
|
68
90
|
break
|
|
69
91
|
|
|
70
92
|
error = result.error or "Unknown provider error"
|
|
71
|
-
has_fallback = index < len(candidates) - 1
|
|
72
93
|
logger.warning(
|
|
73
94
|
"Provider failed" + (", falling back to next provider" if has_fallback else ""),
|
|
74
95
|
extra={
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from dataclasses import dataclass, field
|
|
2
|
-
from datetime import datetime
|
|
2
|
+
from datetime import datetime, timezone
|
|
3
3
|
from enum import Enum
|
|
4
4
|
from typing import Any
|
|
5
5
|
from uuid import UUID, uuid4
|
|
@@ -61,7 +61,7 @@ class Notification:
|
|
|
61
61
|
attempts: int = 0
|
|
62
62
|
max_attempts: int = 3
|
|
63
63
|
error_detail: str | None = None
|
|
64
|
-
created_at: datetime = field(default_factory=datetime.
|
|
64
|
+
created_at: datetime = field(default_factory=lambda: datetime.now(timezone.utc))
|
|
65
65
|
sent_at: datetime | None = None
|
|
66
66
|
delivered_at: datetime | None = None
|
|
67
67
|
|
|
@@ -75,7 +75,7 @@ class Notification:
|
|
|
75
75
|
self.status = NotificationStatus.SENT
|
|
76
76
|
self.provider_used = provider
|
|
77
77
|
self.provider_message_id = provider_message_id
|
|
78
|
-
self.sent_at = datetime.
|
|
78
|
+
self.sent_at = datetime.now(timezone.utc)
|
|
79
79
|
logger.info("Notification sent — awaiting delivery confirmation", extra={
|
|
80
80
|
"notification_id": str(self.id),
|
|
81
81
|
"provider": provider,
|
|
@@ -90,7 +90,7 @@ class Notification:
|
|
|
90
90
|
"notification_id": str(self.id), "current_status": self.status,
|
|
91
91
|
})
|
|
92
92
|
self.status = NotificationStatus.DELIVERED
|
|
93
|
-
self.delivered_at = datetime.
|
|
93
|
+
self.delivered_at = datetime.now(timezone.utc)
|
|
94
94
|
logger.info("Notification delivered", extra={
|
|
95
95
|
"notification_id": str(self.id),
|
|
96
96
|
"provider": self.provider_used,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from dataclasses import dataclass, field
|
|
2
|
-
from datetime import datetime
|
|
2
|
+
from datetime import datetime, timezone
|
|
3
3
|
from uuid import UUID
|
|
4
4
|
|
|
5
5
|
|
|
@@ -8,14 +8,14 @@ class NotificationQueued:
|
|
|
8
8
|
notification_id: UUID
|
|
9
9
|
channel: str
|
|
10
10
|
recipient: str
|
|
11
|
-
occurred_at: datetime = field(default_factory=datetime.
|
|
11
|
+
occurred_at: datetime = field(default_factory=lambda: datetime.now(timezone.utc))
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
@dataclass(frozen=True)
|
|
15
15
|
class NotificationSent:
|
|
16
16
|
notification_id: UUID
|
|
17
17
|
provider: str
|
|
18
|
-
occurred_at: datetime = field(default_factory=datetime.
|
|
18
|
+
occurred_at: datetime = field(default_factory=lambda: datetime.now(timezone.utc))
|
|
19
19
|
|
|
20
20
|
|
|
21
21
|
@dataclass(frozen=True)
|
|
@@ -23,4 +23,4 @@ class NotificationFailed:
|
|
|
23
23
|
notification_id: UUID
|
|
24
24
|
reason: str
|
|
25
25
|
attempts: int
|
|
26
|
-
occurred_at: datetime = field(default_factory=datetime.
|
|
26
|
+
occurred_at: datetime = field(default_factory=lambda: datetime.now(timezone.utc))
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
from django.contrib import admin
|
|
2
|
+
|
|
3
|
+
from notifyfork.core.infrastructure.models import NotificationTemplateModel
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
@admin.register(NotificationTemplateModel)
|
|
7
|
+
class NotificationTemplateAdmin(admin.ModelAdmin):
|
|
8
|
+
list_display = ("id", "mode", "body_kind", "is_active", "updated_at")
|
|
9
|
+
list_filter = ("mode", "is_active")
|
|
10
|
+
search_fields = ("id",)
|
|
11
|
+
readonly_fields = ("created_at", "updated_at")
|
|
12
|
+
|
|
13
|
+
fieldsets = (
|
|
14
|
+
(None, {"fields": ("id", "mode", "is_active")}),
|
|
15
|
+
(
|
|
16
|
+
"Conteúdo",
|
|
17
|
+
{
|
|
18
|
+
"fields": ("body", "subject"),
|
|
19
|
+
"description": (
|
|
20
|
+
"Modo LOCAL: \"body\" é o texto/HTML enviado, com $variaveis "
|
|
21
|
+
"(ex: \"Seu código é: $code\"). "
|
|
22
|
+
"Modo EXTERNAL: \"body\" NÃO é texto de mensagem — é o ID do "
|
|
23
|
+
"template no provider. Para WhatsApp (Twilio) é o Content SID "
|
|
24
|
+
"(HXxxx); para SendGrid é o Dynamic Template ID (d-xxxx)."
|
|
25
|
+
),
|
|
26
|
+
},
|
|
27
|
+
),
|
|
28
|
+
("Mapeamento de variáveis", {"fields": ("variable_mapping",)}),
|
|
29
|
+
("Timestamps", {"fields": ("created_at", "updated_at")}),
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
@admin.display(description="body é...")
|
|
33
|
+
def body_kind(self, obj: NotificationTemplateModel) -> str:
|
|
34
|
+
if obj.mode == NotificationTemplateModel.ModeChoices.EXTERNAL:
|
|
35
|
+
return f"ID externo: {obj.body[:24]}"
|
|
36
|
+
return f"conteúdo local: {obj.body[:40]}"
|
{notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/core/infrastructure/providers/twilio_provider.py
RENAMED
|
@@ -51,7 +51,7 @@ class TwilioSMSProvider(NotificationProvider):
|
|
|
51
51
|
return ProviderResult(success=True, provider_name=self.name, external_id=message.sid)
|
|
52
52
|
|
|
53
53
|
except TwilioRestException as e:
|
|
54
|
-
logger.error("Twilio SMS error", extra={"code": e.code, "
|
|
54
|
+
logger.error("Twilio SMS error", extra={"code": e.code, "twilio_message": e.msg})
|
|
55
55
|
return ProviderResult(
|
|
56
56
|
success=False, provider_name=self.name, error=f"Twilio [{e.code}]: {e.msg}"
|
|
57
57
|
)
|
{notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/core/infrastructure/providers/whatsapp_provider.py
RENAMED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import json
|
|
1
2
|
import logging
|
|
2
3
|
from typing import Any
|
|
3
4
|
|
|
@@ -99,7 +100,7 @@ class TwilioWhatsAppProvider(NotificationProvider):
|
|
|
99
100
|
try:
|
|
100
101
|
message = self._client.messages.create(
|
|
101
102
|
content_sid=template.external_template_id,
|
|
102
|
-
content_variables=
|
|
103
|
+
content_variables=json.dumps(translated), # Twilio expects JSON string
|
|
103
104
|
from_=self._from_number,
|
|
104
105
|
to=to,
|
|
105
106
|
)
|
|
@@ -107,7 +108,10 @@ class TwilioWhatsAppProvider(NotificationProvider):
|
|
|
107
108
|
success=True, provider_name=self.name, external_id=message.sid
|
|
108
109
|
)
|
|
109
110
|
except TwilioRestException as e:
|
|
110
|
-
logger.error(
|
|
111
|
+
logger.error(
|
|
112
|
+
"WhatsApp external template error",
|
|
113
|
+
extra={"code": e.code, "twilio_message": e.msg},
|
|
114
|
+
)
|
|
111
115
|
return ProviderResult(
|
|
112
116
|
success=False,
|
|
113
117
|
provider_name=self.name,
|
|
@@ -21,6 +21,7 @@ class DjangoNotificationRepository(NotificationRepository):
|
|
|
21
21
|
"context": notification.context,
|
|
22
22
|
"status": notification.status.value,
|
|
23
23
|
"provider_used": notification.provider_used,
|
|
24
|
+
"provider_message_id": notification.provider_message_id,
|
|
24
25
|
"attempts": notification.attempts,
|
|
25
26
|
"max_attempts": notification.max_attempts,
|
|
26
27
|
"error_detail": notification.error_detail,
|
|
@@ -64,6 +65,7 @@ class DjangoNotificationRepository(NotificationRepository):
|
|
|
64
65
|
created_at=obj.created_at,
|
|
65
66
|
sent_at=obj.sent_at,
|
|
66
67
|
provider_used=obj.provider_used,
|
|
68
|
+
provider_message_id=obj.provider_message_id,
|
|
67
69
|
)
|
|
68
70
|
n.status = NotificationStatus(obj.status)
|
|
69
71
|
return n
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "notifyfork"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.3"
|
|
8
8
|
description = "Provider-agnostic notification gateway for Django. Send to SMS, Email, WhatsApp, Push, and Slack via a single API."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = { file = "LICENSE" }
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/core/application/dtos/send_notification_dto.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/core/application/interfaces/template_repository.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/core/infrastructure/migrations/0001_initial.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/core/infrastructure/models/notification_model.py
RENAMED
|
File without changes
|
|
File without changes
|
{notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/core/infrastructure/providers/firebase_provider.py
RENAMED
|
File without changes
|
{notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/core/infrastructure/providers/resend_provider.py
RENAMED
|
File without changes
|
{notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/core/infrastructure/providers/sendgrid_provider.py
RENAMED
|
File without changes
|
{notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/core/infrastructure/providers/slack_provider.py
RENAMED
|
File without changes
|
{notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/core/infrastructure/providers/smtp_provider.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{notifyfork-0.1.2 → notifyfork-0.1.3}/notifyfork/core/infrastructure/repositories/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{notifyfork-0.1.2 → notifyfork-0.1.3}/tests/unit/application/test_send_notification_use_case.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|