Coverage for src/artemis_sg/app_creds.py: 71%
27 statements
« prev ^ index » next coverage.py v7.3.1, created at 2023-10-12 06:30 -0700
« prev ^ index » next coverage.py v7.3.1, created at 2023-10-12 06:30 -0700
1"""artemis_sg.app_creds
3Obtains Google API Application Credentials."""
5import os.path
7from google.auth.exceptions import RefreshError
8from google.auth.transport.requests import Request
9from google.oauth2.credentials import Credentials
10from google_auth_oauthlib.flow import InstalledAppFlow
12from artemis_sg.config import CFG
14app_token = CFG["google"]["docs"]["api_creds_token"]
15google_credentials = CFG["google"]["docs"]["api_creds_file"]
18def app_creds(app_token_filename: str = app_token) -> str:
19 """Obtain Google API application credentials.
21 Check given `app_token_filename` for valid credentials. If they don't
22 exist or are not valid, then use
23 `google_auth_oauthlib.flow.InstalledAppFlow` to let the user manually
24 approve the credential request. When successful, the credentials are saved
25 to the given `app_token_filename` and returned.
27 :param app_token_filename:
28 The filename used to inspect and save the credentials in (default is
29 app_creds_token.json). In practice this would not be set, but is given
30 here as a parameter for unittesting purposes.
31 :returns: a json string of the credentials
32 """
34 scopes = (
35 "https://www.googleapis.com/auth/spreadsheets.readonly",
36 "https://www.googleapis.com/auth/presentations",
37 )
38 creds = None
39 # The file `app_token_filename` stores the user's access and refresh tokens, and is
40 # created automatically when the authorization flow completes for the first
41 # time.
43 if os.path.exists(app_token_filename):
44 creds = Credentials.from_authorized_user_file(app_token_filename, scopes)
45 # If there are no (valid) credentials available, let the user log in.
46 if not creds or not creds.valid:
47 if creds and creds.expired and creds.refresh_token: 47 ↛ 48line 47 didn't jump to line 48, because the condition on line 47 was never true
48 try:
49 creds.refresh(Request())
50 except RefreshError:
51 flow = InstalledAppFlow.from_client_secrets_file(
52 google_credentials, scopes
53 )
54 creds = flow.run_local_server(port=0)
55 else:
56 flow = InstalledAppFlow.from_client_secrets_file(google_credentials, scopes)
57 creds = flow.run_local_server(port=0)
58 # Save the credentials for the next run
59 _write_token_file(app_token_filename, creds)
61 return creds
64def _write_token_file(filename: str, creds: str):
65 with open(filename, "w", encoding="utf-8") as token:
66 token.write(creds.to_json())