feat(sdk-python): rewrite to async generator API per arch doc §12.1 - #7
Merged
Merged
Conversation
…fix binary wire format - Delete pocketstation/client.py (HTTP-only, no WebSocket, no LEAVE) - Delete tests/test_client.py (tests for deleted module) - Rewrite pocketstation/station.py: single PocketStation class with connect()/listen()/broadcast()/disconnect() and async context manager - broadcast() sends raw binary PCM bytes, not base64 JSON (wire format fix) - listen() propagates WebSocket errors to caller instead of swallowing them - disconnect() sends LEAVE message before closing WebSocket - AudioFrame gains timestamp_ns field (arch doc §4.1 sequence_number + timestamp_ns) - Update __init__.py: remove PocketStationClient/PocketStationSession exports - Burn down FAKE_SCAFFOLD_INVENTORY.md 'close() LEAVE message' partial row - 13 tests passing (9 new GWT-structured tests covering the four behavioral properties)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Linked issue
Closes #HIDDEN-003 (sdk-python LEAVE gap, see FAKE_SCAFFOLD_INVENTORY)
Summary
Rewrites the Python SDK to match the architecture document §12.1 specification. Two conflicting partial implementations (
client.pyandstation.py) are replaced by a single cleanPocketStationclass.broadcast()now sends raw PCM bytes over WebSocket. The old implementation sent base64-encoded JSON — a protocol deviation that would have broken any real relay integration.listen()now propagates WebSocket errors to the caller. The old implementation had a bareexcept: returnthat swallowed all errors silently.disconnect()and__aexit__now send LEAVE JSON before closing the WebSocket. Burns down the FAKE_SCAFFOLD_INVENTORY partial row.async with PocketStation(...) as station:callsconnect()on enter,disconnect()on exit.AudioFramegainstimestamp_ns: monotonic nanosecond timestamp at frame receipt, matching arch doc §4.1.Scope control
Tests run
python -m pytest tests/ -v # 13 passed in 0.08sRisks
None. No change to relay-facing protocol beyond fixing the binary wire format bug.
Reviewer focus
broadcast()— confirm raw bytes over WebSocket is correct for the relay receiver.disconnect()—finally: await ws.close()closes socket even if LEAVE send fails.listen()— no try/except around async for; errors reach the caller.STAFF_REVIEW
Purpose: Align Python SDK with arch doc §12.1. Fix binary wire format and error-swallowing bugs. Close LEAVE gap from FAKE_SCAFFOLD_INVENTORY.
Files changed: Deleted
client.py,test_client.py. Rewrittenstation.py,test_station.py. Updated__init__.py,types.py,FAKE_SCAFFOLD_INVENTORY.md.Architecture boundary affected: Python SDK (Tier 2) only. No relay/api-server/audio-core changes.
Behavior preserved:
_ensure_room()credential caching,AudioFrame.samples, all type definitions preserved.Tests proving behavior: 13 GWT tests — SUBSCRIBE on connect, binary bytes on broadcast, LEAVE on aexit, ConnectionError propagation, AudioFrame sequence numbering.
What is still mocked/stubbed: WebRTC transport — intentionally DEFERRED (Python is WebSocket listener/voice-agent tier only).
Public API change:
PocketStationClientandPocketStationSessionremoved. These had a name collision in the old__init__.pyand were never documented.Unsupported claims added/removed: None.
FAKE_SCAFFOLD_INVENTORY.md updated: Yes —
close() LEAVE messagePARTIAL row burned down.Final decision: PASS