python-missive 0.2.0__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.
Files changed (100) hide show
  1. python_missive-0.2.0/PKG-INFO +152 -0
  2. python_missive-0.2.0/README.md +134 -0
  3. python_missive-0.2.0/pyproject.toml +55 -0
  4. python_missive-0.2.0/setup.cfg +4 -0
  5. python_missive-0.2.0/src/pymissive/__init__.py +3 -0
  6. python_missive-0.2.0/src/pymissive/__main__.py +9 -0
  7. python_missive-0.2.0/src/pymissive/archives/__init__.py +142 -0
  8. python_missive-0.2.0/src/pymissive/archives/__main__.py +9 -0
  9. python_missive-0.2.0/src/pymissive/archives/address.py +272 -0
  10. python_missive-0.2.0/src/pymissive/archives/address_backends/__init__.py +29 -0
  11. python_missive-0.2.0/src/pymissive/archives/address_backends/base.py +610 -0
  12. python_missive-0.2.0/src/pymissive/archives/address_backends/geoapify.py +221 -0
  13. python_missive-0.2.0/src/pymissive/archives/address_backends/geocode_earth.py +210 -0
  14. python_missive-0.2.0/src/pymissive/archives/address_backends/google_maps.py +371 -0
  15. python_missive-0.2.0/src/pymissive/archives/address_backends/here.py +348 -0
  16. python_missive-0.2.0/src/pymissive/archives/address_backends/locationiq.py +271 -0
  17. python_missive-0.2.0/src/pymissive/archives/address_backends/mapbox.py +314 -0
  18. python_missive-0.2.0/src/pymissive/archives/address_backends/maps_co.py +257 -0
  19. python_missive-0.2.0/src/pymissive/archives/address_backends/nominatim.py +348 -0
  20. python_missive-0.2.0/src/pymissive/archives/address_backends/opencage.py +292 -0
  21. python_missive-0.2.0/src/pymissive/archives/address_backends/pelias_mixin.py +181 -0
  22. python_missive-0.2.0/src/pymissive/archives/address_backends/photon.py +322 -0
  23. python_missive-0.2.0/src/pymissive/archives/cli.py +42 -0
  24. python_missive-0.2.0/src/pymissive/archives/helpers.py +45 -0
  25. python_missive-0.2.0/src/pymissive/archives/missive.py +64 -0
  26. python_missive-0.2.0/src/pymissive/archives/providers/__init__.py +167 -0
  27. python_missive-0.2.0/src/pymissive/archives/providers/apn.py +171 -0
  28. python_missive-0.2.0/src/pymissive/archives/providers/ar24.py +204 -0
  29. python_missive-0.2.0/src/pymissive/archives/providers/base/__init__.py +203 -0
  30. python_missive-0.2.0/src/pymissive/archives/providers/base/_attachments.py +166 -0
  31. python_missive-0.2.0/src/pymissive/archives/providers/base/branded.py +341 -0
  32. python_missive-0.2.0/src/pymissive/archives/providers/base/common.py +781 -0
  33. python_missive-0.2.0/src/pymissive/archives/providers/base/email.py +422 -0
  34. python_missive-0.2.0/src/pymissive/archives/providers/base/email_message.py +85 -0
  35. python_missive-0.2.0/src/pymissive/archives/providers/base/monitoring.py +150 -0
  36. python_missive-0.2.0/src/pymissive/archives/providers/base/notification.py +187 -0
  37. python_missive-0.2.0/src/pymissive/archives/providers/base/postal.py +742 -0
  38. python_missive-0.2.0/src/pymissive/archives/providers/base/postal_defaults.py +26 -0
  39. python_missive-0.2.0/src/pymissive/archives/providers/base/sms.py +213 -0
  40. python_missive-0.2.0/src/pymissive/archives/providers/base/voice_call.py +82 -0
  41. python_missive-0.2.0/src/pymissive/archives/providers/brevo.py +363 -0
  42. python_missive-0.2.0/src/pymissive/archives/providers/certeurope.py +249 -0
  43. python_missive-0.2.0/src/pymissive/archives/providers/django_email.py +182 -0
  44. python_missive-0.2.0/src/pymissive/archives/providers/fcm.py +91 -0
  45. python_missive-0.2.0/src/pymissive/archives/providers/laposte.py +392 -0
  46. python_missive-0.2.0/src/pymissive/archives/providers/maileva.py +511 -0
  47. python_missive-0.2.0/src/pymissive/archives/providers/mailgun.py +118 -0
  48. python_missive-0.2.0/src/pymissive/archives/providers/messenger.py +74 -0
  49. python_missive-0.2.0/src/pymissive/archives/providers/notification.py +112 -0
  50. python_missive-0.2.0/src/pymissive/archives/providers/sendgrid.py +160 -0
  51. python_missive-0.2.0/src/pymissive/archives/providers/ses.py +185 -0
  52. python_missive-0.2.0/src/pymissive/archives/providers/signal.py +68 -0
  53. python_missive-0.2.0/src/pymissive/archives/providers/slack.py +80 -0
  54. python_missive-0.2.0/src/pymissive/archives/providers/smtp.py +190 -0
  55. python_missive-0.2.0/src/pymissive/archives/providers/teams.py +91 -0
  56. python_missive-0.2.0/src/pymissive/archives/providers/telegram.py +69 -0
  57. python_missive-0.2.0/src/pymissive/archives/providers/twilio.py +310 -0
  58. python_missive-0.2.0/src/pymissive/archives/providers/vonage.py +208 -0
  59. python_missive-0.2.0/src/pymissive/archives/sender.py +339 -0
  60. python_missive-0.2.0/src/pymissive/archives/status.py +22 -0
  61. python_missive-0.2.0/src/pymissive/cli.py +42 -0
  62. python_missive-0.2.0/src/pymissive/config.py +397 -0
  63. python_missive-0.2.0/src/pymissive/helpers.py +0 -0
  64. python_missive-0.2.0/src/pymissive/providers/apn.py +8 -0
  65. python_missive-0.2.0/src/pymissive/providers/ar24.py +8 -0
  66. python_missive-0.2.0/src/pymissive/providers/base/__init__.py +64 -0
  67. python_missive-0.2.0/src/pymissive/providers/base/acknowledgement.py +6 -0
  68. python_missive-0.2.0/src/pymissive/providers/base/attachments.py +10 -0
  69. python_missive-0.2.0/src/pymissive/providers/base/branded.py +16 -0
  70. python_missive-0.2.0/src/pymissive/providers/base/email.py +2 -0
  71. python_missive-0.2.0/src/pymissive/providers/base/notification.py +2 -0
  72. python_missive-0.2.0/src/pymissive/providers/base/postal.py +2 -0
  73. python_missive-0.2.0/src/pymissive/providers/base/sms.py +2 -0
  74. python_missive-0.2.0/src/pymissive/providers/base/voice_call.py +2 -0
  75. python_missive-0.2.0/src/pymissive/providers/brevo.py +420 -0
  76. python_missive-0.2.0/src/pymissive/providers/certeurope.py +8 -0
  77. python_missive-0.2.0/src/pymissive/providers/django_email.py +8 -0
  78. python_missive-0.2.0/src/pymissive/providers/fcm.py +8 -0
  79. python_missive-0.2.0/src/pymissive/providers/laposte.py +8 -0
  80. python_missive-0.2.0/src/pymissive/providers/maileva.py +8 -0
  81. python_missive-0.2.0/src/pymissive/providers/mailgun.py +8 -0
  82. python_missive-0.2.0/src/pymissive/providers/messenger.py +8 -0
  83. python_missive-0.2.0/src/pymissive/providers/notification.py +8 -0
  84. python_missive-0.2.0/src/pymissive/providers/partner.py +650 -0
  85. python_missive-0.2.0/src/pymissive/providers/scaleway.py +498 -0
  86. python_missive-0.2.0/src/pymissive/providers/sendgrid.py +8 -0
  87. python_missive-0.2.0/src/pymissive/providers/ses.py +8 -0
  88. python_missive-0.2.0/src/pymissive/providers/signal.py +8 -0
  89. python_missive-0.2.0/src/pymissive/providers/slack.py +8 -0
  90. python_missive-0.2.0/src/pymissive/providers/smtp.py +8 -0
  91. python_missive-0.2.0/src/pymissive/providers/teams.py +8 -0
  92. python_missive-0.2.0/src/pymissive/providers/telegram.py +8 -0
  93. python_missive-0.2.0/src/pymissive/providers/twilio.py +8 -0
  94. python_missive-0.2.0/src/pymissive/providers/vonage.py +8 -0
  95. python_missive-0.2.0/src/python_missive.egg-info/PKG-INFO +152 -0
  96. python_missive-0.2.0/src/python_missive.egg-info/SOURCES.txt +98 -0
  97. python_missive-0.2.0/src/python_missive.egg-info/dependency_links.txt +1 -0
  98. python_missive-0.2.0/src/python_missive.egg-info/entry_points.txt +2 -0
  99. python_missive-0.2.0/src/python_missive.egg-info/requires.txt +10 -0
  100. python_missive-0.2.0/src/python_missive.egg-info/top_level.txt +1 -0
