Example: Websocket example, synchronous client with iterator¶
This example shows:
How to open a websocket connection using a context manager.
Generate a take.
How to iterate over the resulting status and audio messages using
iter_request()
.How to make a request with and without chunks enabled. (Add argument
--chunks
.)
Example output¶
$ python3 -m examples.websocket_example_iter
Found Daisys Speak API version=1 minor=0
[0.002] Take status was changed to: WAITING.
[0.022] Take status was changed to: STARTED.
[0.748] New part being received.
[0.748] Received audio chunk of size 233472.
[1.204] Take status was changed to: PROGRESS_50.
[1.208] New part being received.
[1.208] Received audio chunk of size 116736.
[2.597] Take status was changed to: READY.
Deleting take t01jqrj9j7hyx49enqya9qeas3t: True
Example output (chunks enabled)¶
$ python3 -m examples.websocket_example_iter --chunks
Found Daisys Speak API version=1 minor=0
[0.002] Take status was changed to: WAITING.
[0.026] Take status was changed to: STARTED.
[0.314] New part being received.
[0.314] Received audio chunk of size 4096.
[0.328] Received audio chunk of size 4096.
[0.341] Received audio chunk of size 4096.
[0.351] Received audio chunk of size 4096.
[0.361] Received audio chunk of size 4096.
[0.371] Received audio chunk of size 4096.
[0.381] Received audio chunk of size 4096.
[0.391] Received audio chunk of size 4096.
[0.401] Received audio chunk of size 4096.
[0.411] Received audio chunk of size 4096.
[0.421] Received audio chunk of size 4096.
[0.431] Received audio chunk of size 4096.
[0.442] Received audio chunk of size 4096.
[0.452] Received audio chunk of size 4096.
[0.462] Received audio chunk of size 4096.
[0.472] Received audio chunk of size 4096.
[0.482] Received audio chunk of size 4096.
[0.492] Received audio chunk of size 4096.
[0.502] Received audio chunk of size 4096.
[0.512] Received audio chunk of size 4096.
[0.521] Received audio chunk of size 4096.
[0.532] Received audio chunk of size 4096.
[0.542] Received audio chunk of size 4096.
[0.551] Received audio chunk of size 4096.
[0.561] Received audio chunk of size 4096.
[0.572] Received audio chunk of size 4096.
[0.582] Received audio chunk of size 4096.
[0.592] Received audio chunk of size 4096.
[0.603] Received audio chunk of size 4096.
[0.613] Received audio chunk of size 1536.
[0.963] Take status was changed to: PROGRESS_50.
[0.966] New part being received.
[0.966] Received audio chunk of size 4096.
[0.976] Received audio chunk of size 4096.
[0.985] Received audio chunk of size 4096.
[0.994] Received audio chunk of size 4096.
[1.004] Received audio chunk of size 4096.
[1.014] Received audio chunk of size 4096.
[1.024] Received audio chunk of size 4096.
[1.034] Received audio chunk of size 4096.
[1.044] Received audio chunk of size 4096.
[1.055] Received audio chunk of size 4096.
[1.065] Received audio chunk of size 4096.
[1.075] Received audio chunk of size 4096.
[1.085] Received audio chunk of size 4096.
[1.095] Received audio chunk of size 3072.
[2.600] Take status was changed to: READY.
Deleting take t01jqrjxc257e1mr0r0z65ak4qb: True
examples/websocket_example_async_iter.py¶
1import sys, os, asyncio, time
2from typing import Optional
3from daisys import DaisysAPI
4from daisys.v1.speak import (DaisysWebsocketGenerateError, HTTPStatusError, Status, TakeResponse,
5 StreamOptions, StreamMode)
6
7# Override DAISYS_EMAIL and DAISYS_PASSWORD with your details!
8EMAIL = os.environ.get('DAISYS_EMAIL', 'user@example.com')
9PASSWORD = os.environ.get('DAISYS_PASSWORD', 'pw')
10
11# Please see tokens_example.py for how to use an access token instead of a password.
12
13async def main(chunks):
14 async with DaisysAPI('speak', email=EMAIL, password=PASSWORD) as speak:
15 print('Found Daisys Speak API', await speak.version())
16
17 # A buffer to receive parts; we initialize with a single empty bytes()
18 # because we will use it to accumulate chunks of the current wav file
19 # there. In total we will end with a list of wav files, one for each
20 # part. Parts are bits of speech, usually full sentences, that end with
21 # silence.
22 audio_wavs = [bytes()]
23
24 # Assume at least one voice is available
25 voice = (await speak.get_voices())[0]
26
27 async with speak.websocket(voice_id=voice.voice_id) as ws:
28 # Time the latency from when we submit the request until each part
29 # is received.
30 t0 = time.time()
31
32 # Submit a request to generate a take over the websocket connection.
33 generate_request_id = await ws.generate_take(
34 voice_id=voice.voice_id,
35 text='Hello from Daisys websockets! How may I help you?',
36
37 # Optional
38 stream_options=StreamOptions(mode=StreamMode.CHUNKS) if chunks else None,
39 )
40
41 # The use of an interator simplifies streaming, here we show how to
42 # get both status and audio chunks from the same iterator.
43 async for take_id, take, header, audio in ws.iter_request(generate_request_id):
44 now = time.time() - t0
45 if take is not None:
46 print(f'[{now:.03f}] Take status was changed to: {take.status.name}.')
47 if header is not None:
48 print(f'[{now:.03f}] New part being received.')
49 if audio is not None:
50 print(f'[{now:.03f}] Received audio chunk of size {len(audio)}.')
51
52 # Delete the take
53 if take_id:
54 print(f'Deleting take {take_id}:', await speak.delete_take(take_id))
55
56if __name__=='__main__':
57 try:
58 asyncio.run(main('--chunks' in sys.argv[1:]))
59 except HTTPStatusError as e:
60 try:
61 print(f'HTTP error status {e.response.status_code}: {e.response.json()["detail"]}, {e.request.url}')
62 except:
63 print(f'HTTP error status {e.response.status_code}: {e.response.text}, {e.request.url}')