haskimail 1.0.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.
- haskimail-1.0.0/.github/workflows/publish.yml +46 -0
- haskimail-1.0.0/.gitignore +19 -0
- haskimail-1.0.0/CHANGELOG.md +14 -0
- haskimail-1.0.0/LICENSE +21 -0
- haskimail-1.0.0/PKG-INFO +380 -0
- haskimail-1.0.0/README.md +352 -0
- haskimail-1.0.0/examples/error_handling.py +43 -0
- haskimail-1.0.0/examples/manage_bounces.py +22 -0
- haskimail-1.0.0/examples/manage_domains.py +28 -0
- haskimail-1.0.0/examples/manage_templates.py +32 -0
- haskimail-1.0.0/examples/send_email.py +19 -0
- haskimail-1.0.0/examples/send_email_batch.py +28 -0
- haskimail-1.0.0/examples/send_with_attachments.py +28 -0
- haskimail-1.0.0/examples/send_with_template.py +19 -0
- haskimail-1.0.0/haskimail/__init__.py +42 -0
- haskimail-1.0.0/haskimail/account_client.py +141 -0
- haskimail-1.0.0/haskimail/client.py +106 -0
- haskimail-1.0.0/haskimail/exceptions.py +126 -0
- haskimail-1.0.0/haskimail/server_client.py +306 -0
- haskimail-1.0.0/haskimail.egg-info/PKG-INFO +380 -0
- haskimail-1.0.0/haskimail.egg-info/SOURCES.txt +47 -0
- haskimail-1.0.0/haskimail.egg-info/dependency_links.txt +1 -0
- haskimail-1.0.0/haskimail.egg-info/requires.txt +1 -0
- haskimail-1.0.0/haskimail.egg-info/top_level.txt +1 -0
- haskimail-1.0.0/haskimail.png +0 -0
- haskimail-1.0.0/pyproject.toml +55 -0
- haskimail-1.0.0/setup.cfg +4 -0
- haskimail-1.0.0/tests/__init__.py +0 -0
- haskimail-1.0.0/tests/conftest.py +46 -0
- haskimail-1.0.0/tests/test_account_client.py +112 -0
- haskimail-1.0.0/tests/test_server_client.py +182 -0
- haskimail-1.0.0/wiki/Home.md +31 -0
- haskimail-1.0.0/wiki/Push-/321/210/320/260/320/261/320/273/320/276/320/275/320/276/320/262.md +46 -0
- haskimail-1.0.0/wiki//320/222/320/265/320/261/321/205/321/203/320/272/320/270.md +75 -0
- haskimail-1.0.0/wiki//320/222/320/276/320/267/320/262/321/200/320/260/321/202/321/213-(Bounces).md +72 -0
- haskimail-1.0.0/wiki//320/224/320/276/320/274/320/265/320/275/321/213.md +87 -0
- haskimail-1.0.0/wiki//320/230/321/201/321/205/320/276/320/264/321/217/321/211/320/270/320/265-/321/201/320/276/320/276/320/261/321/211/320/265/320/275/320/270/321/217.md +51 -0
- haskimail-1.0.0/wiki//320/232/320/260/320/275/320/260/320/273/321/213-/321/201/320/276/320/276/320/261/321/211/320/265/320/275/320/270/320/271.md +77 -0
- haskimail-1.0.0/wiki//320/236/320/261/321/200/320/260/320/261/320/276/321/202/320/272/320/260-/320/276/321/210/320/270/320/261/320/276/320/272.md +99 -0
- haskimail-1.0.0/wiki//320/236/321/202/320/272/321/200/321/213/321/202/320/270/321/217-/320/270-/320/272/320/273/320/270/320/272/320/270.md +78 -0
- haskimail-1.0.0/wiki//320/236/321/202/320/277/321/200/320/260/320/262/320/272/320/260-/320/277/320/270/321/201/320/265/320/274.md +94 -0
- haskimail-1.0.0/wiki//320/237/320/260/320/272/320/265/321/202/320/275/320/260/321/217-/320/276/321/202/320/277/321/200/320/260/320/262/320/272/320/260.md +69 -0
- haskimail-1.0.0/wiki//320/237/320/276/320/264/320/277/320/270/321/201/320/270-/320/276/321/202/320/277/321/200/320/260/320/262/320/270/321/202/320/265/320/273/320/265/320/271.md +75 -0
- haskimail-1.0.0/wiki//320/241/320/265/321/200/320/262/320/265/321/200/321/213.md +59 -0
- haskimail-1.0.0/wiki//320/241/321/202/320/260/321/202/320/270/321/201/321/202/320/270/320/272/320/260.md +117 -0
- haskimail-1.0.0/wiki//320/241/321/202/320/276/320/277-/320/273/320/270/321/201/321/202/321/213-(Suppressions).md +58 -0
- haskimail-1.0.0/wiki//320/243/320/264/320/260/320/273/320/265/320/275/320/270/320/265-/320/264/320/260/320/275/320/275/321/213/321/205.md +29 -0
- haskimail-1.0.0/wiki//320/243/321/201/321/202/320/260/320/275/320/276/320/262/320/272/320/260-/320/270-/320/275/320/260/321/201/321/202/321/200/320/276/320/271/320/272/320/260.md +72 -0
- haskimail-1.0.0/wiki//320/250/320/260/320/261/320/273/320/276/320/275/321/213.md +126 -0
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
build:
|
|
9
|
+
name: Build distribution
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
steps:
|
|
12
|
+
- uses: actions/checkout@v4
|
|
13
|
+
|
|
14
|
+
- name: Set up Python
|
|
15
|
+
uses: actions/setup-python@v5
|
|
16
|
+
with:
|
|
17
|
+
python-version: "3.12"
|
|
18
|
+
|
|
19
|
+
- name: Install build tooling
|
|
20
|
+
run: python -m pip install --upgrade build
|
|
21
|
+
|
|
22
|
+
- name: Build sdist and wheel
|
|
23
|
+
run: python -m build
|
|
24
|
+
|
|
25
|
+
- name: Upload artifacts
|
|
26
|
+
uses: actions/upload-artifact@v4
|
|
27
|
+
with:
|
|
28
|
+
name: dist
|
|
29
|
+
path: dist/
|
|
30
|
+
|
|
31
|
+
publish:
|
|
32
|
+
name: Publish to PyPI
|
|
33
|
+
needs: build
|
|
34
|
+
runs-on: ubuntu-latest
|
|
35
|
+
environment: pypi
|
|
36
|
+
permissions:
|
|
37
|
+
id-token: write
|
|
38
|
+
steps:
|
|
39
|
+
- name: Download artifacts
|
|
40
|
+
uses: actions/download-artifact@v4
|
|
41
|
+
with:
|
|
42
|
+
name: dist
|
|
43
|
+
path: dist/
|
|
44
|
+
|
|
45
|
+
- name: Publish to PyPI
|
|
46
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 1.0.0 (2026-06-01)
|
|
4
|
+
|
|
5
|
+
Initial release.
|
|
6
|
+
|
|
7
|
+
- `ServerClient` with full API coverage: email sending, bounces, templates,
|
|
8
|
+
server management, outbound messages, opens, clicks, statistics,
|
|
9
|
+
webhooks, message streams, and suppressions.
|
|
10
|
+
- `AccountClient` with full API coverage: servers, domains, sender signatures,
|
|
11
|
+
template push, and data removals.
|
|
12
|
+
- Typed exception hierarchy matching the HTTP error codes from the Haskimail API.
|
|
13
|
+
- Context manager support for automatic session cleanup.
|
|
14
|
+
- Type hints throughout for IDE autocompletion.
|
haskimail-1.0.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Dashamail
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
haskimail-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,380 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: haskimail
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Official Python client for the Haskimail transactional email API
|
|
5
|
+
Author-email: Dashamail <support@haskimail.ru>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://haskimail.ru
|
|
8
|
+
Project-URL: Documentation, https://haskimail.ru/developer
|
|
9
|
+
Project-URL: Repository, https://github.com/Dashamail/haskimail-python
|
|
10
|
+
Project-URL: Issues, https://github.com/Dashamail/haskimail-python/issues
|
|
11
|
+
Keywords: haskimail,email,transactional,smtp,api
|
|
12
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Topic :: Communications :: Email
|
|
21
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
22
|
+
Classifier: Typing :: Typed
|
|
23
|
+
Requires-Python: >=3.10
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
License-File: LICENSE
|
|
26
|
+
Requires-Dist: requests>=2.28.0
|
|
27
|
+
Dynamic: license-file
|
|
28
|
+
|
|
29
|
+
<a href="https://haskimail.ru">
|
|
30
|
+
<img src="https://github.com/DashaMail/haskimail-python/raw/main/haskimail.png" alt="Haskimail Logo" title="Haskimail" width="120" height="120" align="right">
|
|
31
|
+
</a>
|
|
32
|
+
|
|
33
|
+
# Haskimail Python
|
|
34
|
+
|
|
35
|
+
Официальная Python-библиотека для [Haskimail HTTP API](https://haskimail.ru/developer).
|
|
36
|
+
|
|
37
|
+
[](https://pypi.org/project/haskimail/)
|
|
38
|
+
[](https://opensource.org/licenses/MIT)
|
|
39
|
+
|
|
40
|
+
## Установка
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
pip install haskimail
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Использование
|
|
47
|
+
|
|
48
|
+
### Отправка письма
|
|
49
|
+
|
|
50
|
+
```python
|
|
51
|
+
from haskimail import ServerClient
|
|
52
|
+
|
|
53
|
+
client = ServerClient("ваш-серверный-токен")
|
|
54
|
+
|
|
55
|
+
response = client.send_email({
|
|
56
|
+
"From": "отправитель@домен.ru",
|
|
57
|
+
"To": "получатель@домен.ru",
|
|
58
|
+
"Subject": "Привет от Haskimail!",
|
|
59
|
+
"HtmlBody": "<h1>Привет!</h1><p>Это письмо отправлено через Haskimail.</p>",
|
|
60
|
+
"TextBody": "Привет! Это письмо отправлено через Haskimail.",
|
|
61
|
+
"MessageStream": "outbound",
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
print(f"ID сообщения: {response['MessageID']}")
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Отправка с шаблоном
|
|
68
|
+
|
|
69
|
+
```python
|
|
70
|
+
response = client.send_email_with_template({
|
|
71
|
+
"TemplateId": 42,
|
|
72
|
+
"From": "отправитель@домен.ru",
|
|
73
|
+
"To": "получатель@домен.ru",
|
|
74
|
+
"TemplateModel": {
|
|
75
|
+
"product_name": "Мой Сервис",
|
|
76
|
+
"user_name": "Иван",
|
|
77
|
+
},
|
|
78
|
+
})
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Пакетная отправка
|
|
82
|
+
|
|
83
|
+
```python
|
|
84
|
+
# До 500 писем за один запрос
|
|
85
|
+
responses = client.send_email_batch([
|
|
86
|
+
{
|
|
87
|
+
"From": "отправитель@домен.ru",
|
|
88
|
+
"To": "user1@example.com",
|
|
89
|
+
"Subject": "Привет, User 1!",
|
|
90
|
+
"TextBody": "Сообщение для User 1",
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
"From": "отправитель@домен.ru",
|
|
94
|
+
"To": "user2@example.com",
|
|
95
|
+
"Subject": "Привет, User 2!",
|
|
96
|
+
"TextBody": "Сообщение для User 2",
|
|
97
|
+
},
|
|
98
|
+
])
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Управление возвратами (bounces)
|
|
102
|
+
|
|
103
|
+
```python
|
|
104
|
+
# Получить статистику доставки
|
|
105
|
+
stats = client.get_delivery_statistics()
|
|
106
|
+
|
|
107
|
+
# Список возвратов
|
|
108
|
+
bounces = client.get_bounces(count=50, type="HardBounce")
|
|
109
|
+
|
|
110
|
+
# Реактивировать получателя
|
|
111
|
+
client.activate_bounce(bounce_id=12345)
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Шаблоны
|
|
115
|
+
|
|
116
|
+
```python
|
|
117
|
+
# Список шаблонов
|
|
118
|
+
templates = client.get_templates(count=100)
|
|
119
|
+
|
|
120
|
+
# Создать шаблон
|
|
121
|
+
template = client.create_template({
|
|
122
|
+
"Name": "Приветственное письмо",
|
|
123
|
+
"Subject": "Добро пожаловать, {{name}}!",
|
|
124
|
+
"HtmlBody": "<h1>Привет, {{name}}!</h1>",
|
|
125
|
+
"TextBody": "Привет, {{name}}!",
|
|
126
|
+
})
|
|
127
|
+
|
|
128
|
+
# Редактировать шаблон
|
|
129
|
+
client.edit_template(template["TemplateId"], {
|
|
130
|
+
"Subject": "Обновлённая тема",
|
|
131
|
+
})
|
|
132
|
+
|
|
133
|
+
# Валидировать шаблон
|
|
134
|
+
result = client.validate_template({
|
|
135
|
+
"Subject": "{{subject}}",
|
|
136
|
+
"HtmlBody": "{{content}}",
|
|
137
|
+
"TestRenderModel": {"subject": "Тест", "content": "Привет!"},
|
|
138
|
+
})
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Каналы сообщений (Message Streams)
|
|
142
|
+
|
|
143
|
+
```python
|
|
144
|
+
# Список каналов
|
|
145
|
+
streams = client.get_message_streams()
|
|
146
|
+
|
|
147
|
+
# Создать канал
|
|
148
|
+
stream = client.create_message_stream({
|
|
149
|
+
"ID": "notifications",
|
|
150
|
+
"Name": "Уведомления",
|
|
151
|
+
"MessageStreamType": "Transactional",
|
|
152
|
+
})
|
|
153
|
+
|
|
154
|
+
# Архивировать канал
|
|
155
|
+
client.archive_message_stream("notifications")
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### Стоп-листы (Suppressions)
|
|
159
|
+
|
|
160
|
+
```python
|
|
161
|
+
# Получить стоп-лист для канала
|
|
162
|
+
suppressions = client.get_suppressions("outbound", SuppressionReason="HardBounce")
|
|
163
|
+
|
|
164
|
+
# Добавить в стоп-лист
|
|
165
|
+
client.create_suppressions("outbound", {
|
|
166
|
+
"Suppressions": [{"EmailAddress": "bad@example.com"}]
|
|
167
|
+
})
|
|
168
|
+
|
|
169
|
+
# Удалить из стоп-листа
|
|
170
|
+
client.delete_suppressions("outbound", {
|
|
171
|
+
"Suppressions": [{"EmailAddress": "bad@example.com"}]
|
|
172
|
+
})
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### Вебхуки
|
|
176
|
+
|
|
177
|
+
```python
|
|
178
|
+
# Создать вебхук
|
|
179
|
+
webhook = client.create_webhook({
|
|
180
|
+
"Url": "https://example.com/webhooks/haskimail",
|
|
181
|
+
"MessageStream": "outbound",
|
|
182
|
+
"Triggers": {
|
|
183
|
+
"Open": {"Enabled": True},
|
|
184
|
+
"Click": {"Enabled": True},
|
|
185
|
+
"Delivery": {"Enabled": True},
|
|
186
|
+
"Bounce": {"Enabled": True, "IncludeContent": True},
|
|
187
|
+
},
|
|
188
|
+
})
|
|
189
|
+
|
|
190
|
+
# Список вебхуков
|
|
191
|
+
webhooks = client.get_webhooks()
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### Статистика
|
|
195
|
+
|
|
196
|
+
```python
|
|
197
|
+
# Общий обзор
|
|
198
|
+
overview = client.get_outbound_overview(
|
|
199
|
+
fromdate="2026-01-01",
|
|
200
|
+
todate="2026-06-01",
|
|
201
|
+
messagestream="outbound",
|
|
202
|
+
)
|
|
203
|
+
|
|
204
|
+
# Отправки по дням
|
|
205
|
+
sent = client.get_sent_counts(tag="welcome")
|
|
206
|
+
|
|
207
|
+
# Открытия по платформам
|
|
208
|
+
platforms = client.get_email_open_platform_usage()
|
|
209
|
+
|
|
210
|
+
# Клики по браузерам
|
|
211
|
+
browsers = client.get_click_browser_usage()
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
## AccountClient
|
|
215
|
+
|
|
216
|
+
Для операций на уровне аккаунта (управление серверами, доменами, подписями отправителей) используйте `AccountClient`:
|
|
217
|
+
|
|
218
|
+
```python
|
|
219
|
+
from haskimail import AccountClient
|
|
220
|
+
|
|
221
|
+
account = AccountClient("ваш-аккаунт-токен")
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
### Домены
|
|
225
|
+
|
|
226
|
+
```python
|
|
227
|
+
# Список доменов
|
|
228
|
+
domains = account.get_domains()
|
|
229
|
+
|
|
230
|
+
# Добавить домен
|
|
231
|
+
domain = account.create_domain({"Name": "example.com"})
|
|
232
|
+
|
|
233
|
+
# Проверить DKIM
|
|
234
|
+
account.verify_domain_dkim(domain["ID"])
|
|
235
|
+
|
|
236
|
+
# Проверить SPF
|
|
237
|
+
account.verify_domain_spf(domain["ID"])
|
|
238
|
+
|
|
239
|
+
# Ротация DKIM-ключа
|
|
240
|
+
account.rotate_domain_dkim(domain["ID"])
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
### Серверы
|
|
244
|
+
|
|
245
|
+
```python
|
|
246
|
+
# Список серверов
|
|
247
|
+
servers = account.get_servers()
|
|
248
|
+
|
|
249
|
+
# Создать сервер
|
|
250
|
+
server = account.create_server({
|
|
251
|
+
"Name": "Production",
|
|
252
|
+
"Color": "Green",
|
|
253
|
+
})
|
|
254
|
+
|
|
255
|
+
# Редактировать сервер
|
|
256
|
+
account.edit_server(server["ID"], {"Name": "Production v2"})
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
### Подписи отправителей
|
|
260
|
+
|
|
261
|
+
```python
|
|
262
|
+
# Создать подпись
|
|
263
|
+
signature = account.create_sender_signature({
|
|
264
|
+
"Name": "Отдел продаж",
|
|
265
|
+
"FromEmail": "sales@example.com",
|
|
266
|
+
})
|
|
267
|
+
|
|
268
|
+
# Подтвердить SPF
|
|
269
|
+
account.verify_sender_signature_spf(signature["ID"])
|
|
270
|
+
|
|
271
|
+
# Запросить новый DKIM
|
|
272
|
+
account.request_new_dkim_for_sender_signature(signature["ID"])
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
### Push шаблонов
|
|
276
|
+
|
|
277
|
+
```python
|
|
278
|
+
# Перенести шаблоны между серверами
|
|
279
|
+
account.push_templates({
|
|
280
|
+
"SourceServerID": 1,
|
|
281
|
+
"DestinationServerID": 2,
|
|
282
|
+
"PerformChanges": True,
|
|
283
|
+
})
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
### Удаление данных (GDPR)
|
|
287
|
+
|
|
288
|
+
```python
|
|
289
|
+
result = account.request_data_removal({
|
|
290
|
+
"RequestedBy": "admin@example.com",
|
|
291
|
+
"RequestedFor": "user@example.com",
|
|
292
|
+
})
|
|
293
|
+
|
|
294
|
+
status = account.get_data_removal_status(result["ID"])
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
## Обработка ошибок
|
|
298
|
+
|
|
299
|
+
Библиотека использует типизированную иерархию исключений:
|
|
300
|
+
|
|
301
|
+
```python
|
|
302
|
+
from haskimail import (
|
|
303
|
+
ServerClient,
|
|
304
|
+
HaskimailError, # Базовое исключение
|
|
305
|
+
HttpError, # Ошибка HTTP-уровня
|
|
306
|
+
InvalidAPIKeyError, # 401 — неверный или отсутствующий токен
|
|
307
|
+
ApiInputError, # 422 — ошибка в данных запроса
|
|
308
|
+
InactiveRecipientsError, # 422/406 — неактивный получатель
|
|
309
|
+
InvalidEmailRequestError, # 422/300 — неверный формат email
|
|
310
|
+
RateLimitExceededError, # 429 — превышен лимит запросов
|
|
311
|
+
InternalServerError, # 500 — ошибка сервера
|
|
312
|
+
ServiceUnavailableError, # 503 — сервис недоступен
|
|
313
|
+
UnknownError, # Другие HTTP-ошибки
|
|
314
|
+
)
|
|
315
|
+
|
|
316
|
+
client = ServerClient("ваш-токен")
|
|
317
|
+
|
|
318
|
+
try:
|
|
319
|
+
client.send_email({
|
|
320
|
+
"From": "sender@example.com",
|
|
321
|
+
"To": "recipient@example.com",
|
|
322
|
+
"Subject": "Test",
|
|
323
|
+
"TextBody": "Hello",
|
|
324
|
+
})
|
|
325
|
+
except InactiveRecipientsError as e:
|
|
326
|
+
print(f"Неактивные получатели: {e.recipients}")
|
|
327
|
+
except InvalidAPIKeyError:
|
|
328
|
+
print("Проверьте API-токен!")
|
|
329
|
+
except RateLimitExceededError:
|
|
330
|
+
print("Слишком много запросов, подождите...")
|
|
331
|
+
except ApiInputError as e:
|
|
332
|
+
print(f"Ошибка в данных: {e.message} (код: {e.error_code})")
|
|
333
|
+
except HttpError as e:
|
|
334
|
+
print(f"HTTP-ошибка {e.status_code}: {e.message}")
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
## Context Manager
|
|
338
|
+
|
|
339
|
+
Клиент можно использовать как контекстный менеджер для автоматического закрытия HTTP-сессии:
|
|
340
|
+
|
|
341
|
+
```python
|
|
342
|
+
with ServerClient("ваш-токен") as client:
|
|
343
|
+
client.send_email({...})
|
|
344
|
+
# Сессия автоматически закрыта
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
## Тестирование
|
|
348
|
+
|
|
349
|
+
Для тестов используйте токен `HASKIMAIL_API_TEST` — письма будут валидированы, но не отправлены:
|
|
350
|
+
|
|
351
|
+
```python
|
|
352
|
+
client = ServerClient("HASKIMAIL_API_TEST")
|
|
353
|
+
response = client.send_email({...}) # Не доставится, но проверит данные
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
## Настройка
|
|
357
|
+
|
|
358
|
+
```python
|
|
359
|
+
client = ServerClient(
|
|
360
|
+
"ваш-токен",
|
|
361
|
+
base_url="https://api.haskimail.ru", # по умолчанию
|
|
362
|
+
timeout=30, # таймаут в секундах
|
|
363
|
+
)
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
## Требования
|
|
367
|
+
|
|
368
|
+
- Python 3.10+
|
|
369
|
+
- requests >= 2.28.0
|
|
370
|
+
|
|
371
|
+
## Ссылки
|
|
372
|
+
|
|
373
|
+
- [Документация API Haskimail](https://haskimail.ru/developer)
|
|
374
|
+
- [haskimail.js](https://github.com/Dashamail/haskimail.js) — Node.js SDK
|
|
375
|
+
- [haskimail.java](https://github.com/Dashamail/haskimail.java) — Java SDK
|
|
376
|
+
- [haskimail-php](https://github.com/Dashamail/haskimail-php) — PHP SDK
|
|
377
|
+
|
|
378
|
+
## Лицензия
|
|
379
|
+
|
|
380
|
+
MIT
|