Metadata-Version: 2.4
Name: dlp-sdk
Version: 1.0.0
Summary: Official Python SDK for the Daily Life Pharmacy enterprise platform
Author: Daily Life Pharmacy Engineering
License-Expression: MIT
Project-URL: Source Code, https://github.com/dailylifepharmacy/dlp-sdk
Project-URL: Bug Tracker, https://github.com/dailylifepharmacy/dlp-sdk/issues
Keywords: pharmacy,sdk,api,ecommerce
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Operating System :: OS Independent
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: requests>=2.31
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == "dev"
Requires-Dist: pytest-mock>=3.14; extra == "dev"
Requires-Dist: responses>=0.25; extra == "dev"

﻿# dlp-sdk - Daily Life Pharmacy Python SDK

Official Python SDK for the **Daily Life Pharmacy** enterprise platform.
It wraps the REST API in a typed, session-aware client for customer, admin, and mobile workflows.

---

## Installation

Install from PyPI once the package is published:

```bash
pip install dlp-sdk
```

Install from a local checkout:

```bash
pip install .
```

Install with development dependencies:

```bash
pip install -e .[dev]
```

Requirements:

- Python 3.10+
- `requests>=2.31`

---

## Quick Start

```python
from dlp_sdk import DLPClient

sdk = DLPClient("https://pharmacy.example.com")
print(sdk.health())
```

---

## Authentication

### Admin Login

```python
sdk.auth.admin_login("admin", "yourpassword")

# With 2FA (TOTP)
sdk.auth.admin_login("admin", "yourpassword", totp_code="123456")

# Fetch authenticator QR URI (must be logged in)
uri = sdk.auth.totp_qr_uri()
print(uri)

sdk.auth.admin_logout()
```

### Customer OTP

```python
result = sdk.auth.otp_request("+8801712345678")
print(result.otp)  # dev/demo only

verified = sdk.auth.otp_verify("+8801712345678", "123456")
if verified.valid:
    print(f"Welcome, {verified.customer_name}!")
```

---

## Catalog

```python
products = sdk.catalog.list_products()

pain_killers = sdk.catalog.list_products(
    category="painkiller",
    sort="price_asc",
    limit=20,
)

results = sdk.catalog.list_products(search="paracetamol")
featured = sdk.catalog.list_products(featured=True)

product = sdk.catalog.get_product(1)
product = sdk.catalog.get_product_by_slug("paracetamol-500mg")
print(product.name, product.price, product.stock)

related = sdk.catalog.related_products(product_id=1, limit=4)
```

---

## Cart

The cart is session-based. The SDK preserves the session cookie automatically.

```python
sdk.cart.add(product_id=1, quantity=2)
sdk.cart.add(product_id=5, quantity=1)

cart = sdk.cart.get()
print(f"Items: {len(cart.items)}")
print(f"Subtotal: {cart.subtotal}")
print(f"Delivery: {cart.delivery}")
print(f"Grand total: {cart.grand_total}")

for item in cart.items:
    print(f"{item.name} x {item.qty} = {item.subtotal}")

result = sdk.cart.apply_promo("SAVE10")
if result["valid"]:
    print(f"Saved {result['discount_amount']}")

sdk.cart.remove_promo()
sdk.cart.update(product_id=1, quantity=3)
sdk.cart.remove(product_id=5)
sdk.cart.clear()
```

---

## Orders

```python
sdk.cart.add(product_id=1, quantity=2)
sdk.cart.apply_promo("SAVE10")

order = sdk.orders.create(
    name="Fatima Khanam",
    phone="+8801987654321",
    address="House 7, Road 3, Mirpur-1",
    city="Dhaka",
    payment_method="bKash",
    email="fatima@example.com",
    note="Please ring the bell twice.",
)

print(order.order_code)
print(order.status)
print(order.eta)
print(order.grand_total)

for item in order.items:
    print(item.product_name, item.quantity)

order = sdk.orders.get("DLP12345678")
```

Order statuses: `Confirmed -> Processing -> Shipped -> Delivered`

---

## Admin

