Skip to content

Commit d24d36b

Browse files
chengzeyiclaude
andcommitted
Remove serverless worker from the SDK (BREAKING)
WaveSpeed no longer offers serverless as an external product. Shipping a serverless worker implementation in the public Python SDK advertised a capability customers cannot actually buy, which is misleading — so the implementation is removed rather than left in place to rot. Removed: - src/wavespeed/serverless/ — the whole package: serverless.start(), the job scaler, handler-type dispatch, worker HTTP layer, FastAPI local dev server, local test mode, job/worker state, heartbeat, progress reporting, the boto3 S3 helpers, and utils.validate. - tests/test_serverless/ — its test suite. - images/ — the test_worker Docker image and build/push scripts, which existed solely to build and exercise the worker. - wavespeed.config.serverless plus the import-time environment detection. RUNPOD_* and WAVERLESS_* variables are no longer read by this package. - .dockerignore, which only ever scoped the worker image build. The API client is deliberately untouched: run, run_no_throw, get_result, upload, Client, wavespeed.config.api, and the channel-attribution headers all behave exactly as they did in 1.0.x. config.py kept its `api` class and the install_config_module() call, so wavespeed.config.patch() still works; only the serverless namespace and its loaders were excised. Dependencies drop to what the client actually uses: aiohttp, aiohttp[speedups], aiohttp-retry and boto3 were serverless-only and are gone. typing_extensions is now declared explicitly — _config_module has always imported it, it was just never listed. This removes public API, so the next release is 2.0.0. Worker users should pin wavespeed<2 and plan to migrate. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LJJXU9zyoDSBjApcUpteDt
1 parent 5b94f92 commit d24d36b

45 files changed

Lines changed: 127 additions & 6730 deletions

Some content is hidden

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

.dockerignore

Lines changed: 0 additions & 12 deletions
This file was deleted.

CHANGELOG.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# Changelog
2+
3+
All notable changes to this project are documented here.
4+
5+
Versions are derived from Git tags via `setuptools_scm` — see [VERSIONING.md](VERSIONING.md).
6+
7+
## 2.0.0 — Unreleased
8+
9+
### Removed — BREAKING
10+
11+
**The serverless worker implementation has been removed from the SDK.**
12+
13+
WaveSpeed no longer offers serverless as an external product, so shipping a serverless worker in
14+
the public SDK was misleading: it advertised a capability customers cannot buy. Everything below is
15+
gone as of 2.0.0 and will not be restored.
16+
17+
- `wavespeed.serverless` — the entire package, including `serverless.start()`, the job scaler, the
18+
handler-type dispatcher, the worker HTTP layer, the FastAPI local dev server, local test mode,
19+
worker/job state tracking, heartbeat and progress reporting, the S3 (`boto3`) upload helpers, and
20+
`wavespeed.serverless.utils.validate`.
21+
- `wavespeed.config.serverless` — the serverless config namespace and its import-time environment
22+
auto-detection (`RUNPOD_*` and `WAVERLESS_*` variables are no longer read by this package).
23+
- `images/` — the `test_worker` Docker image and its build/push scripts, which existed only to
24+
build and exercise the worker.
25+
26+
Anyone building workers against this package should pin `wavespeed<2` and plan to migrate.
27+
28+
### Changed
29+
30+
- Dependencies trimmed to what the API client actually needs. `aiohttp`, `aiohttp[speedups]`,
31+
`aiohttp-retry`, and `boto3` are no longer installed; `typing_extensions` is now declared
32+
explicitly (it was already imported by `wavespeed._config_module`).
33+
- README and CLAUDE.md rewritten to describe an API-client-only SDK.
34+
35+
### Unchanged
36+
37+
The API client surface is untouched: `wavespeed.run`, `wavespeed.run_no_throw`,
38+
`wavespeed.get_result`, `wavespeed.upload`, `wavespeed.Client`, `wavespeed.config.api`, and the
39+
channel-attribution request headers all behave exactly as they did in 1.0.x.
40+
41+
## 1.0.14 and earlier
42+
43+
See the Git history and GitHub releases.

CLAUDE.md

Lines changed: 25 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
44

55
## Project Overview
66

7-
WaveSpeed Python SDK - Official Python SDK for WaveSpeedAI inference platform. Provides a serverless worker implementation compatible with RunPod infrastructure.
7+
WaveSpeed Python SDK - Official Python SDK for the WaveSpeedAI inference platform. It is an API
8+
client only: it submits jobs to the hosted WaveSpeed API, polls for results, and uploads files.
9+
10+
> As of v2.0.0 the SDK no longer ships a serverless worker implementation. WaveSpeed does not offer
11+
> serverless as an external product, so that code was removed rather than left in the public SDK.
812
913
## Commands
1014

