Skip to main content

Official Python SDK for the CannaSage Developer API.

Project description

cannasage

Official Python SDK for the CannaSage Developer API. Async-first (httpx) with a sync compatibility wrapper.

Beta. This SDK is pre-1.0 and may change. Pin a specific version in production.

Install

pip install cannasage

Quick start (async)

import asyncio
from cannasage import AsyncCannaSageClient

async def main():
    async with AsyncCannaSageClient(api_key="csk_live_...") as cs:
        result = await cs.sops.list(category="ipm")
        print(result.data)

asyncio.run(main())

Quick start (sync)

from cannasage import CannaSageClient

cs = CannaSageClient(api_key="csk_live_...")
print(cs.sops.list(category="ipm").data)

The sync wrapper spawns a fresh asyncio event loop per call. If you're making many sequential calls, use AsyncCannaSageClient inside a single asyncio.run() block for better throughput.

Authentication

Mode Usage
API key AsyncCannaSageClient(api_key="csk_live_...")
Bearer JWT AsyncCannaSageClient(bearer_token="<jwt>")
OAuth client credentials AsyncCannaSageClient(client_id="...", client_secret="...", scopes=["read"])

The OAuth client exchanges credentials lazily on the first request and caches the access token until ~1 minute before expiry.

Resources

Resource Methods
sops list, get
projects list, get
connectors list, get, create, update, delete, sync, devices, data, push_data
environmental list_data
insights list
grow_tracking costs, harvests
webhooks list_events, list, create, update, delete, list_deliveries, test, redeliver
oauth list, create, delete
keys list, create, revoke, rotate, force_revoke, set_rate_limit, usage

Every method returns an ApiResponse with .data and .meta attributes.

Webhook signature verification

from fastapi import FastAPI, Request, HTTPException
from cannasage import verify_webhook_signature

app = FastAPI()
SECRET = "whsec_..."

@app.post("/webhooks/cannasage")
async def handle_webhook(request: Request):
    raw_body = await request.body()
    signature = request.headers.get("X-CannaSage-Signature", "")
    if not verify_webhook_signature(raw_body, signature, SECRET):
        raise HTTPException(status_code=401, detail="invalid signature")
    event = await request.json()
    # ... handle event
    return {"ok": True}

verify_webhook_signature uses hmac.compare_digest (constant-time) and never raises on mismatch — it returns bool.

Error handling

All HTTP errors raise CannaSageAPIError:

from cannasage import CannaSageAPIError

try:
    await cs.sops.get("missing")
except CannaSageAPIError as err:
    print(err.code, err.status, err.request_id)
    if err.code == "NOT_FOUND":
        ...

Retries, timeouts, idempotency

  • Retries: up to 3 on 429 (rate limited) and 503 (overloaded). Retry-After is honoured with a 30s cap.
  • Timeout: default 30s per request. Override via AsyncCannaSageClient(timeout_seconds=60).
  • Idempotency: POST requests automatically receive a random Idempotency-Key header (forward-compatible — server support coming in a future release).

License

MIT — see LICENSE.

Links

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

cannasage-0.1.0b1.tar.gz (11.2 kB view details)

Uploaded Source

Built Distribution

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

cannasage-0.1.0b1-py3-none-any.whl (18.0 kB view details)

Uploaded Python 3

File details

Details for the file cannasage-0.1.0b1.tar.gz.

File metadata

  • Download URL: cannasage-0.1.0b1.tar.gz
  • Upload date:
  • Size: 11.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for cannasage-0.1.0b1.tar.gz
Algorithm Hash digest
SHA256 8cbb73747871afdb7d311820215152866fc5f11d0e8c449e526c7de18e1a1e5b
MD5 45bf4f4db95bab006744e204931f34b8
BLAKE2b-256 3c6288c9fc838499b9044afe5e57163e3aa915d6c11b0c9c98bb8bb5e10085c8

See more details on using hashes here.

Provenance

The following attestation bundles were made for cannasage-0.1.0b1.tar.gz:

Publisher: publish-sdks.yml on AppSprout-dev/CannaSage

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file cannasage-0.1.0b1-py3-none-any.whl.

File metadata

  • Download URL: cannasage-0.1.0b1-py3-none-any.whl
  • Upload date:
  • Size: 18.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for cannasage-0.1.0b1-py3-none-any.whl
Algorithm Hash digest
SHA256 41c6c1959dc4d1ca355319b0d840a2def8c3526d8e357ecb19225042d10ee556
MD5 10a3fa7177bdff964df9f9b68db54956
BLAKE2b-256 1d6cfeb6053055979fdce81f40ef00bd8bcd55e9c1934e2388f63abf35871c3e

See more details on using hashes here.

Provenance

The following attestation bundles were made for cannasage-0.1.0b1-py3-none-any.whl:

Publisher: publish-sdks.yml on AppSprout-dev/CannaSage

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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