This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
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.
Dependency management is via Poetry.
poetry install # install dependencies
poetry lock # after editing pyproject.toml dependenciesmake publish # poetry lock && poetry export --output requirements.txt && poetry build && poetry publishBump the version field in pyproject.toml before publishing. requirements.txt is a generated lockfile artifact (via poetry export) — don't hand-edit it.
dcipher/client.py—Dcipher, the synchronous client (requests). Ownsrun_flow(), which POSTs to/flows/{flow_id}/run, and (ifwait_until_completion=True) polls/flows/{flow_id}/statusuntil 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). SubclassesDcipherto reuse its request-building/parsing/error-mapping helpers, but re-implementsrun_flow()withasync/awaitandasyncio.sleepinstead ofrequests/sleep. Keep the tworun_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 bytenacityretry decorators), andTaskStatus/FAILED_TASK_STATUSES, which mirror theTaskStatusenum indcipher-api(src/project/constants/task.ts). The/statusendpoint uppercases task status strings before returning them (FlowStatusCheckOutput.createindcipher-api), soTaskStatusvalues here are the uppercased forms (SUCCEEDED,FAILED,CANCELLED,CANCELFAILED,PENDING,QUEUED,RUNNING,CANCELLING). Ifdcipher-api's enum changes, mirror the change here too.dcipher/exceptions.py— exception hierarchy.APIStatusErrorsubclasses map to HTTP status codes (see table in README);WorkflowFailedExceptionis raised when a polled task reaches a failed/cancelled status.dcipher/logger.py— configures the root logger based onDCIPHER_LOGenv var (defaultERROR); silences noisy sub-loggers (httpx,httpcore,asyncio,urllib3) toWARN.
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.
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.