Metadata-Version: 2.4
Name: cqnce-sdk
Version: 0.1.0
Summary: Official Python SDK for cQnce
Author: cQnce
License: MIT
Project-URL: Homepage, https://github.com/cqnce-app/cqnce-sdk
Project-URL: Repository, https://github.com/cqnce-app/cqnce-sdk
Keywords: cqnce,sdk,auth,workflow
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: License :: OSI Approved :: MIT License
Requires-Python: >=3.9
Description-Content-Type: text/markdown

# Python SDK

## Files

- `cqnce_sdk.py`

## Features

- Submit requests (with optional request-based routing rule selection)
- List requests
- Get request details
- Get request status
- Verify callback signature (`X-cQnce-Signature`)
- **Polling helpers** for callback-free scenarios (e.g. desktop apps)

## Dependencies

- Python standard library only

## Quick use

```python
from cqnce_sdk import CqnceClient, CallbackVerifier

client = CqnceClient(base_url="http://localhost:3000", project_api_key="PROJECT_API_KEY")
result = client.submit_request(payload={"action": "payment", "amount": 500})
request_id = result["requestId"]

# Callback verification
ok = CallbackVerifier.verify(raw_body_bytes, signature_header, "shared-secret")
```

## Request-based routing

Pass `routing_rule_id` to route the request through a specific routing rule,
bypassing the server-side filter-expression evaluation:

```python
result = client.submit_request(
    payload={"action": "payment", "amount": 500},
    routing_rule_id="rule-uuid-here",   # directly select a routing rule
    routing_mode="SERIAL",               # optional mode override
)
```

## Polling helpers

Use these when you cannot host an HTTP callback endpoint (desktop/CLI apps).

### Blocking (synchronous)

```python
# Blocks the calling thread until APPROVED / REJECTED / EXPIRED / CANCELLED
final = client.poll_until_resolved(
    request_id,
    on_resolved=lambda status: print("Resolved:", status["status"]),
    interval_seconds=2,
    timeout_seconds=120,
)
```

### Background thread (non-blocking)

```python
thread = client.poll_until_resolved_background(
    request_id,
    on_resolved=lambda status: print("Resolved:", status["status"]),
    on_timeout=lambda: print("Timed out!"),
    interval_seconds=2,
    timeout_seconds=120,
)
# The calling thread continues immediately; on_resolved is called from the background thread.
thread.join()  # optional – wait for the thread
```

