Metadata-Version: 2.4
Name: wavespeed
Version: 0.1.0
Summary: WaveSpeedAI Python Client — Official Python SDK for WaveSpeedAI inference platform
Author-email: WaveSpeedAI <support@wavespeed.ai>
License: MIT
Project-URL: Homepage, https://github.com/WaveSpeedAI/wavespeed-python
Project-URL: Repository, https://github.com/WaveSpeedAI/wavespeed-python
Project-URL: Issues, https://github.com/WaveSpeedAI/wavespeed-python/issues
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: aiohttp[speedups]>=3.9.3
Requires-Dist: aiohttp-retry>=2.8.3
Requires-Dist: requests>=2.25.0
Requires-Dist: boto3>=1.26.165
Provides-Extra: test
Requires-Dist: pytest; extra == "test"
Dynamic: license-file

<div align="center">
  <a href="https://wavespeed.ai" target="_blank" rel="noopener noreferrer">
    <img src="https://raw.githubusercontent.com/WaveSpeedAI/waverless/main/docs/images/wavespeed-dark-logo.png" alt="WaveSpeedAI logo" width="200"/>
  </a>

  <h1>WaveSpeedAI Python SDK</h1>

  <p>
    <strong>Official Python SDK for the WaveSpeedAI inference platform</strong>
  </p>

  <p>
    <a href="https://wavespeed.ai" target="_blank" rel="noopener noreferrer">🌐 Visit wavespeed.ai</a> •
    <a href="https://wavespeed.ai/docs">📖 Documentation</a> •
    <a href="https://github.com/WaveSpeedAI/wavespeed-python/issues">💬 Issues</a>
  </p>
</div>

---

## Installation

```bash
pip install wavespeed
```

## API Client

Run WaveSpeed AI models with a simple API:

```python
import wavespeed

output = wavespeed.run(
    "wavespeed-ai/z-image/turbo",
    input={"prompt": "A cat holds a sign that says 'Hello World'"},
)

print(output["outputs"][0])  # Output URL
```

### Authentication

Set your API key via environment variable:

```bash
export WAVESPEED_API_KEY="your-api-key"
```

Or pass it directly:

```python
from wavespeed import Client

client = Client(api_key="your-api-key")
output = client.run("wavespeed-ai/z-image/turbo", input={"prompt": "A cat holds a sign that says 'Hello World'"})
```

### Options

```python
output = wavespeed.run(
    "wavespeed-ai/z-image/turbo",
    input={"prompt": "A cat holds a sign that says 'Hello World'"},
    timeout=36000.0     # Max wait time in seconds (default: 36000.0)
    poll_interval=1.0,  # Status check interval (default: 1.0)
)
```

### Upload Files

Upload images, videos, or audio files:

```python
import wavespeed

url = wavespeed.upload("/path/to/image.png")
print(url)
```

## Serverless Worker

Build serverless workers for the WaveSpeed platform.

### Basic Handler

```python
import wavespeed.serverless as serverless

def handler(job):
    job_input = job["input"]
    result = job_input.get("prompt", "").upper()
    return {"output": result}

serverless.start({"handler": handler})
```

### Async Handler

```python
import wavespeed.serverless as serverless

async def handler(job):
    job_input = job["input"]
    result = await process_async(job_input)
    return {"output": result}

serverless.start({"handler": handler})
```

### Generator Handler (Streaming)

```python
import wavespeed.serverless as serverless

def handler(job):
    for i in range(10):
        yield {"progress": i, "partial": f"chunk-{i}"}

serverless.start({"handler": handler})
```

### Input Validation

```python
from wavespeed.serverless.utils import validate

INPUT_SCHEMA = {
    "prompt": {"type": str, "required": True},
    "max_tokens": {"type": int, "required": False, "default": 100},
    "temperature": {
        "type": float,
        "required": False,
        "default": 0.7,
        "constraints": lambda x: 0 <= x <= 2,
    },
}

def handler(job):
    result = validate(job["input"], INPUT_SCHEMA)
    if "errors" in result:
        return {"error": result["errors"]}

    validated = result["validated_input"]
    # process with validated input...
    return {"output": "done"}
```

## Local Development

### Test with JSON Input

```bash
# Using CLI argument
python handler.py --test_input '{"input": {"prompt": "hello"}}'

# Using test_input.json file (auto-detected)
echo '{"input": {"prompt": "hello"}}' > test_input.json
python handler.py
```

### Running Tests

```bash
# Run all tests
python -m pytest

# Run a single test file
python -m pytest tests/test_api.py

# Run a specific test
python -m pytest tests/test_api.py::TestClient::test_run_success -v
```

### FastAPI Development Server

```bash
python handler.py --waverless_serve_api --waverless_api_port 8000
```

Then use the interactive Swagger UI at `http://localhost:8000/` or make requests:

```bash
# Synchronous execution
curl -X POST http://localhost:8000/runsync \
  -H "Content-Type: application/json" \
  -d '{"input": {"prompt": "hello"}}'

# Async execution
curl -X POST http://localhost:8000/run \
  -H "Content-Type: application/json" \
  -d '{"input": {"prompt": "hello"}}'
```

## CLI Options

| Option | Description |
|--------|-------------|
| `--test_input JSON` | Run locally with JSON test input |
| `--waverless_serve_api` | Start FastAPI development server |
| `--waverless_api_host HOST` | API server host (default: localhost) |
| `--waverless_api_port PORT` | API server port (default: 8000) |
| `--waverless_log_level LEVEL` | Log level (DEBUG, INFO, WARN, ERROR) |

## Environment Variables

### API Client

| Variable | Description |
|----------|-------------|
| `WAVESPEED_API_KEY` | WaveSpeed API key |

### Serverless Worker

| Variable | Description |
|----------|-------------|
| `WAVERLESS_POD_ID` | Worker/pod identifier |
| `WAVERLESS_API_KEY` | API authentication key |
| `WAVERLESS_WEBHOOK_GET_JOB` | Job fetch endpoint |
| `WAVERLESS_WEBHOOK_POST_OUTPUT` | Result submission endpoint |

## License

MIT
