Skip to main content

PocketStation for Python

PocketStation captures one desktop application and an optional microphone as separate live audio stems. A single native Session can send those stems to Python model code, a remote browser, and a multistem recording without mixing their source identities.

The Python package uses the PocketStation Rust engine for capture, routing, timing, recording, and Relay transport. Your Python code owns the model and application logic.

Capture a desktop application

Install PocketStation:

python -m pip install pocketstation

Capture one application without opening a microphone or writing files:

import pocketstation

with pocketstation.capture(application="Spotify") as live:
    for frame in live.audio:
        print(frame.source_id, frame.stem_id)

Add microphone=True when you need the default microphone as a second independent stem. Add record_to="recordings" when you want each selected stem recorded. Both behaviors are off by default.

Handle permissions and source changes

PocketStation does not prompt during import or discovery. Check microphone permission without prompting, then let Source opening report the authoritative result. Application capture and microphone capture use separate permissions.

When an application or device disappears, PocketStation reports the change and does not switch to another Source. Stop the current Session, discover again, confirm any changed selection, and create a new Session. Store a discovered identity only for its reported persistence scope. Keep fallback and provider retry policy explicit and finite.

See Prepare and qualify each Python platform for the permission states, persistence scopes, and recovery sequence.

Debug a voice interruption

examples/debug_voice_ai.py sends a physical microphone to OpenAI Realtime without another voice framework. PocketStation keeps microphone input, generated assistant audio, and the selected browser's output as independent recorded stems. Provider events and media events share one monotonic timeline, so you can see whether delay occurred before the model, inside the provider, in local output, or after Relay delivery.

See the voice-agent debugger instructions. Run repository examples from a source checkout or source archive. The installed pocketstation-demo command is the packaged application-and-microphone demo.

python -m pip install 'pocketstation[transcription]'
pocketstation-demo

Transcribe both sides of a voice application

Install the transcription extra, then run the example:

python -m pip install 'pocketstation[transcription]'
python examples/transcribe_voice_app.py

The program asks which desktop voice application to inspect. It declares one faster-whisper Operator, connects both stems to its audio input, and prints each transcript with its original source identity. It does not start Relay or write a recording.

The Session runs this path concurrently:

voice application ─┐
                   ├─ one bounded faster-whisper Operator ─ transcripts
physical microphone┘

The complete composition is visible in examples/transcribe_voice_app.py. The example adapter imports faster_whisper.WhisperModel when the Operator starts; the provider is not part of the pocketstation namespace.

This example does not debug turn handling, interruption, agent latency, or browser playout. PocketStation does not receive those events in this program.

Stream any application audio to a browser

Run the Relay example when you want another person to listen in a browser:

python examples/stream_any_app_audio.py

Choose any running application that is producing audio. The example publishes that application as one named AudioBus, waits for Relay readiness, and prints a single-use word code and browser URL. It does not open the microphone or record audio.

The example uses PocketStation's small, rate-limited demo service unless you set POCKETSTATION_CONTROL_URL and POCKETSTATION_RELAY_URL to services you operate. The shared URLs live in pocketstation_demo; application code does not contain service credentials.

Read application and microphone audio

Set the optional microphone and recording parameters when the workflow needs both sides:

import pocketstation

with pocketstation.capture(
    application="Zoom",
    microphone=True,
    record_to="recordings",
) as live:
    for frame in live.audio:
        print(frame.source_id, frame.stem_id)

The iterator reads a bounded native endpoint. A slow Python consumer produces observable pressure and discontinuities; it does not create an unbounded Python audio queue.

Send application-owned audio into a Session

Use audio_input() when your application already owns PCM, such as generated speech or audio received from a call provider:

session = pocketstation.Session(recording_root="recordings")
agent = session.audio_input("agent-output")
agent.output.record("agent")

with session.start():
    agent.write(samples)

The input uses finite preallocated Core buffers. Writes report full, closed, cancelled, and invalid-buffer outcomes explicitly.

Create an integration

PocketStation uses four open boundaries:

Boundary Use it when
Source Media or signals enter the Session.
Operator Work transforms media or emits typed signals.
Connector Media or signals leave for an external system.
Endpoint You need the lower-level outbound execution contract.

Pass one function when the destination is already open:

import pocketstation as pks
import pocketstation.aio as pks_aio

async def send_audio(frame: pks.AudioFrame) -> None:
    await socket.send(frame.samples)

destination = pks_aio.Connector(send=send_audio)
application.send_to(destination)

Subclass the synchronous or asyncio contract when the provider opens and closes resources. The provider class owns its connection; the Session owns bounded delivery, lineage, observations, drain, abort, and joined shutdown:

