Example: Using an access token instead of password

This example shows:

  1. How to initially retrieve access and refresh tokens.

  2. How to use them and store them if they change (are refreshed).

Example output
$ python3 -m examples.tokens_example
examples/tokens_example.py
 1import os, asyncio, json
 2from daisys import DaisysAPI
 3from daisys.v1.speak import VoiceGender, SimpleProsody, DaisysTakeGenerateError, HTTPStatusError
 4
 5# This example shows how to use access and refresh tokens instead of a username and email
 6# address for authenticating with the Daisys API.
 7
 8# Override DAISYS_EMAIL and DAISYS_PASSWORD with your details!
 9EMAIL = os.environ.get('DAISYS_EMAIL', 'user@example.com')
10PASSWORD = os.environ.get('DAISYS_PASSWORD', 'pw')
11
12def load_tokens():
13    """A function to access and refresh tokens from a local file.  In practice you might
14    store this somewhere more global like in a database, to re-use between sessions."""
15    try:
16        with open('daisys_tokens.json') as tokens_file:
17            tokens = json.load(tokens_file)
18            print('Loaded tokens from "daisys_tokens.json".')
19            return tokens['access_token'], tokens['refresh_token']
20    except (FileNotFoundError, json.JSONDecodeError):
21        return None, None
22
23ACCESS_TOKEN, REFRESH_TOKEN = load_tokens()
24
25def store_tokens(access_token: str, refresh_token: str):
26    """A function to store the access and refresh tokens to a local file.  In practice you
27    might store this somewhere like in a database or larger configuration.
28
29    """
30    with open('daisys_tokens.json', 'w') as tokens_file:
31        json.dump({'access_token': access_token,
32                   'refresh_token': refresh_token},
33                  tokens_file)
34        print('Stored new tokens in "daisys_tokens.json".')
35
36def initial_login():
37    """Initially retrieve access and refresh tokens through a normal login."""
38    # Initial login is only required if we don't have an access token yet.
39    print(f'Initial login, attempting to log in with {EMAIL} to retrieve an access token.')
40    with DaisysAPI('speak', email=EMAIL, password=PASSWORD) as speak:
41        # Say what should happen when tokens are retrieved or changed.
42        speak.token_callback = store_tokens
43
44        # Explicit login is only necessary if no other operations occur here, otherwise
45        # login is automatic.
46        speak.login()
47
48        # Login enables auto-logout.  Disable it so that the token will not be invalidated.
49        speak.auto_logout = False
50
51        print('Run again to use stored access token!')
52
53def subsequent_login():
54    """In subsequent uses, the previously stored access token can be used directly."""
55    print('Using previously stored access token.')
56    with DaisysAPI('speak', access_token=ACCESS_TOKEN, refresh_token=REFRESH_TOKEN) as speak:
57        speak.token_callback = store_tokens
58
59        # Here we are just showing how to authenticate with the Daisys API using an access
60        # token instead of the password, so we just list some voices.  See hello_daisys.py
61        # for an example of how to generate audio!
62
63        # Get a list of all voices
64        voices = speak.get_voices()
65        print('Found voices:', [voice.name for voice in voices])
66
67def main():
68    if ACCESS_TOKEN:
69        subsequent_login()
70    else:
71        initial_login()
72
73if __name__=='__main__':
74    try:
75        main()
76    except HTTPStatusError as e:
77        try:
78            print(f'HTTP error status {e.response.status_code}: {e.response.json()["detail"]}, {e.request.url}')
79        except:
80            print(f'HTTP error status {e.response.status_code}: {e.response.text}, {e.request.url}')