Metadata-Version: 2.4
Name: mustafatiksignweb
Version: 0.1.0
Summary: Safe HMAC request signing helpers for authorized APIs
Author: mustafatiksignweb contributors
License: MIT
Requires-Python: >=3.9
Description-Content-Type: text/markdown

# mustafatiksignweb

مكتبة صغيرة لتوقيع طلبات HTTP الخاصة بواجهات API التي تملكها أو لديك تفويض صريح لاستخدامها. تستخدم **HMAC-SHA256** مع canonical request، ولا تطبق تجاوزات anti-bot أو فحص بيانات اعتماد أو جمع cookies/tokens من خدمات طرف ثالث.

## التثبيت

```bash
pip install -e .
```

## الاستخدام

```python
import requests
import mustafatiksignweb

url = "https://api.example.com/v1/items"
params = {"page": 1, "limit": 20}
body = {"filter": "active"}
signer = mustafatiksignweb.RequestSigner("ضع-المفتاح-السري-في-متغير-بيئة", key_id="client-1")

# الدوال ترجع dicts؛ لذلك الاستدعاء الصحيح يتضمن الأقواس.
signed_params = mustafatiksignweb.getparams(
    signer=signer, method="POST", url=url, params=params, body=body
)
headers = mustafatiksignweb.getheaders(
    signer=signer, method="POST", url=url, params=params, body=body,
    headers={"Content-Type": "application/json"}
)
params.update(signed_params)
response = requests.post(url, params=params, json=body, headers=headers, timeout=30)
response.raise_for_status()
```

> لا يمكن جعل `params.update(mustafatiksignweb.getparams)` يولّد توقيعًا صحيحًا دون معرفة method وURL وbody والسر. لذلك صُممت الدوال كـ `getparams(...)` و`getheaders(...)` حتى يوقّع الخادم نفس البيانات بالترتيب canonical نفسه.

## صيغة التوقيع للخادم

يبني العميل النص التالي مفصولًا بـ newline:

```text
METHOD
URL
sorted-urlencoded-query
sha256(body)
timestamp
nonce
```

ثم يحسب `HMAC-SHA256(secret, canonical_request)` ويضع القيمة Base64URL في `X-Request-Signature`. يجب على الخادم التحقق من `timestamp` ضمن نافذة قصيرة (مثل 300 ثانية)، ومنع إعادة استخدام `nonce`، واستخدام مقارنة ثابتة الزمن.

## توليد جهاز محلي

```python
device = mustafatiksignweb.generate_device(user_agent="my-client/1.0")
print(device.to_dict())
```

هذا مولد هوية محلية فقط، ولا يتصل بأي خدمة خارجية ولا ينشئ tokens أو cookies خاصة بخدمة أخرى.
