Skip to content

Commit 54bff2e

Browse files
authored
Merge pull request #1 from anthropics/initial-sdk-import
Initial Python SDK import
2 parents 19c71ae + 8c950a7 commit 54bff2e

File tree

22 files changed

+1796
-1
lines changed

22 files changed

+1796
-1
lines changed

.github/workflows/lint.yml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
name: Lint
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
pull_request:
7+
branches: [ main ]
8+
9+
jobs:
10+
lint:
11+
runs-on: ubuntu-latest
12+
13+
steps:
14+
- uses: actions/checkout@v4
15+
16+
- name: Set up Python
17+
uses: actions/setup-python@v5
18+
with:
19+
python-version: '3.12'
20+
21+
- name: Install dependencies
22+
run: |
23+
python -m pip install --upgrade pip
24+
pip install -e ".[dev]"
25+
26+
- name: Run ruff
27+
run: |
28+
ruff check src/ tests/
29+
ruff format --check src/ tests/
30+
31+
- name: Run mypy
32+
run: |
33+
mypy src/

.github/workflows/publish.yml

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
name: Publish to PyPI
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
version:
7+
description: 'Version to publish (e.g., 0.1.0)'
8+
required: true
9+
type: string
10+
test_pypi:
11+
description: 'Publish to Test PyPI first'
12+
required: false
13+
type: boolean
14+
default: true
15+
16+
jobs:
17+
test:
18+
runs-on: ubuntu-latest
19+
strategy:
20+
matrix:
21+
python-version: ['3.10', '3.11', '3.12', '3.13']
22+
23+
steps:
24+
- uses: actions/checkout@v4
25+
26+
- name: Set up Python ${{ matrix.python-version }}
27+
uses: actions/setup-python@v5
28+
with:
29+
python-version: ${{ matrix.python-version }}
30+
31+
- name: Install dependencies
32+
run: |
33+
python -m pip install --upgrade pip
34+
pip install -e ".[dev]"
35+
36+
- name: Run tests
37+
run: |
38+
python -m pytest tests/ -v
39+
40+
lint:
41+
runs-on: ubuntu-latest
42+
43+
steps:
44+
- uses: actions/checkout@v4
45+
46+
- name: Set up Python
47+
uses: actions/setup-python@v5
48+
with:
49+
python-version: '3.12'
50+
51+
- name: Install dependencies
52+
run: |
53+
python -m pip install --upgrade pip
54+
pip install -e ".[dev]"
55+
56+
- name: Run ruff
57+
run: |
58+
ruff check src/ tests/
59+
ruff format --check src/ tests/
60+
61+
- name: Run mypy
62+
run: |
63+
mypy src/
64+
65+
publish:
66+
needs: [test, lint]
67+
runs-on: ubuntu-latest
68+
69+
steps:
70+
- uses: actions/checkout@v4
71+
72+
- name: Set up Python
73+
uses: actions/setup-python@v5
74+
with:
75+
python-version: '3.12'
76+
77+
- name: Update version
78+
run: |
79+
# Update version in pyproject.toml
80+
sed -i 's/version = ".*"/version = "${{ github.event.inputs.version }}"/' pyproject.toml
81+
sed -i 's/__version__ = ".*"/__version__ = "${{ github.event.inputs.version }}"/' src/claude_code_sdk/__init__.py
82+
83+
- name: Install build dependencies
84+
run: |
85+
python -m pip install --upgrade pip
86+
pip install build twine
87+
88+
- name: Build package
89+
run: python -m build
90+
91+
- name: Check package
92+
run: twine check dist/*
93+
94+
- name: Publish to Test PyPI
95+
if: ${{ github.event.inputs.test_pypi == 'true' }}
96+
env:
97+
TWINE_USERNAME: __token__
98+
TWINE_PASSWORD: ${{ secrets.TEST_PYPI_API_TOKEN }}
99+
run: |
100+
twine upload --repository testpypi dist/*
101+
echo "Package published to Test PyPI"
102+
echo "Install with: pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ claude-code-sdk==${{ github.event.inputs.version }}"
103+
104+
- name: Publish to PyPI
105+
env:
106+
TWINE_USERNAME: __token__
107+
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
108+
run: |
109+
twine upload dist/*
110+
echo "Package published to PyPI"
111+
echo "Install with: pip install claude-code-sdk==${{ github.event.inputs.version }}"

.github/workflows/test.yml

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
name: Test
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
pull_request:
7+
branches: [ main ]
8+
9+
jobs:
10+
test:
11+
runs-on: ubuntu-latest
12+
strategy:
13+
matrix:
14+
python-version: ['3.10', '3.11', '3.12', '3.13']
15+
16+
steps:
17+
- uses: actions/checkout@v4
18+
19+
- name: Set up Python ${{ matrix.python-version }}
20+
uses: actions/setup-python@v5
21+
with:
22+
python-version: ${{ matrix.python-version }}
23+
24+
- name: Install dependencies
25+
run: |
26+
python -m pip install --upgrade pip
27+
pip install -e ".[dev]"
28+
29+
- name: Run tests
30+
run: |
31+
python -m pytest tests/ -v --cov=claude_code_sdk --cov-report=xml
32+
33+
- name: Upload coverage to Codecov
34+
uses: codecov/codecov-action@v4
35+
with:
36+
file: ./coverage.xml
37+
fail_ci_if_error: false

.gitignore

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# Python
2+
__pycache__/
3+
*.py[cod]
4+
*$py.class
5+
*.so
6+
.Python
7+
build/
8+
develop-eggs/
9+
dist/
10+
downloads/
11+
eggs/
12+
.eggs/
13+
lib/
14+
lib64/
15+
parts/
16+
sdist/
17+
var/
18+
wheels/
19+
*.egg-info/
20+
.installed.cfg
21+
*.egg
22+
MANIFEST
23+
24+
# Virtual environments
25+
venv/
26+
ENV/
27+
env/
28+
.venv
29+
30+
# IDEs
31+
.vscode/
32+
.idea/
33+
*.swp
34+
*.swo
35+
*~
36+
37+
# Testing
38+
.tox/
39+
.coverage
40+
.coverage.*
41+
.cache
42+
.pytest_cache/
43+
htmlcov/
44+
45+
# Type checking
46+
.mypy_cache/
47+
.dmypy.json
48+
dmypy.json
49+
.pyre/

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 Anthropic, PBC
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 132 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,132 @@
1-
# claude-code-sdk-python
1+
# Claude Code SDK for Python
2+
3+
Python SDK for Claude Code. See the [Claude Code SDK documentation](https://docs.anthropic.com/en/docs/claude-code/sdk) for more information.
4+
5+
## Installation
6+
7+
```bash
8+
pip install claude-code-sdk
9+
```
10+
11+
**Prerequisites:**
12+
- Python 3.10+
13+
- Node.js
14+
- Claude Code: `npm install -g @anthropic-ai/claude-code`
15+
16+
## Quick Start
17+
18+
```python
19+
import anyio
20+
from claude_code_sdk import query
21+
22+
async def main():
23+
async for message in query(prompt="What is 2 + 2?"):
24+
print(message)
25+
26+
anyio.run(main)
27+
```
28+
29+
## Usage
30+
31+
### Basic Query
32+
33+
```python
34+
from claude_code_sdk import query, ClaudeCodeOptions, AssistantMessage, TextBlock
35+
36+
# Simple query
37+
async for message in query(prompt="Hello Claude"):
38+
if isinstance(message, AssistantMessage):
39+
for block in message.content:
40+
if isinstance(block, TextBlock):
41+
print(block.text)
42+
43+
# With options
44+
options = ClaudeCodeOptions(
45+
system_prompt="You are a helpful assistant",
46+
max_turns=1
47+
)
48+
49+
async for message in query(prompt="Tell me a joke", options=options):
50+
print(message)
51+
```
52+
53+
### Using Tools
54+
55+
```python
56+
options = ClaudeCodeOptions(
57+
allowed_tools=["Read", "Write", "Bash"],
58+
permission_mode='acceptEdits' # auto-accept file edits
59+
)
60+
61+
async for message in query(
62+
prompt="Create a hello.py file",
63+
options=options
64+
):
65+
# Process tool use and results
66+
pass
67+
```
68+
69+
### Working Directory
70+
71+
```python
72+
from pathlib import Path
73+
74+
options = ClaudeCodeOptions(
75+
cwd="/path/to/project" # or Path("/path/to/project")
76+
)
77+
```
78+
79+
## API Reference
80+
81+
### `query(prompt, options=None)`
82+
83+
Main async function for querying Claude.
84+
85+
**Parameters:**
86+
- `prompt` (str): The prompt to send to Claude
87+
- `options` (ClaudeCodeOptions): Optional configuration
88+
89+
**Returns:** AsyncIterator[Message] - Stream of response messages
90+
91+
### Types
92+
93+
See [src/claude_code_sdk/types.py](src/claude_code_sdk/types.py) for complete type definitions:
94+
- `ClaudeCodeOptions` - Configuration options
95+
- `AssistantMessage`, `UserMessage`, `SystemMessage`, `ResultMessage` - Message types
96+
- `TextBlock`, `ToolUseBlock`, `ToolResultBlock` - Content blocks
97+
98+
## Error Handling
99+
100+
```python
101+
from claude_code_sdk import (
102+
ClaudeSDKError, # Base error
103+
CLINotFoundError, # Claude Code not installed
104+
CLIConnectionError, # Connection issues
105+
ProcessError, # Process failed
106+
CLIJSONDecodeError, # JSON parsing issues
107+
)
108+
109+
try:
110+
async for message in query(prompt="Hello"):
111+
pass
112+
except CLINotFoundError:
113+
print("Please install Claude Code")
114+
except ProcessError as e:
115+
print(f"Process failed with exit code: {e.exit_code}")
116+
except CLIJSONDecodeError as e:
117+
print(f"Failed to parse response: {e}")
118+
```
119+
120+
See [src/claude_code_sdk/_errors.py](src/claude_code_sdk/_errors.py) for all error types.
121+
122+
## Available Tools
123+
124+
See the [Claude Code documentation](https://docs.anthropic.com/en/docs/claude-code/security#tools-available-to-claude) for a complete list of available tools.
125+
126+
## Examples
127+
128+
See [examples/quick_start.py](examples/quick_start.py) for a complete working example.
129+
130+
## License
131+
132+
MIT

0 commit comments

Comments
 (0)