```python
sdk.auth.admin_login("admin", "secret")

stats = sdk.admin.stats()
print(stats.order_count, stats.pending_orders)
print(stats.revenue)
print(stats.unread_messages)

reports = sdk.admin.reports()
print(reports.sales.average_order)
print(reports.operations.active_promos)
for product in reports.top_products[:5]:
    print(product.name, product.units, product.sales)

integrations = sdk.admin.integrations()
print(integrations.whatsapp_logs, integrations.label_documents)
```

### Invoice PDF

```python
pdf_bytes = sdk.admin.download_invoice(order_id=42)
sdk.admin.download_invoice(order_id=42, dest_path="/tmp/invoice_DLP12345678.pdf")
```

### WhatsApp Link

```python
link = sdk.admin.whatsapp_link(order_id=42)
print(link)
```

### Barcodes and QR Codes

```python
sdk.admin.download_barcode(product_id=7, dest_path="/tmp/barcode_7.pdf")
sdk.admin.download_qr(product_id=7, dest_path="/tmp/qr_7.pdf")
```

### Shipping and Item Labels

```python
sdk.admin.download_shipping_label(order_id=42, dest_path="/tmp/ship_label.pdf")
sdk.admin.download_item_labels(order_id=42, dest_path="/tmp/item_labels.pdf")
```

---

## Mobile and Content

```python
home = sdk.mobile.home()
for banner in home.banners:
    print(banner.title, banner.image_url)
for post in home.blog_posts:
    print(post.title, post.slug)

sdk.mobile.wishlist_add(product_id=3)
items = sdk.mobile.wishlist()

sdk.mobile.newsletter_subscribe("customer@example.com")
```

---

## Error Handling

```python
from dlp_sdk import (
    DLPClient,
    AuthenticationError,
    AuthorizationError,
    NotFoundError,
    ValidationError,
    RateLimitError,
    ServerError,
    NetworkError,
)

sdk = DLPClient("https://pharmacy.example.com")

try:
    sdk.auth.admin_login("admin", "wrongpass")
except AuthenticationError as exc:
    print(f"Login failed [{exc.status_code}]: {exc}")

try:
    sdk.catalog.get_product(99999)
except NotFoundError:
    print("Product not found")

try:
    sdk.cart.apply_promo("INVALID")
except ValidationError as exc:
    print(f"Promo error: {exc}")

try:
    sdk.health()
except NetworkError:
    print("Server unreachable")
```

| Exception | When raised |
|---|---|
| `AuthenticationError` | 401 bad credentials or expired session |
| `AuthorizationError` | 403 insufficient role |
| `NotFoundError` | 404 resource does not exist |
| `ValidationError` | 400 or 422 invalid request data |
| `RateLimitError` | 429 too many requests |
| `ServerError` | 5xx server-side error |
| `NetworkError` | timeout, connection refused, or DNS failure |

---

## Configuration

```python
sdk = DLPClient(
    "https://pharmacy.example.com",
    timeout=30,
    verify_ssl=True,
    debug=True,
)
```

---

## Running Tests

Install the package and development dependencies first:

```bash
pip install -e .[dev]
pytest tests/test_sdk.py -v
```

If you prefer non-editable installs:

```bash
pip install .[dev]
pytest tests/test_sdk.py -v
```

---

## Resource Overview

| Resource | Attribute | Key Methods |
|---|---|---|
| Authentication | `sdk.auth` | `admin_login`, `admin_logout`, `otp_request`, `otp_verify`, `totp_qr_uri` |
| Catalog | `sdk.catalog` | `list_products`, `get_product`, `get_product_by_slug`, `related_products` |
| Cart | `sdk.cart` | `get`, `add`, `update`, `remove`, `apply_promo`, `remove_promo`, `clear` |
| Orders | `sdk.orders` | `create`, `get`, `validate_promo` |
| Admin | `sdk.admin` | `stats`, `reports`, `integrations`, `download_invoice`, `whatsapp_link`, `download_barcode`, `download_qr`, `download_shipping_label`, `download_item_labels` |
| Mobile/Content | `sdk.mobile` | `home`, `wishlist`, `wishlist_add`, `newsletter_subscribe` |

---

## License

MIT Copyright Daily Life Pharmacy Engineering