@@ -14,73 +18,40 @@ WaveSpeed Python SDK - Official Python SDK for WaveSpeedAI inference platform. P
1418
python -m pytest
1519

1620
# Run a single test file
17-
python -m pytest tests/test_serverless/test_modules/test_job.py
21+
python -m pytest tests/test_api.py
1822

1923
# Run a specific test
20-
python -m pytest tests/test_serverless/test_modules/test_job.py::TestRunJob::test_sync_handler_success -v
24+
python -m pytest tests/test_api.py::TestClient::test_run_success -v
2125
```
2226

23-
### Local Development
27+
### Linting
2428
```bash
25-
# Install in editable mode
26-
pip install -e .
27-
28-
# Run handler locally with test input
29-
python handler.py --test_input '{"input": {"message": "hello"}}'
30-
31-
# Run FastAPI development server
32-
python handler.py --waverless_serve_api --waverless_api_port 8000
29+
pre-commit run --all-files
3330
```
3431

35-
### Docker (test_worker image)
32+
### Local Development
3633
```bash
37-
# Build and test
38-
./images/test_worker/build_and_test.sh
34+
# Install in editable mode
35+
pip install -e .
3936
```
4037

4138
## Architecture
4239

43-
### Serverless Worker (`src/wavespeed/serverless/`)
44-
45-
Entry point: `serverless.start({"handler": handler})` in `__init__.py`
46-
47-
Three execution modes:
48-
1. **Local test mode** - `--test_input` flag or `test_input.json` file
49-
2. **API server mode** - `--waverless_serve_api` for FastAPI dev server
50-
3. **Worker mode** - Production mode polling for jobs
51-
52-
Key modules in `modules/`:
53-
- `job.py` - Job execution (`run_job`, `run_job_generator`, `handle_job`)
54-
- `scaler.py` - Concurrent job fetching and processing (`JobScaler`)
55-
- `handler.py` - Handler type detection (sync/async/generator)
56-
- `http.py` - HTTP communication (`fetch_jobs`, `send_result`, `stream_result`)
57-
- `fastapi.py` - Local development API server (`WorkerAPI`)
58-
- `local.py` - Local test execution
59-
- `state.py` - Job and worker state management
60-
- `validator.py` - Input validation (RunPod-compatible)
61-
62-
### Handler Types
63-
64-
Handlers can be sync/async functions or generators:
65-
```python
66-
def sync_handler(job): return {"output": result}
67-
async def async_handler(job): return {"output": result}
68-
def generator_handler(job): yield partial_result
69-
async def async_gen_handler(job): yield partial_result
70-
```
40+
### API client (`src/wavespeed/api/`)
7141

72-
### Validation (RunPod-compatible)
42+
- `client.py` - `Client`, the only transport. Synchronous, built on `requests`. Handles job
43+
submission, result polling, terminal-status handling, file upload, and the channel-attribution
44+
headers (`X-Client-Name`, etc.).
45+
- `__init__.py` - module-level convenience wrappers over a lazily created default `Client`:
46+
`run`, `run_no_throw`, `get_result`, `upload`.
7347

74-
```python
75-
from wavespeed.serverless.utils import validate
48+
`run` raises on failure; `run_no_throw` returns `{"status", "outputs", "task_id", "error"}` instead,
49+
mirroring the JavaScript SDK. `get_result` recovers a task whose local wait timed out.
7650

77-
schema = {
78-
"prompt": {"type": str, "required": True},
79-
"temperature": {"type": float, "required": False, "default": 0.7, "constraints": lambda x: 0 <= x <= 2},
80-
}
81-
result = validate(job_input, schema) # Returns {"validated_input": ...} or {"errors": [...]}
82-
```
51+
### Configuration (`src/wavespeed/config.py`)
8352

84-
### Environment Detection
53+
A single `api` config class, installed as a config module by `_config_module.py` (the PyTorch-style
54+
`install_config_module` shim). This gives `wavespeed.config.patch(...)` as a context manager /
55+
decorator for tests. `Client` reads its defaults from `wavespeed.config.api`.
8556

86-
Auto-detects RunPod (`RUNPOD_*` env vars) or native Waverless (`WAVERLESS_*` env vars) environments.
57+
`WAVESPEED_API_KEY` seeds `config.api.api_key` at import time.

README.md

Lines changed: 0 additions & 139 deletions
Original file line numberDiff line numberDiff line change
@@ -113,106 +113,8 @@ url = wavespeed.upload("/path/to/image.png")
113113
print(url)
114114
```
115115

