Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

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.

Metadata

Release files for cannasage 0.1.0b2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for cannasage 0.1.0b2
File Size Uploaded Provenance
cannasage-0.1.0b2.tar.gz 11.2 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for cannasage 0.1.0b2
File Interpreter ABI Platform
cannasage-0.1.0b2-py3-none-any.whl Python 3 none any Details

Total release size: 29.2 kB

Release files / cannasage-0.1.0b2.tar.gz

Download URL cannasage-0.1.0b2.tar.gz
Size 11.2 kB
Tags Source
SHA-256 checksum
How to use checksums
82fb32add8a6722747779959bfafa7446e2a735e2d567a098853a19a3f647b5f
BLAKE2b-256 checksum
How to use checksums
36d39feb8d7cad322497a529fa34b4b3c406aa24633f11398e913cb424ea2a00
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 14, 2026.

Transparency log

Release files / cannasage-0.1.0b2-py3-none-any.whl

Download URL cannasage-0.1.0b2-py3-none-any.whl
Size 18.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f9980552d988cbb6e07e96daa146e6fe9d78e2fb3837aab7f4fc1a1bfb1dc7e4
BLAKE2b-256 checksum
How to use checksums
b06dd042b95f879f4eafa0046a4684950ac22f04f3ca1046463a427ce5be2112
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 14, 2026.

Transparency log

Security for cannasage 0.1.0b2

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for cannasage-0.1.0b2.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 14, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page