Skip to content

Commit 0e60f66

Browse files
ignore: python sdk (#2779)
Co-authored-by: Aiden Cline <[email protected]>
1 parent fc8db6c commit 0e60f66

File tree

229 files changed

+22322
-8
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

229 files changed

+22322
-8
lines changed

.github/publish-python-sdk.yml

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
#
2+
# This file is intentionally in the wrong dir, will move and add later....
3+
#
4+
5+
# name: publish-python-sdk
6+
7+
# on:
8+
# release:
9+
# types: [published]
10+
# workflow_dispatch:
11+
12+
# jobs:
13+
# publish:
14+
# runs-on: ubuntu-latest
15+
# permissions:
16+
# contents: read
17+
# steps:
18+
# - name: Checkout repository
19+
# uses: actions/checkout@v4
20+
21+
# - name: Setup Bun
22+
# uses: oven-sh/setup-bun@v1
23+
# with:
24+
# bun-version: 1.2.21
25+
26+
# - name: Install dependencies (JS/Bun)
27+
# run: bun install
28+
29+
# - name: Install uv
30+
# shell: bash
31+
# run: curl -LsSf https://astral.sh/uv/install.sh | sh
32+
33+
# - name: Generate Python SDK from OpenAPI (CLI)
34+
# shell: bash
35+
# run: |
36+
# ~/.local/bin/uv run --project packages/sdk/python python packages/sdk/python/scripts/generate.py --source cli
37+
38+
# - name: Sync Python dependencies
39+
# shell: bash
40+
# run: |
41+
# ~/.local/bin/uv sync --dev --project packages/sdk/python
42+
43+
# - name: Set version from release tag
44+
# shell: bash
45+
# run: |
46+
# TAG="${GITHUB_REF_NAME:-}"
47+
# if [ -z "$TAG" ]; then
48+
# TAG="$(git describe --tags --abbrev=0 || echo 0.0.0)"
49+
# fi
50+
# echo "Using version: $TAG"
51+
# VERSION="$TAG" ~/.local/bin/uv run --project packages/sdk/python python - <<'PY'
52+
# import os, re, pathlib
53+
# root = pathlib.Path('packages/sdk/python')
54+
# pt = (root / 'pyproject.toml').read_text()
55+
# version = os.environ.get('VERSION','0.0.0').lstrip('v')
56+
# pt = re.sub(r'(?m)^(version\s*=\s*")[^"]+("\s*)$', f"\\1{version}\\2", pt)
57+
# (root / 'pyproject.toml').write_text(pt)
58+
# # Also update generator config override for consistency
59+
# cfgp = root / 'openapi-python-client.yaml'
60+
# if cfgp.exists():
61+
# cfg = cfgp.read_text()
62+
# cfg = re.sub(r'(?m)^(package_version_override:\s*)\S+$', f"\\1{version}", cfg)
63+
# cfgp.write_text(cfg)
64+
# PY
65+
66+
# - name: Build and publish to PyPI
67+
# env:
68+
# PYPI_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
69+
# shell: bash
70+
# run: |
71+
# ~/.local/bin/uv run --project packages/sdk/python python packages/sdk/python/scripts/publish.py

packages/plugin/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,4 @@
2424
"typescript": "catalog:",
2525
"@typescript/native-preview": "catalog:"
2626
}
27-
}
27+
}

packages/sdk/js/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,4 @@
2626
"publishConfig": {
2727
"directory": "dist"
2828
}
29-
}
29+
}

packages/sdk/python/.gitignore

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
__pycache__/
2+
*.py[cod]
3+
*.egg-info/
4+
.build/
5+
build/
6+
dist/
7+
.coverage
8+
htmlcov/
9+
.mypy_cache/
10+
.pytest_cache/
11+
.ruff_cache/
12+
.venv/
13+
.conda/
14+
.env
15+
.DS_Store
16+
openapi.json
17+
site/
18+
19+
20+
# IDE
21+
.vscode/
22+
.idea/

