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