116-
## Serverless Worker
117-
118-
Build serverless workers for the WaveSpeed platform.
119-
120-
### Basic Handler
121-
122-
```python
123-
import wavespeed.serverless as serverless
124-
125-
def handler(job):
126-
job_input = job["input"]
127-
result = job_input.get("prompt", "").upper()
128-
return {"output": result}
129-
130-
serverless.start({"handler": handler})
131-
```
132-
133-
### Async Handler
134-
135-
```python
136-
import wavespeed.serverless as serverless
137-
138-
async def handler(job):
139-
job_input = job["input"]
140-
result = await process_async(job_input)
141-
return {"output": result}
142-
143-
serverless.start({"handler": handler})
144-
```
145-
146-
### Generator Handler (Streaming)
147-
148-
```python
149-
import wavespeed.serverless as serverless
150-
151-
def handler(job):
152-
for i in range(10):
153-
yield {"progress": i, "partial": f"chunk-{i}"}
154-
155-
serverless.start({"handler": handler})
156-
```
157-
158-
### Input Validation
159-
160-
```python
161-
from wavespeed.serverless.utils import validate
162-
163-
INPUT_SCHEMA = {
164-
"prompt": {"type": str, "required": True},
165-
"max_tokens": {"type": int, "required": False, "default": 100},
166-
"temperature": {
167-
"type": float,
168-
"required": False,
169-
"default": 0.7,
170-
"constraints": lambda x: 0 <= x <= 2,
171-
},
172-
}
173-
174-
def handler(job):
175-
result = validate(job["input"], INPUT_SCHEMA)
176-
if "errors" in result:
177-
return {"error": result["errors"]}
178-
179-
validated = result["validated_input"]
180-
# process with validated input...
181-
return {"output": "done"}
182-
```
183-
184-
### Concurrent Execution
185-
186-
Enable concurrent job processing with `concurrency_modifier`:
187-
188-
```python
189-
import wavespeed.serverless as serverless
190-
191-
def handler(job):
192-
return {"output": job["input"]["data"]}
193-
194-
def concurrency_modifier(current_concurrency):
195-
return 2 # Process 2 jobs concurrently
196-
197-
serverless.start({
198-
"handler": handler,
199-
"concurrency_modifier": concurrency_modifier
200-
})
201-
```
202-
203116
## Local Development
204117

205-
### Test with JSON Input
206-
207-
```bash
208-
# Using CLI argument
209-
python handler.py --test_input '{"input": {"prompt": "hello"}}'
210-
211-
# Using test_input.json file (auto-detected)
212-
echo '{"input": {"prompt": "hello"}}' > test_input.json
213-
python handler.py
214-
```
215-
216118
### Running Tests
217119

218120
```bash
@@ -226,54 +128,13 @@ python -m pytest tests/test_api.py
226128
python -m pytest tests/test_api.py::TestClient::test_run_success -v
227129
```
228130

229-
### FastAPI Development Server
230-
231-
```bash
232-
python handler.py --waverless_serve_api --waverless_api_port 8000
233-
```
234-
235-
Then use the interactive Swagger UI at `http://localhost:8000/` or make requests:
236-
237-
```bash
238-
# Synchronous execution
239-
curl -X POST http://localhost:8000/runsync \
240-
-H "Content-Type: application/json" \
241-
-d '{"input": {"prompt": "hello"}}'
242-
243-
# Async execution
244-
curl -X POST http://localhost:8000/run \
245-
-H "Content-Type: application/json" \
246-
-d '{"input": {"prompt": "hello"}}'
247-
```
248-
249-
## CLI Options
250-
251-
| Option | Description |
252-
|--------|-------------|
253-
| `--test_input JSON` | Run locally with JSON test input |
254-
| `--waverless_serve_api` | Start FastAPI development server |
255-
| `--waverless_api_host HOST` | API server host (default: localhost) |
256-
| `--waverless_api_port PORT` | API server port (default: 8000) |
257-
| `--waverless_log_level LEVEL` | Log level (DEBUG, INFO, WARN, ERROR) |
258-
259131
## Environment Variables
260132

261-
### API Client
262-
263133
| Variable | Description |
264134
|----------|-------------|
265135
| `WAVESPEED_API_KEY` | WaveSpeed API key |
266136
| `WAVESPEED_CLIENT_NAME` | Channel-attribution name sent as the `X-Client-Name` header (overrides the `client_name` parameter; defaults to `wavespeed-python`) |
267137

268-
### Serverless Worker
269-
270-
| Variable | Description |
271-
|----------|-------------|
272-
| `WAVERLESS_POD_ID` | Worker/pod identifier |
273-
| `WAVERLESS_API_KEY` | API authentication key |
274-
| `WAVERLESS_WEBHOOK_GET_JOB` | Job fetch endpoint |
275-
| `WAVERLESS_WEBHOOK_POST_OUTPUT` | Result submission endpoint |
276-
277138
## License
278139

279140
MIT

0 commit comments

Comments
 (0)