|  |  | 
					
						
						|  |  | 
					
						
						|  | import requests | 
					
						
						|  |  | 
					
						
						|  | from ultralytics.hub.utils import HUB_API_ROOT, PREFIX, request_with_credentials | 
					
						
						|  | from ultralytics.yolo.utils import LOGGER, SETTINGS, emojis, is_colab, set_settings | 
					
						
						|  |  | 
					
						
						|  | API_KEY_URL = 'https://hub.ultralytics.com/settings?tab=api+keys' | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | class Auth: | 
					
						
						|  | id_token = api_key = model_key = False | 
					
						
						|  |  | 
					
						
						|  | def __init__(self, api_key='', verbose=False): | 
					
						
						|  | """ | 
					
						
						|  | Initialize the Auth class with an optional API key. | 
					
						
						|  |  | 
					
						
						|  | Args: | 
					
						
						|  | api_key (str, optional): May be an API key or a combination API key and model ID, i.e. key_id | 
					
						
						|  | """ | 
					
						
						|  |  | 
					
						
						|  | api_key = api_key.split('_')[0] | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | self.api_key = api_key or SETTINGS.get('api_key', '') | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | if self.api_key: | 
					
						
						|  |  | 
					
						
						|  | if self.api_key == SETTINGS.get('api_key'): | 
					
						
						|  |  | 
					
						
						|  | if verbose: | 
					
						
						|  | LOGGER.info(f'{PREFIX}Authenticated โ
') | 
					
						
						|  | return | 
					
						
						|  | else: | 
					
						
						|  |  | 
					
						
						|  | success = self.authenticate() | 
					
						
						|  |  | 
					
						
						|  | elif is_colab(): | 
					
						
						|  |  | 
					
						
						|  | success = self.auth_with_cookies() | 
					
						
						|  | else: | 
					
						
						|  |  | 
					
						
						|  | success = self.request_api_key() | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | if success: | 
					
						
						|  | set_settings({'api_key': self.api_key}) | 
					
						
						|  |  | 
					
						
						|  | if verbose: | 
					
						
						|  | LOGGER.info(f'{PREFIX}New authentication successful โ
') | 
					
						
						|  | elif verbose: | 
					
						
						|  | LOGGER.info(f'{PREFIX}Retrieve API key from {API_KEY_URL}') | 
					
						
						|  |  | 
					
						
						|  | def request_api_key(self, max_attempts=3): | 
					
						
						|  | """ | 
					
						
						|  | Prompt the user to input their API key. Returns the model ID. | 
					
						
						|  | """ | 
					
						
						|  | import getpass | 
					
						
						|  | for attempts in range(max_attempts): | 
					
						
						|  | LOGGER.info(f'{PREFIX}Login. Attempt {attempts + 1} of {max_attempts}') | 
					
						
						|  | input_key = getpass.getpass(f'Enter API key from {API_KEY_URL} ') | 
					
						
						|  | self.api_key = input_key.split('_')[0] | 
					
						
						|  | if self.authenticate(): | 
					
						
						|  | return True | 
					
						
						|  | raise ConnectionError(emojis(f'{PREFIX}Failed to authenticate โ')) | 
					
						
						|  |  | 
					
						
						|  | def authenticate(self) -> bool: | 
					
						
						|  | """ | 
					
						
						|  | Attempt to authenticate with the server using either id_token or API key. | 
					
						
						|  |  | 
					
						
						|  | Returns: | 
					
						
						|  | bool: True if authentication is successful, False otherwise. | 
					
						
						|  | """ | 
					
						
						|  | try: | 
					
						
						|  | header = self.get_auth_header() | 
					
						
						|  | if header: | 
					
						
						|  | r = requests.post(f'{HUB_API_ROOT}/v1/auth', headers=header) | 
					
						
						|  | if not r.json().get('success', False): | 
					
						
						|  | raise ConnectionError('Unable to authenticate.') | 
					
						
						|  | return True | 
					
						
						|  | raise ConnectionError('User has not authenticated locally.') | 
					
						
						|  | except ConnectionError: | 
					
						
						|  | self.id_token = self.api_key = False | 
					
						
						|  | LOGGER.warning(f'{PREFIX}Invalid API key โ ๏ธ') | 
					
						
						|  | return False | 
					
						
						|  |  | 
					
						
						|  | def auth_with_cookies(self) -> bool: | 
					
						
						|  | """ | 
					
						
						|  | Attempt to fetch authentication via cookies and set id_token. | 
					
						
						|  | User must be logged in to HUB and running in a supported browser. | 
					
						
						|  |  | 
					
						
						|  | Returns: | 
					
						
						|  | bool: True if authentication is successful, False otherwise. | 
					
						
						|  | """ | 
					
						
						|  | if not is_colab(): | 
					
						
						|  | return False | 
					
						
						|  | try: | 
					
						
						|  | authn = request_with_credentials(f'{HUB_API_ROOT}/v1/auth/auto') | 
					
						
						|  | if authn.get('success', False): | 
					
						
						|  | self.id_token = authn.get('data', {}).get('idToken', None) | 
					
						
						|  | self.authenticate() | 
					
						
						|  | return True | 
					
						
						|  | raise ConnectionError('Unable to fetch browser authentication details.') | 
					
						
						|  | except ConnectionError: | 
					
						
						|  | self.id_token = False | 
					
						
						|  | return False | 
					
						
						|  |  | 
					
						
						|  | def get_auth_header(self): | 
					
						
						|  | """ | 
					
						
						|  | Get the authentication header for making API requests. | 
					
						
						|  |  | 
					
						
						|  | Returns: | 
					
						
						|  | (dict): The authentication header if id_token or API key is set, None otherwise. | 
					
						
						|  | """ | 
					
						
						|  | if self.id_token: | 
					
						
						|  | return {'authorization': f'Bearer {self.id_token}'} | 
					
						
						|  | elif self.api_key: | 
					
						
						|  | return {'x-api-key': self.api_key} | 
					
						
						|  | else: | 
					
						
						|  | return None | 
					
						
						|  |  | 
					
						
						|  | def get_state(self) -> bool: | 
					
						
						|  | """ | 
					
						
						|  | Get the authentication state. | 
					
						
						|  |  | 
					
						
						|  | Returns: | 
					
						
						|  | bool: True if either id_token or API key is set, False otherwise. | 
					
						
						|  | """ | 
					
						
						|  | return self.id_token or self.api_key | 
					
						
						|  |  | 
					
						
						|  | def set_api_key(self, key: str): | 
					
						
						|  | """ | 
					
						
						|  | Set the API key for authentication. | 
					
						
						|  |  | 
					
						
						|  | Args: | 
					
						
						|  | key (str): The API key string. | 
					
						
						|  | """ | 
					
						
						|  | self.api_key = key | 
					
						
						|  |  |