class WebSocketConnector(pks_aio.Connector):
    def __init__(self, url, token):
        self.url, self.token = url, token

    async def start(self):
        self.socket = await connect(self.url, token=self.token)

    async def send(self, frame: pks.AudioFrame):
        await self.socket.send(frame.samples)

    async def stop(self):
        await self.socket.close()

Attach one configured object to one or more stems:

destination = WebSocketConnector(url, token)
application.send_to(destination)
microphone.send_to(destination)

PocketStation calls start() once, interleaves both source-aware stems through send(), and calls stop() once. A second Connector object creates a separate destination. See Create an integration for deadlines, failures, and the advanced SPI.

Python provider callbacks execute on bounded off-realtime workers. They cannot be used as native capture callbacks. Compiled native extensions remain the path for native provider code, and process sidecars remain available when crash isolation is required.

Use Relay from Python

Python creates and deletes RelaySessions through the typed HTTP control client. The shared Rust pocketstation-relay connector publishes media. The Go Relay service forwards WebRTC audio. Python does not encode Opus, write RTP, or own a second media plane.

The control client uses finite request deadlines, bounded response bodies, redacted secrets, and matching synchronous and asyncio APIs.

Sync and asyncio

pocketstation and pocketstation.aio operate the same native Session. The asyncio namespace provides awaitable lifecycle, stream, Relay, provider, and audio-input operations without creating another audio queue.

Python callbacks still cross the interpreter boundary. Capture, routing, recording, and Relay transport remain native-speed; arbitrary Python model code does not have the same execution cost as Rust.

Platform support

Area Support
Python 3.11 and newer
macOS Apple silicon Installed wheel, application capture, physical microphone, 10 ms voice path, Relay, Chromium, and multistem recording tested
Linux Core application selection and 10 ms capture tested; installed Python distribution qualification in progress
Windows 11 ARM64 Core application selection and 10 ms capture tested in a VM; installed Python distribution and physical-device qualification in progress
WAN and TURN Not yet qualified

The native binding uses PocketStation Core 1.1.4 and the shared Relay Connector 0.1.2.

The Rust-to-Python audio read currently copies native samples into Python-owned bytes before exposing a memoryview. The view avoids another Python-side copy; the complete boundary is not zero-copy.

Develop the SDK

uv sync --extra transcription
uv run pytest -q
uv run ruff check python tests examples
uv run ruff format --check python tests examples
uv run mypy python tests/qualification/typing_contract.py examples

