# PyAI Python starter

Stream Speak and transcribe recordings with Hear through one reusable client.

## Requirements

Python 3.10+. A PyAI key. The starter writes speech.wav; add --transcribe call.wav to transcribe your own recording.

## Run

```sh
python3 -m venv .venv
. .venv/bin/activate
python -m pip install -r requirements.txt
cp .env.example .env
# Fill in .env, then export its values in this shell:
set -a
. ./.env
set +a
python main.py
```

The starter measures first received bytes, not speaker playback latency. Feed PCM chunks to your audio sink for live playback.

Select a voice from `GET https://api.pyai.com/v1/voices`. Use the current voice/language support table rather than assuming every voice supports every language. PCM, WAV and G.711 support streaming; MP3 and Opus are buffered.

Keep `.env` out of Git. These starters use server-side credentials.

[Full guide](https://docs.pyai.com/guides/sdks) · [Agent setup](https://pyai.com/build-with-ai) · [API contract](https://api.pyai.com/openapi.json)

## Download from your terminal

```sh
curl -fSL https://pyai.com/starters/pyai-python.tar.gz -o pyai-python.tar.gz
tar -xzf pyai-python.tar.gz
cd pyai-python
python3 -m venv .venv
. .venv/bin/activate
python -m pip install -r requirements.txt
cp .env.example .env
# Fill in .env, then export its values in this shell:
set -a
. ./.env
set +a
python main.py
```

## .env.example

```text
PYAI_API_KEY=replace_me
PYAI_VOICE=stock_emma_en_gb
```

## main.py

```python
"""Stream Speak to a WAV, then optionally transcribe a local recording."""
import argparse
from contextlib import closing
import os
from pathlib import Path
import time
import wave

from pyai import PyAI


def main():
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("--text", default="Hello! Your PyAI voice integration is ready.")
    parser.add_argument("--transcribe", type=Path)
    args = parser.parse_args()
    started = time.perf_counter()
    received = 0
    with PyAI(api_key=os.environ["PYAI_API_KEY"]) as client:
        # Reuse this client in your application; do not recreate it per chunk.
        with wave.open("speech.wav", "wb") as audio:
            audio.setparams((1, 2, 24000, 0, "NONE", "not compressed"))
            with closing(client.audio.speech_stream(
                input=args.text,
                voice=os.getenv("PYAI_VOICE", "stock_emma_en_gb"),
                response_format="pcm", sample_rate=24000,
            )) as chunks:
                for chunk in chunks:
                    if not received:
                        print(f"First audio bytes: {(time.perf_counter() - started) * 1000:.0f} ms")
                    # A live player can consume each chunk here instead.
                    audio.writeframesraw(chunk)
                    received += len(chunk)
        if not received:
            raise RuntimeError("Speak returned no audio")
        print(f"Saved speech.wav ({received} PCM bytes)")
        if args.transcribe:
            with args.transcribe.open("rb") as recording:
                result = client.audio.transcriptions.create(
                    file=recording, filename=args.transcribe.name,
                )  # Omit the language hint for automatic detection.
            print(result["text"])


if __name__ == "__main__":
    main()
```

## requirements.txt

```text
pyai-sdk==0.4.0
```
