pushizo 0.1.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.
- pushizo-0.1.0/LICENSE +21 -0
- pushizo-0.1.0/PKG-INFO +205 -0
- pushizo-0.1.0/README.md +177 -0
- pushizo-0.1.0/pyproject.toml +41 -0
- pushizo-0.1.0/setup.cfg +4 -0
- pushizo-0.1.0/src/pushizo/__init__.py +63 -0
- pushizo-0.1.0/src/pushizo/_client.py +367 -0
- pushizo-0.1.0/src/pushizo/_errors.py +130 -0
- pushizo-0.1.0/src/pushizo/_generated/__init__.py +4 -0
- pushizo-0.1.0/src/pushizo/_generated/models.py +10558 -0
- pushizo-0.1.0/src/pushizo/_generated/resources.py +6594 -0
- pushizo-0.1.0/src/pushizo/_identity.py +48 -0
- pushizo-0.1.0/src/pushizo/_types.py +22 -0
- pushizo-0.1.0/src/pushizo/_version.py +1 -0
- pushizo-0.1.0/src/pushizo/_webhooks.py +110 -0
- pushizo-0.1.0/src/pushizo/py.typed +0 -0
- pushizo-0.1.0/src/pushizo.egg-info/PKG-INFO +205 -0
- pushizo-0.1.0/src/pushizo.egg-info/SOURCES.txt +22 -0
- pushizo-0.1.0/src/pushizo.egg-info/dependency_links.txt +1 -0
- pushizo-0.1.0/src/pushizo.egg-info/requires.txt +8 -0
- pushizo-0.1.0/src/pushizo.egg-info/top_level.txt +2 -0
- pushizo-0.1.0/tests/test_client.py +280 -0
- pushizo-0.1.0/tests/test_identity.py +43 -0
- pushizo-0.1.0/tests/test_webhooks.py +48 -0
pushizo-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Pushizo contributors
|
|
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.
|
pushizo-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pushizo
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Pushizo sunucu SDK'sı: bildirim gönderme, kullanıcı/abonelik yönetimi, segment/şablon/kampanya ve webhook imza doğrulaması
|
|
5
|
+
Author: Pushizo
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://docs.pushizo.com/docs/sdk/python
|
|
8
|
+
Project-URL: Documentation, https://docs.pushizo.com/docs/sdk/python
|
|
9
|
+
Project-URL: Repository, https://github.com/pushizo/pushizo-python
|
|
10
|
+
Project-URL: Issues, https://github.com/pushizo/pushizo-python/issues
|
|
11
|
+
Project-URL: Changelog, https://docs.pushizo.com/docs/changelog
|
|
12
|
+
Keywords: pushizo,push,notifications,email,sms,webhooks
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Typing :: Typed
|
|
18
|
+
Requires-Python: >=3.9
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
License-File: LICENSE
|
|
21
|
+
Requires-Dist: httpx<1,>=0.24
|
|
22
|
+
Provides-Extra: dev
|
|
23
|
+
Requires-Dist: pytest>=7; extra == "dev"
|
|
24
|
+
Requires-Dist: cryptography>=41; extra == "dev"
|
|
25
|
+
Provides-Extra: jwt
|
|
26
|
+
Requires-Dist: cryptography>=41; extra == "jwt"
|
|
27
|
+
Dynamic: license-file
|
|
28
|
+
|
|
29
|
+
<!-- pushizo:header -->
|
|
30
|
+
<p align="center">
|
|
31
|
+
<a href="https://pushizo.com"><img src="https://raw.githubusercontent.com/pushizo/.github/main/profile/assets/mark.svg" alt="Pushizo" width="56" height="56"></a>
|
|
32
|
+
</p>
|
|
33
|
+
<p align="center">
|
|
34
|
+
<a href="https://docs.pushizo.com/docs/sdk/python"><img src="https://img.shields.io/badge/docs-docs.pushizo.com-5b4bdb" alt="Docs"></a>
|
|
35
|
+
<a href="https://docs.pushizo.com/docs/api"><img src="https://img.shields.io/badge/API-reference-b44fc4" alt="API reference"></a>
|
|
36
|
+
<a href="https://github.com/pushizo/pushizo-python/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-16130f" alt="License: MIT"></a>
|
|
37
|
+
</p>
|
|
38
|
+
<p align="center"><a href="#english">English</a> · <a href="#türkçe">Türkçe</a></p>
|
|
39
|
+
|
|
40
|
+
## English
|
|
41
|
+
|
|
42
|
+
**Pushizo Python SDK** — Server-side SDK for Python with synchronous and asyncio clients. Models and resources are generated from the Pushizo OpenAPI schema; retries, idempotency, pagination and webhook verification are built in.
|
|
43
|
+
|
|
44
|
+
> **Status:** Publishing to PyPI is in progress.<br>
|
|
45
|
+
> **Durum:** PyPI yayını hazırlanıyor.
|
|
46
|
+
|
|
47
|
+
**Install from GitHub until then · O zamana kadar GitHub'dan kurulum:**
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
pip install https://github.com/pushizo/pushizo-python/releases/download/v0.1.0/pushizo-0.1.0-py3-none-any.whl
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
**After publication · Yayından sonra:**
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
pip install pushizo
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
The detailed guide below is in Turkish; code samples are language-neutral. Full documentation:
|
|
60
|
+
[docs.pushizo.com/docs/sdk/python](https://docs.pushizo.com/docs/sdk/python) · API reference: [docs.pushizo.com/docs/api](https://docs.pushizo.com/docs/api).
|
|
61
|
+
|
|
62
|
+
## Türkçe
|
|
63
|
+
<!-- /pushizo:header -->
|
|
64
|
+
|
|
65
|
+
# Pushizo Python SDK
|
|
66
|
+
|
|
67
|
+
Pushizo public API'si için Python sunucu SDK'sı (Python 3.9+, [httpx](https://www.python-httpx.org/)).
|
|
68
|
+
Modeller ve kaynak metotları [Pushizo OpenAPI şemasından](https://github.com/pushizo/pushizo-openapi) üretilir; kimlik doğrulama, yeniden deneme, idempotency,
|
|
69
|
+
sayfalama ve webhook imza doğrulaması el yazımı katmandadır.
|
|
70
|
+
|
|
71
|
+
## Kurulum
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
pip install pushizo
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Kullanım
|
|
78
|
+
|
|
79
|
+
```python
|
|
80
|
+
import os
|
|
81
|
+
from pushizo import Pushizo
|
|
82
|
+
|
|
83
|
+
hs = Pushizo(api_key=os.environ["HS_API_KEY"], app_id="app_…") # yerelde base_url="http://localhost:4000"
|
|
84
|
+
|
|
85
|
+
# Bildirim gönder (Idempotency-Key verilmezse otomatik UUID üretilir; yeniden denemelerde aynı anahtar kullanılır)
|
|
86
|
+
res = hs.notifications.create(
|
|
87
|
+
{
|
|
88
|
+
"target": {"include_aliases": {"external_id": ["user-42"]}},
|
|
89
|
+
"contents": {"en": "Your order shipped", "tr": "Siparişiniz kargoya verildi"},
|
|
90
|
+
},
|
|
91
|
+
idempotency_key="order-1001",
|
|
92
|
+
)
|
|
93
|
+
print(res["id"], res["status"])
|
|
94
|
+
|
|
95
|
+
# Kullanıcı oluştur/güncelle ve abonelik ekle
|
|
96
|
+
hs.users.upsert({"external_id": "user-42", "tags": {"plan": "pro"}})
|
|
97
|
+
hs.users.add_subscription("external_id", "user-42", {"channel": "email", "token": "ayse@pushizo.com"})
|
|
98
|
+
|
|
99
|
+
# Cursor sayfalama: tüm sayfaları tek tek dolaşır
|
|
100
|
+
for segment in hs.segments.list_all(limit=100):
|
|
101
|
+
print(segment["name"])
|
|
102
|
+
|
|
103
|
+
# Başka bir app için tek çağrı
|
|
104
|
+
hs.apps.get(app_id="app_diger")
|
|
105
|
+
|
|
106
|
+
# SDK identity verification: identity_hash = HMAC-SHA256(sdk_secret, external_id)
|
|
107
|
+
identity_hash = Pushizo.identity_hash(os.environ["HS_SDK_SECRET"], "user-42")
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Modeller çalışma zamanında sade `dict`'tir; tipler `pushizo._generated.models` içindeki `TypedDict`'lerle
|
|
111
|
+
(`CreateNotificationDto`, `Message` …) editörde görünür. SDK'da metodu olmayan uçlar ve JSON dışı yanıtlar için
|
|
112
|
+
`hs.request("GET", "/v1/apps/app_…/analytics/messages", query={"format": "csv"})` kullanılabilir.
|
|
113
|
+
|
|
114
|
+
### Ayarlar
|
|
115
|
+
|
|
116
|
+
| Parametre | Varsayılan | Açıklama |
|
|
117
|
+
|-----------|------------|----------|
|
|
118
|
+
| `api_key` | — | `hs_live_…` API anahtarı (Bearer) |
|
|
119
|
+
| `app_id` | `None` | Çağrıda `app_id=` verilmezse kullanılan app |
|
|
120
|
+
| `base_url` | `https://api.pushizo.com` | API adresi |
|
|
121
|
+
| `timeout` | `30` | Deneme başına zaman aşımı (sn) |
|
|
122
|
+
| `max_retries` | `3` | En fazla yeniden deneme (politika: aşağıda) |
|
|
123
|
+
| `auto_idempotency_key` | `True` | `Idempotency-Key` destekleyen çağrılarda otomatik UUID |
|
|
124
|
+
| `http_client` | — | Özel `httpx.Client` (proxy, TLS) |
|
|
125
|
+
|
|
126
|
+
Her çağrı `request_options={"timeout": 5, "max_retries": 0, "headers": {...}}` ile ayrıca ayarlanabilir.
|
|
127
|
+
|
|
128
|
+
### Hatalar
|
|
129
|
+
|
|
130
|
+
429 her metotta; 5xx ve ağ hataları GET/HEAD/OPTIONS/PUT/DELETE'te, POST/PATCH'te yalnızca `Idempotency-Key` varsa (otomatik anahtar dahil) veya istek sunucuya hiç gönderilemediyse (bağlantı reddi, DNS hatası, bağlantı zaman aşımı) üstel geri çekilmeyle (0,3 / 1 / 3 sn) yeniden denenir; `Retry-After` başlığına uyulur.
|
|
131
|
+
Kalıcı hatalar HTTP durumuna göre tiplendirilir; hepsi `PushizoError`'dan türer ve `status`, `code` (`HS_…`),
|
|
132
|
+
`request_id`, `details` taşır:
|
|
133
|
+
|
|
134
|
+
```python
|
|
135
|
+
from pushizo import ErrorCode, NotFoundError, RateLimitError, PushizoError
|
|
136
|
+
|
|
137
|
+
try:
|
|
138
|
+
hs.notifications.get("msg_yok")
|
|
139
|
+
except NotFoundError as e:
|
|
140
|
+
print(e.code == ErrorCode.NOT_FOUND, e.request_id)
|
|
141
|
+
except RateLimitError:
|
|
142
|
+
...
|
|
143
|
+
except PushizoError as e: # InvalidRequestError, AuthenticationError, PermissionDeniedError, ConflictError, ServerError, NetworkError
|
|
144
|
+
print(e.status, e.code, e.message)
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
## Webhook imza doğrulaması
|
|
148
|
+
|
|
149
|
+
Pushizo her webhook isteğini `Pushizo-Signature: t=<unix>,v1=<hex>` başlığıyla imzalar
|
|
150
|
+
(`v1 = HMAC-SHA256(secret, f"{t}.{ham_gövde}")`). Ham gövdeyi (JSON'u ayrıştırmadan) doğrulayın:
|
|
151
|
+
|
|
152
|
+
```python
|
|
153
|
+
from flask import Flask, request
|
|
154
|
+
from pushizo import WebhookSignatureError, construct_webhook_events
|
|
155
|
+
|
|
156
|
+
app = Flask(__name__)
|
|
157
|
+
|
|
158
|
+
@app.post("/hooks/pushizo")
|
|
159
|
+
def pushizo_hook():
|
|
160
|
+
try:
|
|
161
|
+
events = construct_webhook_events(
|
|
162
|
+
request.get_data(), # ham gövde
|
|
163
|
+
request.headers.get("Pushizo-Signature"),
|
|
164
|
+
os.environ["HS_WEBHOOK_SECRET"], # rotasyonda [eski, yeni] verilebilir
|
|
165
|
+
)
|
|
166
|
+
except WebhookSignatureError as e:
|
|
167
|
+
return e.reason, 400
|
|
168
|
+
for event in events: # tekil veya batch gövde
|
|
169
|
+
... # Pushizo-Event-Id ile tekrarları ayıklayın
|
|
170
|
+
return "", 204
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Zaman damgası 5 dakikadan eskiyse (`tolerance_seconds`) istek tekrar (replay) sayılır ve reddedilir.
|
|
174
|
+
|
|
175
|
+
## Geliştirme
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
pip install -e ".[dev]"
|
|
179
|
+
pytest # sdk/python içinde
|
|
180
|
+
node sdk/scripts/generate-server-sdks.mjs --lang python # depo kökünde; modeller/kaynaklar yeniden üretilir
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
`src/pushizo/_generated/` elle düzenlenmez. Webhook testleri `sdk/testdata/webhook-signature-vectors.json`
|
|
184
|
+
ortak vektörlerini kullanır (Node, PHP, Go, Java, .NET ve Ruby SDK'larıyla aynı).
|
|
185
|
+
|
|
186
|
+
<!-- pushizo:footer -->
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
## Support · Destek
|
|
190
|
+
|
|
191
|
+
- **Guide · Rehber:** [docs.pushizo.com/docs/sdk/python](https://docs.pushizo.com/docs/sdk/python)
|
|
192
|
+
- **API reference & OpenAPI · API referansı ve OpenAPI:** [docs.pushizo.com/docs/api](https://docs.pushizo.com/docs/api) ·
|
|
193
|
+
[pushizo-openapi](https://github.com/pushizo/pushizo-openapi)
|
|
194
|
+
- **Bugs & ideas · Hata ve öneri:** [Issues](https://github.com/pushizo/pushizo-python/issues)
|
|
195
|
+
- **Security · Güvenlik:** please do not open public issues; email [security@pushizo.com](mailto:security@pushizo.com) ·
|
|
196
|
+
herkese açık issue açmayın, bu adrese yazın.
|
|
197
|
+
- **Help · Destek:** [support@pushizo.com](mailto:support@pushizo.com)
|
|
198
|
+
|
|
199
|
+
This repository is mirrored automatically from the Pushizo main repository on every release. Please open an issue
|
|
200
|
+
instead of a pull request; fixes land in the main repository and ship with the next release.
|
|
201
|
+
Bu depo her sürümde Pushizo ana deposundan otomatik yansıtılır. Pull request yerine issue açın; düzeltmeler ana depoda
|
|
202
|
+
yapılır ve bir sonraki sürümle buraya gelir.
|
|
203
|
+
|
|
204
|
+
Released under the MIT License · MIT lisanslıdır — [LICENSE](https://github.com/pushizo/pushizo-python/blob/main/LICENSE).
|
|
205
|
+
<!-- /pushizo:footer -->
|
pushizo-0.1.0/README.md
ADDED
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
<!-- pushizo:header -->
|
|
2
|
+
<p align="center">
|
|
3
|
+
<a href="https://pushizo.com"><img src="https://raw.githubusercontent.com/pushizo/.github/main/profile/assets/mark.svg" alt="Pushizo" width="56" height="56"></a>
|
|
4
|
+
</p>
|
|
5
|
+
<p align="center">
|
|
6
|
+
<a href="https://docs.pushizo.com/docs/sdk/python"><img src="https://img.shields.io/badge/docs-docs.pushizo.com-5b4bdb" alt="Docs"></a>
|
|
7
|
+
<a href="https://docs.pushizo.com/docs/api"><img src="https://img.shields.io/badge/API-reference-b44fc4" alt="API reference"></a>
|
|
8
|
+
<a href="https://github.com/pushizo/pushizo-python/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-16130f" alt="License: MIT"></a>
|
|
9
|
+
</p>
|
|
10
|
+
<p align="center"><a href="#english">English</a> · <a href="#türkçe">Türkçe</a></p>
|
|
11
|
+
|
|
12
|
+
## English
|
|
13
|
+
|
|
14
|
+
**Pushizo Python SDK** — Server-side SDK for Python with synchronous and asyncio clients. Models and resources are generated from the Pushizo OpenAPI schema; retries, idempotency, pagination and webhook verification are built in.
|
|
15
|
+
|
|
16
|
+
> **Status:** Publishing to PyPI is in progress.<br>
|
|
17
|
+
> **Durum:** PyPI yayını hazırlanıyor.
|
|
18
|
+
|
|
19
|
+
**Install from GitHub until then · O zamana kadar GitHub'dan kurulum:**
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
pip install https://github.com/pushizo/pushizo-python/releases/download/v0.1.0/pushizo-0.1.0-py3-none-any.whl
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
**After publication · Yayından sonra:**
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
pip install pushizo
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
The detailed guide below is in Turkish; code samples are language-neutral. Full documentation:
|
|
32
|
+
[docs.pushizo.com/docs/sdk/python](https://docs.pushizo.com/docs/sdk/python) · API reference: [docs.pushizo.com/docs/api](https://docs.pushizo.com/docs/api).
|
|
33
|
+
|
|
34
|
+
## Türkçe
|
|
35
|
+
<!-- /pushizo:header -->
|
|
36
|
+
|
|
37
|
+
# Pushizo Python SDK
|
|
38
|
+
|
|
39
|
+
Pushizo public API'si için Python sunucu SDK'sı (Python 3.9+, [httpx](https://www.python-httpx.org/)).
|
|
40
|
+
Modeller ve kaynak metotları [Pushizo OpenAPI şemasından](https://github.com/pushizo/pushizo-openapi) üretilir; kimlik doğrulama, yeniden deneme, idempotency,
|
|
41
|
+
sayfalama ve webhook imza doğrulaması el yazımı katmandadır.
|
|
42
|
+
|
|
43
|
+
## Kurulum
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
pip install pushizo
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Kullanım
|
|
50
|
+
|
|
51
|
+
```python
|
|
52
|
+
import os
|
|
53
|
+
from pushizo import Pushizo
|
|
54
|
+
|
|
55
|
+
hs = Pushizo(api_key=os.environ["HS_API_KEY"], app_id="app_…") # yerelde base_url="http://localhost:4000"
|
|
56
|
+
|
|
57
|
+
# Bildirim gönder (Idempotency-Key verilmezse otomatik UUID üretilir; yeniden denemelerde aynı anahtar kullanılır)
|
|
58
|
+
res = hs.notifications.create(
|
|
59
|
+
{
|
|
60
|
+
"target": {"include_aliases": {"external_id": ["user-42"]}},
|
|
61
|
+
"contents": {"en": "Your order shipped", "tr": "Siparişiniz kargoya verildi"},
|
|
62
|
+
},
|
|
63
|
+
idempotency_key="order-1001",
|
|
64
|
+
)
|
|
65
|
+
print(res["id"], res["status"])
|
|
66
|
+
|
|
67
|
+
# Kullanıcı oluştur/güncelle ve abonelik ekle
|
|
68
|
+
hs.users.upsert({"external_id": "user-42", "tags": {"plan": "pro"}})
|
|
69
|
+
hs.users.add_subscription("external_id", "user-42", {"channel": "email", "token": "ayse@pushizo.com"})
|
|
70
|
+
|
|
71
|
+
# Cursor sayfalama: tüm sayfaları tek tek dolaşır
|
|
72
|
+
for segment in hs.segments.list_all(limit=100):
|
|
73
|
+
print(segment["name"])
|
|
74
|
+
|
|
75
|
+
# Başka bir app için tek çağrı
|
|
76
|
+
hs.apps.get(app_id="app_diger")
|
|
77
|
+
|
|
78
|
+
# SDK identity verification: identity_hash = HMAC-SHA256(sdk_secret, external_id)
|
|
79
|
+
identity_hash = Pushizo.identity_hash(os.environ["HS_SDK_SECRET"], "user-42")
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Modeller çalışma zamanında sade `dict`'tir; tipler `pushizo._generated.models` içindeki `TypedDict`'lerle
|
|
83
|
+
(`CreateNotificationDto`, `Message` …) editörde görünür. SDK'da metodu olmayan uçlar ve JSON dışı yanıtlar için
|
|
84
|
+
`hs.request("GET", "/v1/apps/app_…/analytics/messages", query={"format": "csv"})` kullanılabilir.
|
|
85
|
+
|
|
86
|
+
### Ayarlar
|
|
87
|
+
|
|
88
|
+
| Parametre | Varsayılan | Açıklama |
|
|
89
|
+
|-----------|------------|----------|
|
|
90
|
+
| `api_key` | — | `hs_live_…` API anahtarı (Bearer) |
|
|
91
|
+
| `app_id` | `None` | Çağrıda `app_id=` verilmezse kullanılan app |
|
|
92
|
+
| `base_url` | `https://api.pushizo.com` | API adresi |
|
|
93
|
+
| `timeout` | `30` | Deneme başına zaman aşımı (sn) |
|
|
94
|
+
| `max_retries` | `3` | En fazla yeniden deneme (politika: aşağıda) |
|
|
95
|
+
| `auto_idempotency_key` | `True` | `Idempotency-Key` destekleyen çağrılarda otomatik UUID |
|
|
96
|
+
| `http_client` | — | Özel `httpx.Client` (proxy, TLS) |
|
|
97
|
+
|
|
98
|
+
Her çağrı `request_options={"timeout": 5, "max_retries": 0, "headers": {...}}` ile ayrıca ayarlanabilir.
|
|
99
|
+
|
|
100
|
+
### Hatalar
|
|
101
|
+
|
|
102
|
+
429 her metotta; 5xx ve ağ hataları GET/HEAD/OPTIONS/PUT/DELETE'te, POST/PATCH'te yalnızca `Idempotency-Key` varsa (otomatik anahtar dahil) veya istek sunucuya hiç gönderilemediyse (bağlantı reddi, DNS hatası, bağlantı zaman aşımı) üstel geri çekilmeyle (0,3 / 1 / 3 sn) yeniden denenir; `Retry-After` başlığına uyulur.
|
|
103
|
+
Kalıcı hatalar HTTP durumuna göre tiplendirilir; hepsi `PushizoError`'dan türer ve `status`, `code` (`HS_…`),
|
|
104
|
+
`request_id`, `details` taşır:
|
|
105
|
+
|
|
106
|
+
```python
|
|
107
|
+
from pushizo import ErrorCode, NotFoundError, RateLimitError, PushizoError
|
|
108
|
+
|
|
109
|
+
try:
|
|
110
|
+
hs.notifications.get("msg_yok")
|
|
111
|
+
except NotFoundError as e:
|
|
112
|
+
print(e.code == ErrorCode.NOT_FOUND, e.request_id)
|
|
113
|
+
except RateLimitError:
|
|
114
|
+
...
|
|
115
|
+
except PushizoError as e: # InvalidRequestError, AuthenticationError, PermissionDeniedError, ConflictError, ServerError, NetworkError
|
|
116
|
+
print(e.status, e.code, e.message)
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Webhook imza doğrulaması
|
|
120
|
+
|
|
121
|
+
Pushizo her webhook isteğini `Pushizo-Signature: t=<unix>,v1=<hex>` başlığıyla imzalar
|
|
122
|
+
(`v1 = HMAC-SHA256(secret, f"{t}.{ham_gövde}")`). Ham gövdeyi (JSON'u ayrıştırmadan) doğrulayın:
|
|
123
|
+
|
|
124
|
+
```python
|
|
125
|
+
from flask import Flask, request
|
|
126
|
+
from pushizo import WebhookSignatureError, construct_webhook_events
|
|
127
|
+
|
|
128
|
+
app = Flask(__name__)
|
|
129
|
+
|
|
130
|
+
@app.post("/hooks/pushizo")
|
|
131
|
+
def pushizo_hook():
|
|
132
|
+
try:
|
|
133
|
+
events = construct_webhook_events(
|
|
134
|
+
request.get_data(), # ham gövde
|
|
135
|
+
request.headers.get("Pushizo-Signature"),
|
|
136
|
+
os.environ["HS_WEBHOOK_SECRET"], # rotasyonda [eski, yeni] verilebilir
|
|
137
|
+
)
|
|
138
|
+
except WebhookSignatureError as e:
|
|
139
|
+
return e.reason, 400
|
|
140
|
+
for event in events: # tekil veya batch gövde
|
|
141
|
+
... # Pushizo-Event-Id ile tekrarları ayıklayın
|
|
142
|
+
return "", 204
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Zaman damgası 5 dakikadan eskiyse (`tolerance_seconds`) istek tekrar (replay) sayılır ve reddedilir.
|
|
146
|
+
|
|
147
|
+
## Geliştirme
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
pip install -e ".[dev]"
|
|
151
|
+
pytest # sdk/python içinde
|
|
152
|
+
node sdk/scripts/generate-server-sdks.mjs --lang python # depo kökünde; modeller/kaynaklar yeniden üretilir
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
`src/pushizo/_generated/` elle düzenlenmez. Webhook testleri `sdk/testdata/webhook-signature-vectors.json`
|
|
156
|
+
ortak vektörlerini kullanır (Node, PHP, Go, Java, .NET ve Ruby SDK'larıyla aynı).
|
|
157
|
+
|
|
158
|
+
<!-- pushizo:footer -->
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
## Support · Destek
|
|
162
|
+
|
|
163
|
+
- **Guide · Rehber:** [docs.pushizo.com/docs/sdk/python](https://docs.pushizo.com/docs/sdk/python)
|
|
164
|
+
- **API reference & OpenAPI · API referansı ve OpenAPI:** [docs.pushizo.com/docs/api](https://docs.pushizo.com/docs/api) ·
|
|
165
|
+
[pushizo-openapi](https://github.com/pushizo/pushizo-openapi)
|
|
166
|
+
- **Bugs & ideas · Hata ve öneri:** [Issues](https://github.com/pushizo/pushizo-python/issues)
|
|
167
|
+
- **Security · Güvenlik:** please do not open public issues; email [security@pushizo.com](mailto:security@pushizo.com) ·
|
|
168
|
+
herkese açık issue açmayın, bu adrese yazın.
|
|
169
|
+
- **Help · Destek:** [support@pushizo.com](mailto:support@pushizo.com)
|
|
170
|
+
|
|
171
|
+
This repository is mirrored automatically from the Pushizo main repository on every release. Please open an issue
|
|
172
|
+
instead of a pull request; fixes land in the main repository and ship with the next release.
|
|
173
|
+
Bu depo her sürümde Pushizo ana deposundan otomatik yansıtılır. Pull request yerine issue açın; düzeltmeler ana depoda
|
|
174
|
+
yapılır ve bir sonraki sürümle buraya gelir.
|
|
175
|
+
|
|
176
|
+
Released under the MIT License · MIT lisanslıdır — [LICENSE](https://github.com/pushizo/pushizo-python/blob/main/LICENSE).
|
|
177
|
+
<!-- /pushizo:footer -->
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "pushizo"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Pushizo sunucu SDK'sı: bildirim gönderme, kullanıcı/abonelik yönetimi, segment/şablon/kampanya ve webhook imza doğrulaması"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.9"
|
|
11
|
+
license = { text = "MIT" }
|
|
12
|
+
authors = [{ name = "Pushizo" }]
|
|
13
|
+
keywords = ["pushizo", "push", "notifications", "email", "sms", "webhooks"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Programming Language :: Python :: 3",
|
|
16
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
17
|
+
"License :: OSI Approved :: MIT License",
|
|
18
|
+
"Operating System :: OS Independent",
|
|
19
|
+
"Typing :: Typed",
|
|
20
|
+
]
|
|
21
|
+
dependencies = ["httpx>=0.24,<1"]
|
|
22
|
+
|
|
23
|
+
[project.urls]
|
|
24
|
+
Homepage = "https://docs.pushizo.com/docs/sdk/python"
|
|
25
|
+
Documentation = "https://docs.pushizo.com/docs/sdk/python"
|
|
26
|
+
Repository = "https://github.com/pushizo/pushizo-python"
|
|
27
|
+
Issues = "https://github.com/pushizo/pushizo-python/issues"
|
|
28
|
+
Changelog = "https://docs.pushizo.com/docs/changelog"
|
|
29
|
+
|
|
30
|
+
[project.optional-dependencies]
|
|
31
|
+
dev = ["pytest>=7", "cryptography>=41"]
|
|
32
|
+
jwt = ["cryptography>=41"]
|
|
33
|
+
|
|
34
|
+
[tool.setuptools.packages.find]
|
|
35
|
+
where = ["src"]
|
|
36
|
+
|
|
37
|
+
[tool.setuptools.package-data]
|
|
38
|
+
pushizo = ["py.typed"]
|
|
39
|
+
|
|
40
|
+
[tool.pytest.ini_options]
|
|
41
|
+
testpaths = ["tests"]
|
pushizo-0.1.0/setup.cfg
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"""Pushizo Python sunucu SDK'sı.
|
|
2
|
+
|
|
3
|
+
.. code-block:: python
|
|
4
|
+
|
|
5
|
+
from pushizo import Pushizo
|
|
6
|
+
|
|
7
|
+
hs = Pushizo(api_key=os.environ["HS_API_KEY"], app_id="app_…")
|
|
8
|
+
hs.notifications.create({"target": {"include_aliases": {"external_id": ["u1"]}}, "contents": {"en": "Shipped"}})
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from ._client import DEFAULT_BASE_URL, Pushizo
|
|
12
|
+
from ._errors import (
|
|
13
|
+
AuthenticationError,
|
|
14
|
+
ConflictError,
|
|
15
|
+
ErrorCode,
|
|
16
|
+
PushizoError,
|
|
17
|
+
InvalidRequestError,
|
|
18
|
+
NetworkError,
|
|
19
|
+
NotFoundError,
|
|
20
|
+
PermissionDeniedError,
|
|
21
|
+
RateLimitError,
|
|
22
|
+
ServerError,
|
|
23
|
+
WebhookSignatureError,
|
|
24
|
+
)
|
|
25
|
+
from ._generated import API_VERSION
|
|
26
|
+
from ._identity import identity_token
|
|
27
|
+
from ._types import FileInput, RequestOptions
|
|
28
|
+
from ._version import __version__
|
|
29
|
+
from ._webhooks import (
|
|
30
|
+
WEBHOOK_DEFAULT_TOLERANCE_SECONDS,
|
|
31
|
+
WEBHOOK_EVENT_ID_HEADER,
|
|
32
|
+
WEBHOOK_SIGNATURE_HEADER,
|
|
33
|
+
WebhookVerifyResult,
|
|
34
|
+
construct_webhook_events,
|
|
35
|
+
verify_webhook_signature,
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
__all__ = [
|
|
39
|
+
"identity_token",
|
|
40
|
+
"API_VERSION",
|
|
41
|
+
"DEFAULT_BASE_URL",
|
|
42
|
+
"WEBHOOK_DEFAULT_TOLERANCE_SECONDS",
|
|
43
|
+
"WEBHOOK_EVENT_ID_HEADER",
|
|
44
|
+
"WEBHOOK_SIGNATURE_HEADER",
|
|
45
|
+
"AuthenticationError",
|
|
46
|
+
"ConflictError",
|
|
47
|
+
"ErrorCode",
|
|
48
|
+
"FileInput",
|
|
49
|
+
"Pushizo",
|
|
50
|
+
"PushizoError",
|
|
51
|
+
"InvalidRequestError",
|
|
52
|
+
"NetworkError",
|
|
53
|
+
"NotFoundError",
|
|
54
|
+
"PermissionDeniedError",
|
|
55
|
+
"RateLimitError",
|
|
56
|
+
"RequestOptions",
|
|
57
|
+
"ServerError",
|
|
58
|
+
"WebhookSignatureError",
|
|
59
|
+
"WebhookVerifyResult",
|
|
60
|
+
"__version__",
|
|
61
|
+
"construct_webhook_events",
|
|
62
|
+
"verify_webhook_signature",
|
|
63
|
+
]
|