Skip to content

Latest commit

 

History

History
40 lines (25 loc) · 3.33 KB

CLAUDE.md

File metadata and controls

40 lines (25 loc) · 3.33 KB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

What this is

The official Python client library for the Dcipher Workflows API (PyPI package dcipher). It's a thin HTTP wrapper — no framework, no server code, just two client classes and shared support modules. Public API docs: https://app.dcipheranalytics.com/workflows.

Development commands

Dependency management is via Poetry.

poetry install              # install dependencies
poetry lock                 # after editing pyproject.toml dependencies

Publishing a release

make publish   # poetry lock && poetry export --output requirements.txt && poetry build && poetry publish

Bump the version field in pyproject.toml before publishing. requirements.txt is a generated lockfile artifact (via poetry export) — don't hand-edit it.

Architecture

  • dcipher/client.py — Dcipher, the synchronous client (requests). Owns run_flow(), which POSTs to /flows/{flow_id}/run, and (if wait_until_completion=True) polls /flows/{flow_id}/status until the task reaches a terminal status. Also owns response-URL extraction/download (_save_result(s)) and HTTP-status → exception mapping (_make_status_error).
  • dcipher/async_client.py — AsyncDcipher(Dcipher), the async counterpart (httpx). Subclasses Dcipher to reuse its request-building/parsing/error-mapping helpers, but re-implements run_flow() with async/await and asyncio.sleep instead of requests/sleep. Keep the two run_flow() implementations in sync when changing polling/status-handling logic — there's no shared base method for the polling loop itself.
  • dcipher/constants.py — RETRIABLE_EXCEPTIONS (used by tenacity retry decorators), and TaskStatus / FAILED_TASK_STATUSES, which mirror the TaskStatus enum in dcipher-api (src/project/constants/task.ts). The /status endpoint uppercases task status strings before returning them (FlowStatusCheckOutput.create in dcipher-api), so TaskStatus values here are the uppercased forms (SUCCEEDED, FAILED, CANCELLED, CANCELFAILED, PENDING, QUEUED, RUNNING, CANCELLING). If dcipher-api's enum changes, mirror the change here too.
  • dcipher/exceptions.py — exception hierarchy. APIStatusError subclasses map to HTTP status codes (see table in README); WorkflowFailedException is raised when a polled task reaches a failed/cancelled status.
  • dcipher/logger.py — configures the root logger based on DCIPHER_LOG env var (default ERROR); silences noisy sub-loggers (httpx, httpcore, asyncio, urllib3) to WARN.

Retry behavior

Both clients wrap their HTTP calls in tenacity.retry using RETRIABLE_EXCEPTIONS from constants.py (connection/timeout errors, 409, 429, >=500, and JSON decode failures) with random exponential backoff. max_retries is a constructor argument on Dcipher/AsyncDcipher.

Status polling contract

When wait_until_completion=True, run_flow() polls until status is SUCCEEDED (success) or one of FAILED_TASK_STATUSES (FAILED, CANCELLED, CANCELFAILED — raises WorkflowFailedException). Any other status (PENDING, QUEUED, RUNNING, CANCELLING, or the pre-task "setting up cluster" placeholder from dcipher-api) is treated as still in progress.