Example: Hello Daisys, synchronous client¶
This example shows:
How to create the synchronous client using a context manager.
Get a list of voices.
If there are none, how to generate a voice.
Reference the voice to generate audio (a “take”) for some text.
Download the resulting audio.
Example output¶
$ python3 -m examples.hello_daisys
Found Daisys Speak API version=1 minor=0
Found voices: []
Not enough voices!
Using model "shakespeare"
Generating a voice.
Sally speaking!
Read 198700 bytes of wav data, wrote "hello_daisys.wav".
Checking take: True
Checking list of takes: True
Deleting take t01hbbgw0zz4e9y6pb9qdxnrmag: True
Deleting voice v01hbbgtrvk50pxwyjvvsxygbza: True
examples/hello_daisys.py¶
1import os, asyncio, json
2from daisys import DaisysAPI
3from daisys.v1.speak import VoiceGender, SimpleProsody, DaisysTakeGenerateError, HTTPStatusError
4
5# Override DAISYS_EMAIL and DAISYS_PASSWORD with your details!
6EMAIL = os.environ.get('DAISYS_EMAIL', 'user@example.com')
7PASSWORD = os.environ.get('DAISYS_PASSWORD', 'pw')
8
9# Please see tokens_example.py for how to use an access token instead of a password.
10
11def load_tokens():
12 """A function to access and refresh tokens from a local file. In practice you might
13 store this somewhere more global like in a database, to re-use between sessions."""
14 try:
15 with open('daisys_tokens.json') as tokens_file:
16 tokens = json.load(tokens_file)
17 print('Loaded tokens from "daisys_tokens.json".')
18 return tokens['access_token'], tokens['refresh_token']
19 except (FileNotFoundError, json.JSONDecodeError):
20 return None, None
21
22ACCESS_TOKEN, REFRESH_TOKEN = load_tokens()
23
24def main():
25 with DaisysAPI('speak', email=EMAIL, password=PASSWORD) as speak:
26 print('Found Daisys Speak API', speak.version())
27
28 # The following is an example of how to use the Daisys API for generating a voice
29 # and then using it in a speech generation task. The API generates "takes"
30 # representing one or more sentences from a speaker. The same example is possible
31 # with the synchronous client, where the 'await' keywords should be removed.
32
33 # Get a list of all voices
34 voices = speak.get_voices()
35 print('Found voices:', [voice.name for voice in voices])
36
37 # Choose one
38 if len(voices) > 0:
39 voice = voices[-1]
40 delete_voice = False
41 else:
42 print('Not enough voices!')
43
44 # Okay, let's generate a voice.
45
46 # First we need to know the model.
47 models = speak.get_models()
48 if len(models) > 0:
49 model = models[0]
50 print(f'Using model "{model.displayname}"')
51 else:
52 print('No models found!')
53 return
54
55 print('Generating a voice.')
56 voice = speak.generate_voice(name='Lucy', gender=VoiceGender.FEMALE, model=model.name)
57 delete_voice = True
58
59 # Try to modify the voice's name
60 voice.name = 'Sally'
61 speak.update_voice(**dict(voice))
62 voice = speak.get_voice(voice.voice_id)
63
64 # Now we have a voice.
65 print(voice.name, 'speaking!')
66
67 try:
68 # Synthesize some audio from text
69 take = speak.generate_take(voice_id=voice.voice_id, text="Hello there, I am Daisys!",
70 prosody=SimpleProsody(pace=-3, pitch=2, expression=10))
71 except DaisysTakeGenerateError as e:
72 print('Error generating take:', str(e))
73 return
74
75 # The take is now READY. We get its associated audio file. We provide a filename
76 # so that it gets written to disk, but it is also returned.
77 audio_wav = speak.get_take_audio(take.take_id, file='hello_daisys.mp3', format='mp3')
78
79 print(f'Read {len(audio_wav)} bytes of wav data, wrote "hello_daisys.wav".')
80
81 # Let's check if we can get info on it again.
82 check_take = speak.get_take(take.take_id)
83 print('Checking take:', check_take == take)
84
85 # Let's check if we can find it in the most recent 5 takes.
86 last_5_takes = speak.get_takes(length=5)
87 print('Checking list of takes:', take.take_id in [t.take_id for t in last_5_takes])
88
89 # Delete the take
90 print(f'Deleting take {take.take_id}:', speak.delete_take(take.take_id))
91
92 # Delete the voice
93 if delete_voice:
94 print(f'Deleting voice {voice.voice_id}:', speak.delete_voice(voice.voice_id))
95
96if __name__=='__main__':
97 try:
98 main()
99 except HTTPStatusError as e:
100 try:
101 print(f'HTTP error status {e.response.status_code}: {e.response.json()["detail"]}, {e.request.url}')
102 except:
103 print(f'HTTP error status {e.response.status_code}: {e.response.text}, {e.request.url}')