@@ -187,6 +187,7 @@ def __init__(
187
187
self ,
188
188
port = 38745 ,
189
189
trade_url = "https://auth.naas.ai/bearer/workspace/longlived" ,
190
+ trade_jupyterhub_url = "https://auth.naas.ai/bearer/jupyterhub/longlived" ,
190
191
timeout = 60 , # 60,
191
192
login_url = os .environ .get ('NAAS_LOGIN_URL' , "https://naas.ai?cli_token=generate_token" ),
192
193
):
@@ -197,6 +198,7 @@ def __init__(
197
198
# TODO: Fix bug where the async call during dev mode, only finishes after the exact timeout period
198
199
self ._timeout = timeout
199
200
self .trade_url = trade_url
201
+ self .trade_jupyterhub_url = trade_jupyterhub_url
200
202
self ._login_url = login_url
201
203
self ._redirect_uri = None
202
204
@@ -336,6 +338,7 @@ def access_token(self):
336
338
def _gather_env_credentials (self ):
337
339
_SCHEMA_VARS = {
338
340
"NAAS_CREDENTIALS_JWT_TOKEN" : "jwt_token" ,
341
+ "JUPYTERHUB_API_TOKEN" : "jupyterhub_api_token"
339
342
}
340
343
341
344
credentials = {}
@@ -356,72 +359,63 @@ def _gather_file_credentials(self, credentials_file_path: Path):
356
359
self ._file_contents = json .loads (self ._file_contents )
357
360
return self ._file_contents
358
361
359
- def _generate_credential_file (self , credentials_file_path : Path ):
362
+ def _generate_credential_file (self , credentials_file_path : Path , jupyterhub_access_token = None , prompt = True ):
360
363
# Trade access token (and authenticate) and store the long-lived token in the credentials file
364
+ if jupyterhub_access_token is not None :
365
+ access_token = self .trade_for_long_lived_token (access_token = jupyterhub_access_token , access_token_type = "jupyterhub" )
366
+ self ._jwt_token = access_token
367
+ else :
368
+ access_token = self .trade_for_long_lived_token (self .access_token ())
369
+ self ._jwt_token = access_token
370
+
361
371
try :
362
- self ._jwt_token = self .trade_for_long_lived_token (self .access_token ())
363
-
364
372
# Create target directory in case it does not exists.
365
- os .makedirs (
366
- '/' .join (
367
- credentials_file_path .as_posix ().split ('/' )[:- 1 ]
368
- ),
369
- exist_ok = True
370
- )
373
+ os .makedirs (os .path .join (os .path .dirname (credentials_file_path )), exist_ok = True )
371
374
372
375
with open (credentials_file_path , "w" ) as file :
373
- file .write (json .dumps ({"jwt_token" : self . _jwt_token }))
376
+ file .write (json .dumps ({"jwt_token" : access_token }))
374
377
375
- print (f'\n \t ✅ CLI Token successfuly generated and stored to { credentials_file_path .as_posix ()} \n \n ' )
378
+ if prompt :
379
+ print (f'\n \t ✅ CLI Token successfuly generated and stored to { credentials_file_path .as_posix ()} \n \n ' )
376
380
377
- return self . _jwt_token
381
+ return access_token
378
382
except TimeoutException as e :
379
383
print (f'\n \n \t ❌ The process was not able to complete in time. Please try again.\n \n ' )
380
384
return None
381
385
382
-
383
-
384
386
def check_credentials (self ):
385
387
# This method is responsible for inspecting the naas credentials files
386
388
# locally and retrieving the jwt token if it exists and is valid.
387
- # The order of priority is as follows:
388
- # 1. Check if file exists, if not call appropriate method to start authentication process
389
- # 2.a Check if file is empty, if so call appropriate method to start authentication process
390
- # 2.b If file is not empty, check if token is valid, if not call appropriate method to start authentication process
391
- # 3. If file exists and is not empty and token is valid, set the jwt token to the class property and return
392
389
393
390
credentials_path = Path (os .path .expanduser ("~/.naas/credentials" ))
394
-
395
- if credentials_path .exists () and credentials_path .is_file ():
396
- # First order option for credential gathering is to check the file contents and grab the token
391
+ _var_credentials = self ._gather_env_credentials ()
392
+
393
+ # look for the existence of overriding environment variable to create the new file
394
+ if "jwt_token" in _var_credentials :
395
+ # Validate stored token is valid... then assign value and return
396
+ self ._jwt_token = _var_credentials ["jwt_token" ]
397
+ return self ._jwt_token
398
+
399
+ elif "jupyterhub_api_token" in _var_credentials :
400
+ access_token = _var_credentials ["jupyterhub_api_token" ]
401
+ self ._generate_credential_file (credentials_file_path = credentials_path , jupyterhub_access_token = access_token , prompt = False )
402
+
403
+ elif credentials_path .exists () and credentials_path .is_file ():
404
+ # Check the file contents and grab the token
397
405
credentials = self ._gather_file_credentials (credentials_path )
398
406
logging .debug (f"Credentials file found and not empty." )
399
- credentials .update (self ._gather_env_credentials ())
400
-
401
- # If environment variable is present, override file contents
402
- if "jwt_token" in credentials :
403
- # Validate stored token is valid... then assign value and return
404
- self ._jwt_token = credentials ["jwt_token" ]
405
- return self ._jwt_token
406
-
407
- else :
408
- # As a second order option, look for the existence of overriding environment variable to create the new file
409
- _var_credentials = self ._gather_env_credentials ()
410
-
411
- if "jwt_token" in _var_credentials :
412
- # Validate stored token is valid... then assign value and return
413
- self ._jwt_token = _var_credentials ["jwt_token" ]
414
- return self ._jwt_token
415
-
407
+ # credentials.update(self._gather_env_credentials())
408
+ self ._jwt_token = credentials ["jwt_token" ]
409
+
410
+ else :
416
411
# We could not find any credentials, so we need to start the authentication process
417
412
self ._generate_credential_file (credentials_file_path = credentials_path )
418
413
419
- # if not self._jwt_token:
420
- # raise Exception("Could not find any credentials to authenticate with.")
421
-
422
- def trade_for_long_lived_token (self , access_token ):
423
- # headers = {"Authorization": f"Bearer {access_token}"}
424
- url = f"{ self .trade_url } /?token={ access_token } "
414
+ def trade_for_long_lived_token (self , access_token , access_token_type = "workspace" ):
415
+ if access_token_type == "workspace" :
416
+ url = f"{ self .trade_url } /?token={ access_token } "
417
+ if access_token_type == "jupyterhub" :
418
+ url = f"{ self .trade_jupyterhub_url } /?token={ access_token } "
425
419
426
420
response = requests .get (url )
427
421
0 commit comments