@@ -0,0 +1,152 @@
1
+ Metadata-Version: 2.4
2
+ Name: python-missive
3
+ Version: 0.2.0
4
+ Summary: Framework-agnostic messaging library for multi-channel communication.
5
+ Author-email: Charl <charl@example.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://example.com/python-missive
8
+ Requires-Python: >=3.10
9
+ Description-Content-Type: text/markdown
10
+ Provides-Extra: scaleway
11
+ Requires-Dist: boto3>=1.34; extra == "scaleway"
12
+ Requires-Dist: scaleway>=2.0; extra == "scaleway"
13
+ Provides-Extra: dev
14
+ Requires-Dist: pytest>=8.3; extra == "dev"
15
+ Requires-Dist: ruff>=0.5; extra == "dev"
16
+ Requires-Dist: flake8-simplify>=0.21; extra == "dev"
17
+ Requires-Dist: flake8-docstrings>=1.7; extra == "dev"
18
+
19
+ # python-missive
20
+
21
+ Bibliothèque Python légère et agnostique pour l'envoi de missives multi-canaux (emails, SMS, notifications push, courrier postal, etc.).
22
+
23
+ ## Présentation
24
+
25
+ **python-missive** est une bibliothèque Python framework-agnostic qui fournit des providers unifiés pour l'envoi de messages multi-canaux. Elle sert de base à **django-missive** et peut être utilisée indépendamment dans n'importe quel projet Python.
26
+
27
+ ### Fonctionnalités principales
28
+
29
+ - 🔌 **15+ providers intégrés** pour différents canaux de communication
30
+ - 📧 **Email** : SendGrid, Mailgun, SES, Brevo, SMTP, Django Email
31
+ - 📱 **SMS & Voix** : Twilio, Vonage, SMSPartner
32
+ - 💬 **Messaging** : Telegram, Signal, Messenger, Slack, Teams
33
+ - 📮 **Courrier postal & LRE** : La Poste, Maileva, AR24, Certeurope
34
+ - 🔔 **Notifications push** : FCM (Firebase), APN (Apple), In-App
35
+ - 🏗️ **Architecture modulaire** basée sur ProviderKit
36
+ - ✅ **Framework-agnostic** : utilisable avec ou sans framework
37
+ - 🎯 **Type hints complets** et documentation
38
+
39
+ ## Installation
40
+
41
+ ```bash
42
+ # Installation basique
43
+ pip install python-missive
44
+
45
+ # Avec dépendances pour providers spécifiques
46
+ pip install python-missive[email] # Providers email
47
+ pip install python-missive[sms] # SMS et vocal
48
+ pip install python-missive[messaging] # Telegram, Signal, etc.
49
+ pip install python-missive[push] # FCM, APN
50
+ pip install python-missive[postal] # Courrier postal
51
+ pip install python-missive[all] # Tous les providers
52
+ ```
53
+
54
+ ## Usage rapide
55
+
56
+ ```python
57
+ from pymissive.providers.sendgrid import SendGridProvider
58
+
59
+ # Configurer le provider
60
+ provider = SendGridProvider(config={
61
+ 'SENDGRID_API_KEY': 'your-api-key'
62
+ })
63
+
64
+ # Envoyer un email
65
+ result = provider.send_email(
66
+ from_email='sender@example.com',
67
+ to_email='recipient@example.com',
68
+ subject='Hello',
69
+ body='<p>Message content</p>'
70
+ )
71
+ ```
72
+
73
+ ## Providers disponibles
74
+
75
+ ### Email
76
+ - `DjangoEmailProvider` - Utilise le backend email Django
77
+ - `SMTPProvider` - SMTP générique
78
+ - `SendGridProvider` - SendGrid API
79
+ - `MailgunProvider` - Mailgun API
80
+ - `SESProvider` - Amazon SES
81
+ - `BrevoProvider` - Brevo (ex-Sendinblue)
82
+ - `ScalewayProvider` - Scaleway Transactional Email
83
+
84
+ ### SMS & Voix
85
+ - `TwilioProvider` - Twilio SMS et appels vocaux
86
+ - `VonageProvider` - Vonage (ex-Nexmo)
87
+ - `SMSPartnerProvider` - SMSPartner
88
+
89
+ ### Messaging
90
+ - `TelegramProvider` - Telegram Bot API
91
+ - `SignalProvider` - Signal Messenger
92
+ - `MessengerProvider` - Facebook Messenger
93
+ - `SlackProvider` - Slack
94
+ - `TeamsProvider` - Microsoft Teams
95
+
96
+ ### Courrier postal & LRE
97
+ - `LaPosteProvider` - La Poste (courrier physique)
98
+ - `MailevaProvider` - Maileva
99
+ - `AR24Provider` - AR24 (LRE)
100
+ - `CerteuropeProvider` - Certeurope
101
+
102
+ ### Notifications push
103
+ - `FCMProvider` - Firebase Cloud Messaging
104
+ - `APNProvider` - Apple Push Notification
105
+ - `InAppNotificationProvider` - Notifications in-app
106
+
107
+ ## Architecture
108
+
109
+ La bibliothèque utilise **ProviderKit** pour la gestion des providers :
110
+
111
+ ```python
112
+ from pymissive.providers import get_missive_providers
113
+
114
+ # Découvrir tous les providers disponibles
115
+ providers = get_missive_providers()
116
+
117
+ # Filtrer par type de service
118
+ email_providers = [p for p in providers if 'email' in p.services]
119
+ ```
120
+
121
+ ## Documentation
122
+
123
+ Pour plus de détails, consultez la documentation dans le dossier `docs/` :
124
+
125
+ - `docs/purpose.md` - Objectifs et architecture du projet
126
+ - `docs/structure.md` - Structure des modules et organisation
127
+ - `docs/development.md` - Guidelines de développement
128
+ - `docs/AI.md` - Contrat pour assistants IA
129
+
130
+ ## Développement
131
+
132
+ ```bash
133
+ # Créer un environnement virtuel
134
+ python service.py dev venv
135
+
136
+ # Installer en mode développement
137
+ python service.py dev install-dev
138
+
139
+ # Exécuter les tests
140
+ python service.py dev test
141
+
142
+ # Formater le code
143
+ python service.py dev format
144
+
145
+ # Lancer tous les checks qualité
146
+ python service.py quality check
147
+ ```
148
+
149
+ ## Licence
150
+
151
+ Ce projet est sous licence MIT. Voir le fichier `LICENSE` pour plus de détails.
152
+
@@ -0,0 +1,134 @@
1
+ # python-missive
2
+
3
+ Bibliothèque Python légère et agnostique pour l'envoi de missives multi-canaux (emails, SMS, notifications push, courrier postal, etc.).
4
+
5
+ ## Présentation
6
+
7
+ **python-missive** est une bibliothèque Python framework-agnostic qui fournit des providers unifiés pour l'envoi de messages multi-canaux. Elle sert de base à **django-missive** et peut être utilisée indépendamment dans n'importe quel projet Python.
8
+
9
+ ### Fonctionnalités principales
10
+
11
+ - 🔌 **15+ providers intégrés** pour différents canaux de communication
12
+ - 📧 **Email** : SendGrid, Mailgun, SES, Brevo, SMTP, Django Email
13
+ - 📱 **SMS & Voix** : Twilio, Vonage, SMSPartner
14
+ - 💬 **Messaging** : Telegram, Signal, Messenger, Slack, Teams
15
+ - 📮 **Courrier postal & LRE** : La Poste, Maileva, AR24, Certeurope
16
+ - 🔔 **Notifications push** : FCM (Firebase), APN (Apple), In-App
17
+ - 🏗️ **Architecture modulaire** basée sur ProviderKit
18
+ - ✅ **Framework-agnostic** : utilisable avec ou sans framework
19
+ - 🎯 **Type hints complets** et documentation
20
+
21
+ ## Installation
22
+
23
+ ```bash
24
+ # Installation basique
25
+ pip install python-missive
26
+
27
+ # Avec dépendances pour providers spécifiques
28
+ pip install python-missive[email] # Providers email
29
+ pip install python-missive[sms] # SMS et vocal
30
+ pip install python-missive[messaging] # Telegram, Signal, etc.
31
+ pip install python-missive[push] # FCM, APN
32
+ pip install python-missive[postal] # Courrier postal
33
+ pip install python-missive[all] # Tous les providers
34
+ ```
35
+
36
+ ## Usage rapide
37
+
38
+ ```python
39
+ from pymissive.providers.sendgrid import SendGridProvider
40
+
41
+ # Configurer le provider
42
+ provider = SendGridProvider(config={
43
+ 'SENDGRID_API_KEY': 'your-api-key'
44
+ })
45
+
46
+ # Envoyer un email
47
+ result = provider.send_email(
48
+ from_email='sender@example.com',
49
+ to_email='recipient@example.com',
50
+ subject='Hello',
51
+ body='<p>Message content</p>'
52
+ )
53
+ ```
54
+
55
+ ## Providers disponibles
56
+
57
+ ### Email
58
+ - `DjangoEmailProvider` - Utilise le backend email Django
59
+ - `SMTPProvider` - SMTP générique
60
+ - `SendGridProvider` - SendGrid API
61
+ - `MailgunProvider` - Mailgun API
62
+ - `SESProvider` - Amazon SES
63
+ - `BrevoProvider` - Brevo (ex-Sendinblue)
64
+ - `ScalewayProvider` - Scaleway Transactional Email
65
+
66
+ ### SMS & Voix
67
+ - `TwilioProvider` - Twilio SMS et appels vocaux
68
+ - `VonageProvider` - Vonage (ex-Nexmo)
69
+ - `SMSPartnerProvider` - SMSPartner
70
+
71
+ ### Messaging
72
+ - `TelegramProvider` - Telegram Bot API
73
+ - `SignalProvider` - Signal Messenger
74
+ - `MessengerProvider` - Facebook Messenger
75
+ - `SlackProvider` - Slack
76
+ - `TeamsProvider` - Microsoft Teams
77
+
78
+ ### Courrier postal & LRE
79
+ - `LaPosteProvider` - La Poste (courrier physique)
80
+ - `MailevaProvider` - Maileva
81
+ - `AR24Provider` - AR24 (LRE)
82
+ - `CerteuropeProvider` - Certeurope
83
+
84
+ ### Notifications push
85
+ - `FCMProvider` - Firebase Cloud Messaging
86
+ - `APNProvider` - Apple Push Notification
87
+ - `InAppNotificationProvider` - Notifications in-app
88
+
89
+ ## Architecture
90
+
91
+ La bibliothèque utilise **ProviderKit** pour la gestion des providers :
92
+
93
+ ```python
94
+ from pymissive.providers import get_missive_providers
95
+
96
+ # Découvrir tous les providers disponibles
97
+ providers = get_missive_providers()
98
+
99
+ # Filtrer par type de service
100
+ email_providers = [p for p in providers if 'email' in p.services]
101
+ ```
102
+
103
+ ## Documentation
104
+
105
+ Pour plus de détails, consultez la documentation dans le dossier `docs/` :
106
+
107
+ - `docs/purpose.md` - Objectifs et architecture du projet
108
+ - `docs/structure.md` - Structure des modules et organisation
109
+ - `docs/development.md` - Guidelines de développement
110
+ - `docs/AI.md` - Contrat pour assistants IA
111
+
112
+ ## Développement
113
+
114
+ ```bash
115
+ # Créer un environnement virtuel
116
+ python service.py dev venv
117
+
118
+ # Installer en mode développement
119
+ python service.py dev install-dev
120
+
121
+ # Exécuter les tests
122
+ python service.py dev test
123
+
124
+ # Formater le code
125
+ python service.py dev format
126
+
127
+ # Lancer tous les checks qualité
128
+ python service.py quality check
129
+ ```
130
+
131
+ ## Licence
132
+
133
+ Ce projet est sous licence MIT. Voir le fichier `LICENSE` pour plus de détails.
134
+
@@ -0,0 +1,55 @@
1
+ [build-system]
2
+ requires = ["setuptools>=69", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "python-missive"
7
+ version = "0.2.0"
8
+ description = "Framework-agnostic messaging library for multi-channel communication."
9
+ authors = [{ name = "Charl", email = "charl@example.com" }]
10
+ readme = "README.md"
11
+ requires-python = ">=3.10"
12
+ license = { text = "MIT" }
13
+ dependencies = []
14
+
15
+ [project.scripts]
16
+ pymissive = "pymissive.cli:main"
17
+
18
+ [project.optional-dependencies]
19
+ scaleway = ["boto3>=1.34", "scaleway>=2.0"]
20
+ dev = [
21
+ "pytest>=8.3",
22
+ "ruff>=0.5",
23
+ "flake8-simplify>=0.21",
24
+ "flake8-docstrings>=1.7",
25
+ ]
26
+
27
+ [project.urls]
28
+ Homepage = "https://example.com/python-missive"
29
+
30
+ [tool.setuptools]
31
+ package-dir = { "" = "src" }
32
+
33
+ [tool.setuptools.packages.find]
34
+ where = ["src"]
35
+
36
+ [tool.pytest.ini_options]
37
+ testpaths = ["tests"]
38
+
39
+ [tool.mypy]
40
+ python_version = "3.10"
41
+ warn_return_any = true
42
+ warn_unused_configs = true
43
+ disallow_untyped_defs = false
44
+ ignore_missing_imports = true
45
+ show_error_codes = true
46
+ # Ignore archives directory (old code)
47
+ exclude = [
48
+ "src/pymissive/archives/.*",
49
+ ]
50
+ # Ignore mixin attribute errors (they are provided by BaseProvider)
51
+ [[tool.mypy.overrides]]
52
+ module = [
53
+ "pymissive.providers.base.*",
54
+ ]
55
+ ignore_errors = true
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,3 @@
1
+ """Python Missive - Framework-agnostic messaging library."""
2
+
3
+ __version__ = "0.1.0"
@@ -0,0 +1,9 @@
1
+ from __future__ import annotations
2
+
3
+ from .cli import main
4
+
5
+ if __name__ == "__main__":
6
+ import sys
7
+
8
+ sys.exit(main())
9
+
@@ -0,0 +1,142 @@
1
+ """Lightweight multi-channel messaging helpers."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any, Dict, Optional, Sequence, Union
6
+
7
+ from .address import Address
8
+ from .address_backends import (BaseAddressBackend, GoogleMapsAddressBackend,
9
+ HereAddressBackend, MapboxAddressBackend,
10
+ NominatimAddressBackend, PhotonAddressBackend)
11
+ from .helpers import (
12
+ DEFAULT_MIN_ADDRESS_CONFIDENCE,
13
+ describe_address_backends,
14
+ format_phone_international,
15
+ get_address_backend_by_attribute,
16
+ get_address_backends_from_config,
17
+ get_address_by_reference,
18
+ get_provider_by_attribute,
19
+ search_addresses,
20
+ )
21
+ from .missive import Missive
22
+ from .providers.base.common import BaseProviderCommon
23
+ from .sender import MissiveSender
24
+ from .status import MissiveStatus
25
+
26
+ __all__ = [
27
+ "MissiveStatus",
28
+ "BaseProviderCommon",
29
+ "Address",
30
+ "Missive",
31
+ "MissiveSender",
32
+ "send_missive",
33
+ "format_phone_international",
34
+ "get_address_backends_from_config",
35
+ "get_address_by_reference",
36
+ "search_addresses",
37
+ "get_address_backend_by_attribute",
38
+ "describe_address_backends",
39
+ "get_provider_by_attribute",
40
+ "DEFAULT_MIN_ADDRESS_CONFIDENCE",
41
+ "BaseAddressBackend",
42
+ "GoogleMapsAddressBackend",
43
+ "HereAddressBackend",
44
+ "MapboxAddressBackend",
45
+ "NominatimAddressBackend",
46
+ "PhotonAddressBackend",
47
+ ]
48
+
49
+
50
+ def send_missive(
51
+ missive_type: str,
52
+ body: str,
53
+ subject: Optional[str] = None,
54
+ recipient_email: Optional[str] = None,
55
+ recipient_phone: Optional[str] = None,
56
+ recipient: Optional[Any] = None,
57
+ providers_config: Optional[Union[Sequence[str], Dict[str, Dict[str, Any]]]] = None,
58
+ config: Optional[Dict[str, Any]] = None,
59
+ sandbox: bool = False,
60
+ enable_fallback: bool = True,
61
+ **kwargs: Any,
62
+ ) -> Missive:
63
+ """Send a missive with automatic provider selection and fallback.
64
+
65
+ Args:
66
+ missive_type: Type of missive (EMAIL, SMS, POSTAL, etc.)
67
+ body: Message body/content
68
+ subject: Message subject (required for EMAIL)
69
+ recipient_email: Recipient email address (for EMAIL)
70
+ recipient_phone: Recipient phone number (for SMS, VOICE_CALL)
71
+ recipient: Complex recipient object with metadata (for PUSH_NOTIFICATION, etc.)
72
+ providers_config: Either:
73
+ - List of provider import paths: ["pymissive.providers.brevo.BrevoProvider"]
74
+ - Dict mapping paths to configs: {"path": {"API_KEY": "value"}}
75
+ config: Default configuration dict merged with provider-specific configs
76
+ sandbox: If True, forces sandbox mode for all providers (no real sends)
77
+ enable_fallback: If True, try next provider on failure
78
+ **kwargs: Additional options (provider_options, is_registered, etc.)
79
+
80
+ Returns:
81
+ Missive object with updated status
82
+
83
+ Raises:
84
+ RuntimeError: If all providers fail
85
+ ValueError: If required fields are missing
86
+
87
+ Example:
88
+ >>> missive = send_missive(
89
+ ... "EMAIL",
90
+ ... body="Hello world",
91
+ ... subject="Test",
92
+ ... recipient_email="user@example.com",
93
+ ... )
94
+ >>> print(missive.status)
95
+ MissiveStatus.SENT
96
+ """
97
+ missive_type = missive_type.upper()
98
+
99
+ # Validate required fields based on type
100
+ if missive_type == "EMAIL" and not recipient_email:
101
+ raise ValueError("recipient_email required for EMAIL missives")
102
+ if missive_type == "EMAIL" and not subject:
103
+ raise ValueError("subject required for EMAIL missives")
104
+ if missive_type in ("SMS", "VOICE_CALL") and not recipient_phone:
105
+ raise ValueError(f"recipient_phone required for {missive_type} missives")
106
+ if (
107
+ missive_type in ("POSTAL", "POSTAL_REGISTERED")
108
+ and not recipient
109
+ and not recipient_email
110
+ ):
111
+ raise ValueError(
112
+ f"recipient or recipient_email required for {missive_type} missives"
113
+ )
114
+
115
+ # Create missive object
116
+ missive = Missive(
117
+ missive_type=missive_type,
118
+ body=body,
119
+ subject=subject,
120
+ recipient_email=recipient_email,
121
+ recipient_phone=recipient_phone,
122
+ recipient=recipient,
123
+ provider_options=kwargs.get("provider_options", {}),
124
+ is_registered=kwargs.get("is_registered", missive_type == "POSTAL_REGISTERED"),
125
+ requires_signature=kwargs.get("requires_signature", False),
126
+ )
127
+
128
+ # Create sender and send
129
+ sender = MissiveSender(
130
+ providers_config=providers_config,
131
+ default_config=config,
132
+ sandbox=sandbox,
133
+ )
134
+
135
+ try:
136
+ sender.send(missive, enable_fallback=enable_fallback)
137
+ except Exception as e:
138
+ missive.status = MissiveStatus.FAILED
139
+ missive.error_message = str(e)
140
+ raise
141
+
142
+ return missive
@@ -0,0 +1,9 @@
1
+ from __future__ import annotations
2
+
3
+ from .cli import main
4
+
5
+ if __name__ == "__main__":
6
+ import sys
7
+
8
+ sys.exit(main())
9
+