The SDK uses uv as its package manager with Ruff for linting and mypy/Pyright for type-checking; pydantic-v1 and pydantic-v2 dependency groups are kept separate via conflict enforcement, and the project's own lru_cache replaces functools.lru_cache to preserve type information. The CI pipeline in .github/workflows/ci.yml runs lint, build, and test jobs on each push and pull request, with branch-filtering that skips internal codegen branches, while a separate breaking-change detection job checks compatibility against main.
The project uses uv as its package manager, requiring uv>=0.9 enforced via required-version.[1] The uv configuration pins the index to public PyPI to ensure consistent resolution regardless of a contributor's global uv config.[1] The pydantic-v1 and pydantic-v2 dependency groups conflict with each other, and pydantic-v1 also conflicts with the mcp extra — uv enforces both via its conflicts setting.[1]
Ruff is configured with line length 120, targeting Python 3.8 syntax, and enforces isort, bugbear rules, unused-import removal, missing future annotations, bare excepts, unused arguments, print statements, TYPE_CHECKING misuse, and import rules.[1] functools.lru_cache is banned by ruff because it does not retain type information for wrapped function arguments; the project's own lru_cache from _utils must be used instead.[1] src/anthropic/_files.py is excluded from mypy type-checking because mypy cannot apply correct type narrowing to it; Pyright is relied on instead for that internal module.[1]
Tests are run with pytest using --tb=short -n auto (parallel by default via pytest-xdist), with asyncio_mode = "auto" and all warnings treated as errors.[1]
The CI pipeline in .github/workflows/ci.yml runs three core jobs — lint, build, and test — all on ubuntu-latest with a 10-minute timeout, triggered on pushes to most branches and on pull requests from forks.[2] Pushes to branches named integrated/**, stl-preview-head/**, stl-preview-base/**, generated, and codegen/** (except codegen/stl/**) are skipped by the CI workflow.[2] CI pins uv at version 0.10.2 via astral-sh/setup-uv, installs dependencies with uv sync --all-extras, and invokes ./scripts/lint, ./scripts/bootstrap, ./scripts/test, and uv build for the respective jobs.[2] The build job uploads a build artifact to https://pkg.stainless.com/s using a GitHub OIDC token, but only when running in the anthropics/anthropic-sdk-python-private repository and not on a branch starting with refs/heads/stl/.[2]
The detect_breaking_changes_vs_main job runs on depot-ubuntu-24.04 for the internal stainless-sdks/anthropic-python repository and falls back to ubuntu-latest for all other forks and mirrors.[2] The job uses fetch-depth: 0 and filter: blob:none on checkout so git merge-base HEAD origin/main can resolve the fork point cheaply without downloading all file blobs.[2] Before running detection, the job checks out the breaking-change detection script from the base SHA, ensuring detection still works even when entire detection scripts are removed in the current branch.[2] The detect_breaking_changes_vs_main job is skipped on release-please-- branches to avoid false positives during automated releases.[2]
Sources