packages/sdk/python/README.md

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
# Opencode Python SDK
2+
3+
This package provides a Python SDK for the Opencode API. It is generated using openapi-python-client (not Stainless).
4+
5+
6+
Documentation
7+
- Full docs: see `mkdocs` site under `packages/sdk/python/docs/`
8+
- Preview locally:
9+
```bash
10+
uv run --project packages/sdk/python mkdocs serve -f packages/sdk/python/mkdocs.yml
11+
```
12+
13+
Badges
14+
- PyPI: https://img.shields.io/pypi/v/opencode-ai?style=flat-square
15+
16+
Requirements
17+
- Python 3.8+
18+
- uv (recommended) -> https://docs.astral.sh/uv/
19+
- openapi-python-client (invoked via `uvx`)
20+
21+
Install uv
22+
```bash
23+
# macOS/Linux
24+
curl -LsSf https://astral.sh/uv/install.sh | sh
25+
```
26+
27+
Set up the environment (from this directory)
28+
```bash
29+
uv sync --dev
30+
```
31+
32+
Generate client code (from CLI-generated spec)
33+
```bash
34+
# From repository root OR from this directory
35+
uv run python packages/sdk/python/scripts/generate.py --source cli
36+
```
37+
38+
Alternatively, fetch spec from a running server
39+
```bash
40+
uv run python packages/sdk/python/scripts/generate.py --source server --server-url http://localhost:4096/doc
41+
```
42+
43+
This will:
44+
1) Produce an OpenAPI spec from the local CLI or a running server
45+
2) Run openapi-python-client (via `uvx`) to generate client code
46+
3) Copy the generated Python package into src/opencode_ai
47+
48+
Usage (after generation)
49+
```python
50+
from opencode_ai import OpenCodeClient
51+
52+
client = OpenCodeClient(base_url="http://localhost:4096")
53+
print(client.get_config())
54+
55+
# See examples/basic_usage.py for more details
56+
57+
# Streaming events (sync)
58+
for event in client.subscribe_events():
59+
print(event)
60+
break
61+
62+
# Error handling and retries
63+
# Set retries>0 to enable exponential backoff for transient errors like 429/5xx
64+
client = OpenCodeClient(retries=2, backoff_factor=0.1)
65+
66+
# Async usage example
67+
# uv run --project packages/sdk/python python - <<'PY'
68+
# import asyncio
69+
# from opencode_ai import OpenCodeClient
70+
# async def main():
71+
# client = OpenCodeClient()
72+
# async for event in client.subscribe_events_async():
73+
# print(event)
74+
# break
75+
# asyncio.run(main())
76+
# PY
77+
```
78+
79+
Notes
80+
- We intentionally do not use Stainless for the Python SDK.
81+
- The generator targets OpenAPI 3.1 emitted by the opencode server at /doc.
82+
- See scripts/generate.py for details and customization points.
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Generation workflow
2+
3+
The SDK is generated from the Opencode server's OpenAPI 3.1 spec.
4+
5+
Two source modes are supported:
6+
- CLI (default): runs `bun dev generate` to emit the OpenAPI JSON
7+
- Server: fetches `http://localhost:4096/doc` from a running server
8+
9+
Generator command
10+
```bash
11+
# From repo root
12+
uv run --project packages/sdk/python python packages/sdk/python/scripts/generate.py --source cli
13+
# Or
14+
uv run --project packages/sdk/python python packages/sdk/python/scripts/generate.py --source server --server-url http://localhost:4096/doc
15+
```
16+
17+
Post-generation
18+
- The generator injects `extras.py` (OpenCodeClient) and patches `__init__.py` to export it
19+
- Code is formatted with `ruff` (imports) and `black`

packages/sdk/python/docs/index.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Opencode Python SDK
2+
3+
The official Python client for the Opencode API, generated from the OpenAPI spec and extended with ergonomic helpers.
4+
5+
Highlights
6+
- Provider-agnostic client generated from OpenAPI 3.1
7+
- Thin convenience wrapper (OpenCodeClient) for common tasks
8+
- Sync and async SSE streaming for live event feeds
9+
- First-class uv support for development
10+
11+
If you're new, start with Quickstart or Installation in the navigation.
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Installation
2+
3+
Requirements
4+
- Python 3.8+
5+
- uv (recommended) -> https://docs.astral.sh/uv/
6+
7+
Install uv
8+
```bash
9+
curl -LsSf https://astral.sh/uv/install.sh | sh
10+
```
11+
12+
Project setup
13+
```bash
14+
# From repo root or this directory
15+
uv sync --dev --project packages/sdk/python
16+
```
17+
18+
Using pip (alternative)
19+
```bash
20+
pip install opencode-ai
21+
```
22+
23+
Preview docs locally
24+
```bash
25+
# From repo root
26+
uv run --project packages/sdk/python mkdocs serve -f packages/sdk/python/mkdocs.yml
27+
```
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Publishing (maintainers)
2+
3+
Automated publishing runs on GitHub Releases.
4+
5+
Workflow
6+
- Create a new Release (the tag value becomes the package version)
7+
- The `publish-python-sdk` workflow will:
8+
- Generate the SDK from OpenAPI (CLI path)
9+
- Set the version in `pyproject.toml` and generator config
10+
- Build wheel/sdist and upload to PyPI
11+
12+
Prerequisites
13+
- Repository secret: `PYPI_API_TOKEN`
14+
15+
Manual publish
16+
```bash
17+
# TestPyPI
18+
REPOSITORY=testpypi PYPI_TOKEN=$TEST_PYPI_API_TOKEN \
19+
uv run --project packages/sdk/python python packages/sdk/python/scripts/publish.py
20+
21+
# PyPI
22+
REPOSITORY=pypi PYPI_TOKEN=$PYPI_API_TOKEN \
23+
uv run --project packages/sdk/python python packages/sdk/python/scripts/publish.py
24+
```
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Quickstart
2+
3+
Create a client and make your first calls.
4+
5+
```python
6+
from opencode_ai import OpenCodeClient
7+
8+
client = OpenCodeClient(base_url="http://localhost:4096")
9+
10+
# List projects
11+
for p in client.list_projects() or []:
12+
print(p.id, p.directory)
13+
14+
# Get path info
15+
path = client.get_path()
16+
print(path.directory)
17+
18+
# Stream events (sync)
19+
for event in client.subscribe_events():
20+
print(event)
21+
break
22+
```

0 commit comments

Comments
 (0)