Reference

  • RELEASE_NOTES.md — user-visible changes and upgrade guidance.
  • docs/README.md — task guides, concepts, operations, and API ownership.
  • Write application-owned audio — bounded PCM input and selective output cancellation.
  • Record and observe a Session — multistem outcomes, route metrics, and lifecycle events.
  • Prepare each platform — permissions, source persistence, explicit rediscovery, and fallback policy.
  • examples/README.md — runnable examples and prerequisites.
  • pocketstation.capture — concise application and microphone capture.
  • pocketstation.session — Session declarations and lifecycle.
  • pocketstation.graph — stems, ports, routes, and signal contracts.
  • pocketstation.connector — outbound provider authoring.
  • pocketstation.operator_authoring — computation authoring.
  • pocketstation.source_authoring — inbound provider authoring.
  • pocketstation.aio — asyncio projection of the same engine.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pocketstation-0.1.2.tar.gz (237.2 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

pocketstation-0.1.2-cp311-abi3-win_arm64.whl (4.5 MB view details)

Uploaded CPython 3.11+Windows ARM64

pocketstation-0.1.2-cp311-abi3-win_amd64.whl (4.6 MB view details)

Uploaded CPython 3.11+Windows x86-64

pocketstation-0.1.2-cp311-abi3-manylinux_2_34_x86_64.whl (9.3 MB view details)

Uploaded CPython 3.11+manylinux: glibc 2.34+ x86-64

pocketstation-0.1.2-cp311-abi3-manylinux_2_34_aarch64.whl (9.0 MB view details)

Uploaded CPython 3.11+manylinux: glibc 2.34+ ARM64

pocketstation-0.1.2-cp311-abi3-macosx_11_0_arm64.whl (5.2 MB view details)

Uploaded CPython 3.11+macOS 11.0+ ARM64

pocketstation-0.1.2-cp311-abi3-macosx_10_12_x86_64.whl (5.4 MB view details)

Uploaded CPython 3.11+macOS 10.12+ x86-64

File details

Details for the file pocketstation-0.1.2.tar.gz.

File metadata

  • Download URL: pocketstation-0.1.2.tar.gz
  • Upload date:
  • Size: 237.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pocketstation-0.1.2.tar.gz
Algorithm Hash digest
SHA256 6438263e237750e901c425f78f61267a47bf16132f2f05c1bd468e2aa7ce539c
MD5 62dd57852f0aac45871e75d16e6607ff
BLAKE2b-256 a66bcda6bd027052daeee399e1b5553d8afb9a42c01d7d0f41bb5d27fa95a35b

See more details on using hashes here.

Provenance

The following attestation bundles were made for pocketstation-0.1.2.tar.gz:

Publisher: release.yml on pocketstation-io/sdk-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pocketstation-0.1.2-cp311-abi3-win_arm64.whl.

File metadata

File hashes

Hashes for pocketstation-0.1.2-cp311-abi3-win_arm64.whl
Algorithm Hash digest
SHA256 d0ede1711d09b3f218f0faaee2485ce670b0e71f1929cf8f15a1ea36d80f70bb
MD5 1493323ccaa28e14e97835a1d6f66227
BLAKE2b-256 b00b2245ce9651fb5ae1d0cdf957a45dd8de9ba501b2a584ebe7eca6b4f4efed

See more details on using hashes here.

Provenance

The following attestation bundles were made for pocketstation-0.1.2-cp311-abi3-win_arm64.whl:

Publisher: release.yml on pocketstation-io/sdk-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pocketstation-0.1.2-cp311-abi3-win_amd64.whl.

File metadata

File hashes

Hashes for pocketstation-0.1.2-cp311-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 8abe77398eb717684b004710f843aa0a4b374f1f12caca96f722cdb4397cdaa3
MD5 196bb03c4a8bd3f8ad36d3b45a910bca
BLAKE2b-256 fb01bd411abe0f48b42e98ef37cbe691711ab2577cf6a86e93839f42e62d514d

See more details on using hashes here.

Provenance

The following attestation bundles were made for pocketstation-0.1.2-cp311-abi3-win_amd64.whl:

Publisher: release.yml on pocketstation-io/sdk-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pocketstation-0.1.2-cp311-abi3-manylinux_2_34_x86_64.whl.

File metadata

File hashes

Hashes for pocketstation-0.1.2-cp311-abi3-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 d89c15608bd769bfc9fff8cf0d54f9250def4dced8d30cdcc8407436272b1e48
MD5 5f66be60cd245b95cd30d57532d8f763
BLAKE2b-256 7588d0309e659fc381b22e4d0c3e921965c0ca020e75fa5498b4befd4c0550d4

See more details on using hashes here.

Provenance

The following attestation bundles were made for pocketstation-0.1.2-cp311-abi3-manylinux_2_34_x86_64.whl:

Publisher: release.yml on pocketstation-io/sdk-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pocketstation-0.1.2-cp311-abi3-manylinux_2_34_aarch64.whl.

File metadata

File hashes

Hashes for pocketstation-0.1.2-cp311-abi3-manylinux_2_34_aarch64.whl
Algorithm Hash digest
SHA256 b43c4d13f819598b25a5b5f6ce2bdb9a7083c3cae4019e0932b95a2cd90e44bd
MD5 85d95789f7ed82849c78075040e06a9c
BLAKE2b-256 d63b8cecddf84d02fa9c62de4176898fed537d7928096b1d8a827f915573fb91

See more details on using hashes here.

Provenance

The following attestation bundles were made for pocketstation-0.1.2-cp311-abi3-manylinux_2_34_aarch64.whl:

Publisher: release.yml on pocketstation-io/sdk-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pocketstation-0.1.2-cp311-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for pocketstation-0.1.2-cp311-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 d9581c154d13c8f4f2c92f971abbb790a7551b39fd1e5c17ea1f15c6d38ded68
MD5 66b6dbbaf3260f4524850e35bc6efbce
BLAKE2b-256 cb4fdc5331d941339721c6831c73abbb5ab9ed37f19f62d7ac76931a803c09c4

See more details on using hashes here.

Provenance

The following attestation bundles were made for pocketstation-0.1.2-cp311-abi3-macosx_11_0_arm64.whl:

Publisher: release.yml on pocketstation-io/sdk-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pocketstation-0.1.2-cp311-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for pocketstation-0.1.2-cp311-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 b63e9f8aa1a06dc784667855f424a358501d0a11813b96b0fce61c2dc897bbe6
MD5 23a7686178adbc19b6c78db29c52cc7d
BLAKE2b-256 65334f1bae30945728e59656ccab8b0be6f6d0961d9602c5bd9d405040df885e

See more details on using hashes here.

Provenance

The following attestation bundles were made for pocketstation-0.1.2-cp311-abi3-macosx_10_12_x86_64.whl:

Publisher: release.yml on pocketstation-io/sdk-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.1.4

7 files

0.1.3

7 files

This release

0.1.2 This release

7 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page