|
5 | 5 | from dateutil import parser |
6 | 6 | from rauth import OAuth1Session |
7 | 7 |
|
8 | | -from microSALT import logger |
| 8 | +from microSALT import app, logger |
9 | 9 | from microSALT.utils.pubmlst.exceptions import ( |
10 | | - PUBMLSTError, |
| 10 | + PubMLSTError, |
11 | 11 | SessionTokenRequestError, |
12 | 12 | SessionTokenResponseError, |
13 | 13 | ) |
14 | 14 | from microSALT.utils.pubmlst.helpers import ( |
15 | | - BASE_API, |
16 | | - credentials_path_key, |
17 | 15 | folders_config, |
18 | 16 | get_path, |
| 17 | + get_service_config, |
19 | 18 | load_auth_credentials, |
20 | | - pubmlst_session_credentials_file_name, |
21 | 19 | save_session_token, |
22 | 20 | ) |
| 21 | +from microSALT.utils.pubmlst.constants import CREDENTIALS_KEY |
23 | 22 |
|
24 | 23 | session_token_validity = 12 # 12-hour validity |
25 | 24 | session_expiration_buffer = 60 # 60-second buffer |
26 | 25 |
|
27 | 26 |
|
28 | | -def get_new_session_token(db: str): |
29 | | - """Request a new session token using all credentials for a specific database.""" |
30 | | - logger.debug(f"Fetching a new session token for database '{db}'...") |
| 27 | +class ClientAuthentication: |
31 | 28 |
|
32 | | - try: |
33 | | - consumer_key, consumer_secret, access_token, access_secret = load_auth_credentials() |
| 29 | + def __init__(self, service: str): |
| 30 | + """Initialize the client with the specified service.""" |
| 31 | + self.service: str = service |
| 32 | + self.service_config: dict = get_service_config(service) |
| 33 | + self.base_api: str = self.service_config["base_api"] |
34 | 34 |
|
35 | | - url = f"{BASE_API}/db/{db}/oauth/get_session_token" |
| 35 | + def get_new_session_token(self, db: str): |
| 36 | + """Request a new session token using all credentials for a specific database.""" |
36 | 37 |
|
37 | | - session = OAuth1Session( |
38 | | - consumer_key=consumer_key, |
39 | | - consumer_secret=consumer_secret, |
40 | | - access_token=access_token, |
41 | | - access_token_secret=access_secret, |
42 | | - ) |
| 38 | + try: |
| 39 | + consumer_key, consumer_secret, access_token, access_secret = load_auth_credentials( |
| 40 | + self.service |
| 41 | + ) |
| 42 | + logger.debug(f"Consumer Key: {consumer_key}") |
| 43 | + logger.debug(f"Consumer Secret: {consumer_secret}") |
| 44 | + logger.debug(f"Access Token: {access_token}") |
| 45 | + logger.debug(f"Access Secret: {access_secret}") |
| 46 | + |
| 47 | + url = f"{self.base_api}/db/{db}/oauth/get_session_token" |
43 | 48 |
|
44 | | - response = session.get(url, headers={"User-Agent": "BIGSdb API downloader"}) |
45 | | - logger.debug(f"Response Status Code: {response.status_code}") |
| 49 | + logger.debug(f"Requesting session token from URL: {url}") |
46 | 50 |
|
47 | | - if response.ok: |
48 | | - try: |
49 | | - token_data = response.json() |
50 | | - session_token = token_data.get("oauth_token") |
51 | | - session_secret = token_data.get("oauth_token_secret") |
| 51 | + session = OAuth1Session( |
| 52 | + consumer_key=consumer_key, |
| 53 | + consumer_secret=consumer_secret, |
| 54 | + access_token=access_token, |
| 55 | + access_token_secret=access_secret, |
| 56 | + ) |
52 | 57 |
|
53 | | - if not session_token or not session_secret: |
54 | | - raise SessionTokenResponseError( |
55 | | - db, "Missing 'oauth_token' or 'oauth_token_secret' in response." |
| 58 | + response = session.get(url, headers={"User-Agent": "BIGSdb API downloader"}) |
| 59 | + logger.debug(f"Response Content: {response.content}") |
| 60 | + logger.debug(f"Response Status Code: {response.status_code}") |
| 61 | + |
| 62 | + if response.ok: |
| 63 | + try: |
| 64 | + token_data = response.json() |
| 65 | + session_token = token_data.get("oauth_token") |
| 66 | + session_secret = token_data.get("oauth_token_secret") |
| 67 | + |
| 68 | + if not session_token or not session_secret: |
| 69 | + raise SessionTokenResponseError( |
| 70 | + db, "Missing 'oauth_token' or 'oauth_token_secret' in response." |
| 71 | + ) |
| 72 | + |
| 73 | + expiration_time = datetime.now() + timedelta(hours=session_token_validity) |
| 74 | + |
| 75 | + save_session_token( |
| 76 | + service=self.service, |
| 77 | + db=db, |
| 78 | + token=session_token, |
| 79 | + secret=session_secret, |
| 80 | + expiration_date=expiration_time, |
56 | 81 | ) |
| 82 | + return session_token, session_secret |
| 83 | + |
| 84 | + except (ValueError, KeyError) as e: |
| 85 | + raise SessionTokenResponseError(db, f"Invalid response format: {str(e)}") |
| 86 | + else: |
| 87 | + raise SessionTokenRequestError(db, response.status_code, response.text) |
| 88 | + |
| 89 | + except PubMLSTError as e: |
| 90 | + logger.error(f"Error during token fetching: {e}") |
| 91 | + raise |
| 92 | + except Exception as e: |
| 93 | + logger.error(f"Unexpected error: {e}") |
| 94 | + raise PubMLSTError( |
| 95 | + f"Unexpected error while fetching session token for database '{db}': {e}" |
| 96 | + ) |
57 | 97 |
|
58 | | - expiration_time = datetime.now() + timedelta(hours=session_token_validity) |
| 98 | + def load_session_credentials( |
| 99 | + self, |
| 100 | + db: str, |
| 101 | + ): |
| 102 | + """Load session token from file for a specific database.""" |
| 103 | + try: |
| 104 | + credentials_file = os.path.join( |
| 105 | + get_path(folders_config, CREDENTIALS_KEY), |
| 106 | + self.service_config["session_credentials_file_name"], |
| 107 | + ) |
| 108 | + |
| 109 | + if not os.path.exists(credentials_file): |
| 110 | + logger.debug("Session file does not exist. Fetching a new session token.") |
| 111 | + return self.get_new_session_token(db) |
| 112 | + |
| 113 | + with open(credentials_file, "r") as f: |
| 114 | + try: |
| 115 | + all_sessions = json.load(f) |
| 116 | + except json.JSONDecodeError as e: |
| 117 | + raise SessionTokenResponseError(db, f"Failed to parse session file: {str(e)}") |
| 118 | + |
| 119 | + db_session_data = all_sessions.get("databases", {}).get(db) |
| 120 | + if not db_session_data: |
| 121 | + logger.debug( |
| 122 | + f"No session token found for database '{db}'. Fetching a new session token." |
| 123 | + ) |
| 124 | + return self.get_new_session_token(db) |
| 125 | + |
| 126 | + expiration = parser.parse(db_session_data.get("expiration", "")) |
| 127 | + if datetime.now() < expiration - timedelta(seconds=session_expiration_buffer): |
| 128 | + logger.debug(f"Using existing session token for database '{db}'.") |
| 129 | + session_token = db_session_data.get("token") |
| 130 | + session_secret = db_session_data.get("secret") |
59 | 131 |
|
60 | | - save_session_token(db, session_token, session_secret, expiration_time) |
61 | 132 | return session_token, session_secret |
62 | 133 |
|
63 | | - except (ValueError, KeyError) as e: |
64 | | - raise SessionTokenResponseError(db, f"Invalid response format: {str(e)}") |
65 | | - else: |
66 | | - raise SessionTokenRequestError(db, response.status_code, response.text) |
67 | | - |
68 | | - except PUBMLSTError as e: |
69 | | - logger.error(f"Error during token fetching: {e}") |
70 | | - raise |
71 | | - except Exception as e: |
72 | | - logger.error(f"Unexpected error: {e}") |
73 | | - raise PUBMLSTError( |
74 | | - f"Unexpected error while fetching session token for database '{db}': {e}" |
75 | | - ) |
76 | | - |
77 | | - |
78 | | -def load_session_credentials(db: str): |
79 | | - """Load session token from file for a specific database.""" |
80 | | - try: |
81 | | - credentials_file = os.path.join( |
82 | | - get_path(folders_config, credentials_path_key), pubmlst_session_credentials_file_name |
83 | | - ) |
84 | | - |
85 | | - if not os.path.exists(credentials_file): |
86 | | - logger.debug("Session file does not exist. Fetching a new session token.") |
87 | | - return get_new_session_token(db) |
88 | | - |
89 | | - with open(credentials_file, "r") as f: |
90 | | - try: |
91 | | - all_sessions = json.load(f) |
92 | | - except json.JSONDecodeError as e: |
93 | | - raise SessionTokenResponseError(db, f"Failed to parse session file: {str(e)}") |
94 | | - |
95 | | - db_session_data = all_sessions.get("databases", {}).get(db) |
96 | | - if not db_session_data: |
97 | 134 | logger.debug( |
98 | | - f"No session token found for database '{db}'. Fetching a new session token." |
| 135 | + f"Session token for database '{db}' has expired. Fetching a new session token." |
| 136 | + ) |
| 137 | + return self.get_new_session_token(db) |
| 138 | + |
| 139 | + except PubMLSTError as e: |
| 140 | + logger.error(f"PuBMLST-specific error occurred: {e}") |
| 141 | + raise |
| 142 | + except Exception as e: |
| 143 | + logger.error(f"Unexpected error: {e}") |
| 144 | + raise PubMLSTError( |
| 145 | + f"Unexpected error while loading session token for database '{db}': {e}" |
99 | 146 | ) |
100 | | - return get_new_session_token(db) |
101 | | - |
102 | | - expiration = parser.parse(db_session_data.get("expiration", "")) |
103 | | - if datetime.now() < expiration - timedelta(seconds=session_expiration_buffer): |
104 | | - logger.debug(f"Using existing session token for database '{db}'.") |
105 | | - session_token = db_session_data.get("token") |
106 | | - session_secret = db_session_data.get("secret") |
107 | | - |
108 | | - return session_token, session_secret |
109 | | - |
110 | | - logger.debug( |
111 | | - f"Session token for database '{db}' has expired. Fetching a new session token." |
112 | | - ) |
113 | | - return get_new_session_token(db) |
114 | | - |
115 | | - except PUBMLSTError as e: |
116 | | - logger.error(f"PUBMLST-specific error occurred: {e}") |
117 | | - raise |
118 | | - except Exception as e: |
119 | | - logger.error(f"Unexpected error: {e}") |
120 | | - raise PUBMLSTError(f"Unexpected error while loading session token for database '{db}': {e}") |
|
0 commit comments