

remove client.py
@90e4cb3b3202d478fa61185e80eb7673e6fa7eb4
--- speaches/client.py
... | ... | @@ -1,94 +0,0 @@ |
1 | -# TODO: move out of `speaches` package | |
2 | -import asyncio | |
3 | -import signal | |
4 | - | |
5 | -import httpx | |
6 | -from httpx_ws import AsyncWebSocketSession, WebSocketDisconnect, aconnect_ws | |
7 | -from wsproto.connection import ConnectionState | |
8 | - | |
9 | -CHUNK = 1024 * 4 | |
10 | -AUDIO_RECORD_CMD = "arecord -D default -f S16_LE -r 16000 -c 1 -t raw" | |
11 | -COPY_TO_CLIPBOARD_CMD = "wl-copy" | |
12 | -NOTIFY_CMD = "notify-desktop" | |
13 | - | |
14 | -client = httpx.AsyncClient(base_url="ws://localhost:8000") | |
15 | - | |
16 | - | |
17 | -async def audio_sender(ws: AsyncWebSocketSession) -> None: | |
18 | - process = await asyncio.create_subprocess_shell( | |
19 | - AUDIO_RECORD_CMD, | |
20 | - stdout=asyncio.subprocess.PIPE, | |
21 | - stderr=asyncio.subprocess.DEVNULL, | |
22 | - ) | |
23 | - assert process.stdout is not None | |
24 | - try: | |
25 | - while not process.stdout.at_eof(): | |
26 | - data = await process.stdout.read(CHUNK) | |
27 | - if ws.connection.state != ConnectionState.OPEN: | |
28 | - break | |
29 | - await ws.send_bytes(data) | |
30 | - except Exception as e: | |
31 | - print(e) | |
32 | - finally: | |
33 | - process.kill() | |
34 | - | |
35 | - | |
36 | -async def transcription_receiver(ws: AsyncWebSocketSession) -> None: | |
37 | - transcription = "" | |
38 | - notification_id: int | None = None | |
39 | - try: | |
40 | - while True: | |
41 | - data = await ws.receive_text() | |
42 | - if not data: | |
43 | - break | |
44 | - transcription += data | |
45 | - await copy_to_clipboard(transcription) | |
46 | - notification_id = await notify(transcription, replaces_id=notification_id) | |
47 | - except WebSocketDisconnect: | |
48 | - pass | |
49 | - print(transcription) | |
50 | - | |
51 | - | |
52 | -async def copy_to_clipboard(text: str) -> None: | |
53 | - process = await asyncio.create_subprocess_shell( | |
54 | - COPY_TO_CLIPBOARD_CMD, stdin=asyncio.subprocess.PIPE | |
55 | - ) | |
56 | - await process.communicate(input=text.encode("utf-8")) | |
57 | - await process.wait() | |
58 | - | |
59 | - | |
60 | -async def notify(text: str, replaces_id: int | None = None) -> int: | |
61 | - cmd = ["notify-desktop", "--app-name", "Speaches"] | |
62 | - if replaces_id is not None: | |
63 | - cmd.extend(["--replaces-id", str(replaces_id)]) | |
64 | - cmd.append("'Speaches'") | |
65 | - cmd.append(f"'{text}'") | |
66 | - process = await asyncio.create_subprocess_shell( | |
67 | - " ".join(cmd), | |
68 | - stdout=asyncio.subprocess.PIPE, | |
69 | - ) | |
70 | - await process.wait() | |
71 | - assert process.stdout is not None | |
72 | - notification_id = (await process.stdout.read()).decode("utf-8") | |
73 | - return int(notification_id) | |
74 | - | |
75 | - | |
76 | -async def main() -> None: | |
77 | - async with aconnect_ws("/v1/audio/transcriptions", client) as ws: | |
78 | - async with asyncio.TaskGroup() as tg: | |
79 | - sender_task = tg.create_task(audio_sender(ws)) | |
80 | - receiver_task = tg.create_task(transcription_receiver(ws)) | |
81 | - | |
82 | - async def on_interrupt(): | |
83 | - sender_task.cancel() | |
84 | - receiver_task.cancel() | |
85 | - await asyncio.gather(sender_task, receiver_task) | |
86 | - | |
87 | - asyncio.get_running_loop().add_signal_handler( | |
88 | - signal.SIGINT, | |
89 | - lambda: asyncio.create_task(on_interrupt()), | |
90 | - ) | |
91 | - | |
92 | - | |
93 | -asyncio.run(main()) | |
94 | -# poetry --directory /home/nixos/code/speaches run python /home/nixos/code/speaches/speaches/client.py |
Add a comment
Delete comment
Once you delete this comment, you won't be able to recover it. Are you sure you want to delete this comment?