{
  "slug": "sdk/python",
  "title": "Python SDK",
  "description": "Send Cuitty events from Python — sync or async, with built-in batching and HMAC signing.",
  "url": "https://cuitty.com/docs/sdk/python",
  "markdown_url": "https://cuitty.com/docs/sdk/python.md",
  "json_url": "https://cuitty.com/docs/sdk/python.json",
  "frontmatter": {
    "title": "Python SDK",
    "description": "Send Cuitty events from Python — sync or async, with built-in batching and HMAC signing.",
    "order": 2,
    "section": "SDK",
    "updatedAt": "2026-04-27"
  },
  "headings": [
    {
      "depth": 1,
      "slug": "python-sdk",
      "text": "Python SDK"
    },
    {
      "depth": 2,
      "slug": "planned-api",
      "text": "Planned API"
    },
    {
      "depth": 2,
      "slug": "wire-protocol-equivalent-today",
      "text": "Wire-protocol equivalent today"
    },
    {
      "depth": 2,
      "slug": "live-performance-numbers",
      "text": "Live performance numbers"
    },
    {
      "depth": 2,
      "slug": "see-also",
      "text": "See also"
    }
  ],
  "body_markdown": "# Python SDK\n\n> **Status: Preview.** The Python SDK is on the Phase 3 roadmap. Until it ships you can use [the wire protocol directly](/docs/reference/wire-protocol) — every Python HTTP client supports the small surface area required.\n\n## Planned API\n\n```python\nfrom cuitty import Client\n\nc = Client(\n    portal_url=\"https://app.cuitty.com\",\n    project_id=PROJECT_ID,\n    api_key=API_KEY,\n)\n\nc.audit(\n    actor=\"alice@example.com\",\n    action=\"secret.rotate\",\n    resource=\"stripe.live_key\",\n)\n\nc.flush()\n```\n\n## Wire-protocol equivalent today\n\n```python\nimport hmac, hashlib, json, os, time\nimport urllib.request\n\nbody = json.dumps({\n    \"events\": [{\n        \"type\": \"audit\",\n        \"ts\": time.strftime(\"%Y-%m-%dT%H:%M:%SZ\", time.gmtime()),\n        \"data\": {\"actor\": \"alice@example.com\",\n                 \"action\": \"secret.rotate\",\n                 \"resource\": \"stripe.live_key\"},\n    }],\n}).encode()\n\nsig = hmac.new(os.environ[\"CUITTY_WEBHOOK_SECRET\"].encode(),\n               body, hashlib.sha256).hexdigest()\n\nreq = urllib.request.Request(\n    \"https://app.cuitty.com/api/ingest\",\n    data=body,\n    headers={\n        \"Authorization\": f\"Bearer {os.environ['CUITTY_API_KEY']}\",\n        \"Content-Type\": \"application/json\",\n        \"X-Cuitty-Signature\": sig,\n    },\n)\nprint(urllib.request.urlopen(req).read())\n```\n\n## Live performance numbers\n\nSee live benchmarks at [https://benchmarks.cuitty.com/sdks/python](https://benchmarks.cuitty.com/sdks/python).\n\n## See also\n\n- [Wire protocol](/docs/reference/wire-protocol)\n- [SDK parity & divergence](/docs/sdk/parity)",
  "links_out": [
    "/docs/reference/wire-protocol",
    "https://benchmarks.cuitty.com/sdks/python",
    "/docs/sdk/parity"
  ]
}