Skip to main content

Official Python client for the Dhanavega API — generated Pydantic models (datamodel-code-generator) over a thin httpx client core. See issue #41, ADR 0037.

Project description

dhanavega-sdk

Official Python client for the Dhanavega API. Generated Pydantic v2 models (via datamodel-code-generator) over a thin httpx client core — auth, Idempotency-Key autogeneration, RFC 9457 problem+json error parsing, If-Match concurrency, and cursor pagination. See issue #41 and ADR 0037 for the design rationale.

Status: buildable and test-covered; not yet published to PyPI (issue #41 — publication is a manual step performed by the maintainers once the platform reaches its India-GA milestone). Everything below documents the eventual pip install dhanavega-sdk experience.

Install

pip install dhanavega-sdk
# or
uv add dhanavega-sdk

Quickstart

from dhanavega_sdk import DhanavegaClient

client = DhanavegaClient(base_url="https://api.dhanavega.example", token="…")

response = client.request("los", "GET", "/los/leads")
print(response.data)

Or with a token getter (refreshed per request):

client = DhanavegaClient(
    base_url="https://api.dhanavega.example",
    get_token=lambda: fetch_short_lived_token(),
)

An async client is available too:

from dhanavega_sdk import AsyncDhanavegaClient

async with AsyncDhanavegaClient(base_url="...", token="...") as client:
    response = await client.request("los", "GET", "/los/leads")

Auth

tenant_id is never sent by the client — the API derives it server-side from the bearer JWT (api-docs/02-auth-tenancy-scopes.md). Supply either a static token or a get_token callable; the client sets the Authorization: Bearer <token> header on every request.

Idempotency

Every POST/PUT/PATCH/DELETE requires an Idempotency-Key header (api-docs/04-idempotency-concurrency-webhooks.md §1). The client autogenerates a uuid4 for every mutating request unless you pass your own (e.g. to deliberately replay an attempt):

client.request("los", "POST", "/los/applications", json=body, idempotency_key="my-own-key")

A stored replay comes back with response.idempotency_replayed is True.

Error handling

Every non-2xx response raises DhanavegaProblemError — never a bare httpx.HTTPStatusError — parsed from the platform's RFC 9457 application/problem+json envelope (api-docs/03-errors-pagination.md §1). Branch on error.code (a DhanavegaErrorCode), never on error.detail text:

from dhanavega_sdk import DhanavegaProblemError

try:
    client.request("los", "POST", "/los/applications", json=body)
except DhanavegaProblemError as error:
    if error.code == "VALIDATION_FAILED":
        for field_error in error.errors or []:
            print(field_error.pointer, field_error.rule)
    elif error.code == "RATE_LIMITED":
        print("retry after", error.retry_after)

Concurrency (If-Match)

from dhanavega_sdk import with_if_match

client.request(
    "los", "PATCH", f"/los/applications/{app_id}",
    json=patch_body,
    **with_if_match(etag),
)

Missing If-Match on a mutable-entity mutation → 428 PRECONDITION_REQUIRED; a stale one → 412 VERSION_CONFLICT.

Pagination

from dhanavega_sdk import paginate

for lead in paginate(lambda cursor: client.request(
    "los", "GET", "/los/leads", params={"page[after]": cursor} if cursor else None,
).data):
    print(lead)

paginate walks page.has_more / page.next_cursor until the stream ends — cursors are opaque; never parse or construct them yourself.

Regenerating models

uv sync --group codegen
uv run --group codegen python scripts/generate_models.py

Regenerates every committed file under src/dhanavega_sdk/models/ from planning/api-docs/openapi/**. Run this whenever a contract YAML changes — tests/test_models_drift.py fails CI if the committed models fall out of sync with the contract.

Publish procedure (manual, first release)

Publication is intentionally not automated yet (issue #41). CI's sdk-release.yml carries a publish-sdk-pypi job gated behind the PUBLISH_ENABLED repo variable, which is unset today. To publish manually once the maintainers decide to:

cd packages/sdk-python
uv build
uv publish --token "$PYPI_TOKEN"

Development

uv sync
uv run ruff check .
uv run ruff format --check .
uv run mypy src
uv run pytest

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

dhanavega_sdk-0.1.0.tar.gz (102.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

dhanavega_sdk-0.1.0-py3-none-any.whl (74.8 kB view details)

Uploaded Python 3

File details

Details for the file dhanavega_sdk-0.1.0.tar.gz.

File metadata

  • Download URL: dhanavega_sdk-0.1.0.tar.gz
  • Upload date:
  • Size: 102.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for dhanavega_sdk-0.1.0.tar.gz
Algorithm Hash digest
SHA256 873ece6dba50ce6a50ffa74aaa557f764a8772564d876cc4706eca6839fb68d9
MD5 a982ac3416014cb532058cab582e3b41
BLAKE2b-256 e86055f7fc9dc6d823f1df0b2c025de4e6e1ae7c2f04635bcdc0f72b273e43a8

See more details on using hashes here.

File details

Details for the file dhanavega_sdk-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: dhanavega_sdk-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 74.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for dhanavega_sdk-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e891435dde948938c108a86381a0c037ee8e4220e5da51b74f6ff4e6a18dd932
MD5 14f8c246941ccdda6144739fb0d83cea
BLAKE2b-256 3b1234ffb5034251f2adc47aac8bd91744bff1fe01ee609922ef430e153c756f

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page