def authenticate(username: str, password: str) -> FireflyResponse: """ Authenticates user and stores temporary token in `fireflyai.token`. Other modules automatically detect if a token exists and use it, unless a user specifically provides a token for a specific request. The token is valid for a 24-hour period, after which this method needs to be called again in order to generate a new token. Args: username (str): Username. password (str): Password. Returns: FireflyResponse: Empty FireflyResponse if successful, raises FireflyError otherwise. """ url = 'login' requestor = APIRequestor() response = requestor.post(url, body={ 'username': username, 'password': password, 'tnc': None }, api_key="") fireflyai.token = response['token'] return FireflyResponse(status_code=response.status_code, headers=response.headers)
def impersonate(cls, user_id: str = None, admin_token: str = None) -> FireflyResponse: """ impersonate user and stores temporary token in `fireflyai.token` Args: user_id (str): user ID. email (str): User email. admin_token (str): Admin user token. Returns: FireflyResponse: Empty FireflyResponse if successful, raises FireflyError otherwise. """ logging.info(' '.join(['impersonate to user_ID:', str(user_id)])) url = ''.join(['users/login_as/', str(user_id)]) requester = APIRequestor() try: response = requester.post(url, api_key=admin_token) fireflyai.token = response['result'] my_token = UserToken(fireflyai.token) logging.info(' '.join([ 'user ID:', str(user_id), '- Login successful with Account ID: ' + str(my_token.get_account_id()) ])) except Exception as ex: logging.warning(' '.join( ['user ID:', str(user_id), '- Login Failed'])) raise ex return FireflyResponse(status_code=response.status_code, headers=response.headers)
def get_perturbations_download_link(cls, pred_id: int, features: str = None, api_key: str = None) -> FireflyResponse: requester = APIRequestor() url = '/'.join([cls._CLASS_PREFIX, str(pred_id), 'perturbations_link']) data = { "features": features } response = requester.post(url=url, body=data, api_key=api_key) return response
def __do_operation(cls, task_id, op, api_key=None): if op not in ('resume', 'rerun', 'pause', 'cancel'): raise APIError("Operation {} is not supported".format(op)) requestor = APIRequestor() url = '{prefix}/{task_id}/{op}'.format(prefix=cls._CLASS_PREFIX, task_id=task_id, op=op) response = requestor.post(url=url, api_key=api_key) return response
def _list(cls, search_term: str = None, page: int = None, page_size: int = None, sort: Dict = None, filter_: Dict = None, api_key: str = None, url: str = None) -> FireflyResponse: requestor = APIRequestor() filters = requestor.parse_filter_parameters(filter_) sorts = requestor.parse_sort_parameters(sort) params = {'search_all_columns': search_term, 'page': page, 'page_size': page_size, 'sort': sorts, 'filter': filters } response = requestor.get(url=url if url else cls.class_url(), params=params, api_key=api_key) return response
def _get_available_configuration_options(cls, id: int, inter_level: InterpretabilityLevel = None, api_key: str = None) -> FireflyResponse: inter_level = inter_level.value if inter_level is not None else None requestor = APIRequestor() url = "tasks/configuration/options" response = requestor.get(url=url, params={'dataset_id': id, 'interpretable': inter_level}, api_key=api_key) new_data = { 'estimators': [Estimator(e) for e in response['estimators']], 'target_metric': [TargetMetric(e) for e in response['target_metric']], 'splitting_strategy': [SplittingStrategy(e) for e in response['splitting_strategy']], 'pipeline': [Pipeline(e) for e in response['pipeline']], } return FireflyResponse(data=new_data)
def get_top_insights(cls, pred_id: int, api_key: str = None) -> FireflyResponse: """ Gets the wisdoms list for the user with the demo wisdoms. Args: api_key (Optional[str]): Explicit `api_key`, not required, if `Whatify.login()` was run prior. Returns: FireflyResponse: Contains mapping of wisdoms for the user. """ requestor = APIRequestor() url = '/'.join([cls._CLASS_PREFIX, 'predictions/insights/top', str(pred_id)]) response = requestor.get(url, api_key=api_key) return response
def get_metadata(cls, id: int, api_key: str = None) -> FireflyResponse: """ Gets metadata for a specific Dataset. Args: id (int): Dataset ID. api_key (Optional[str]): Explicit `api_key`, not required, if `fireflyai.authenticate()` was run prior. Returns: FireflyResponse: Contains mapping of metadata. """ requestor = APIRequestor() url = '{prefix}/{id}/meta'.format(prefix=cls._CLASS_PREFIX, id=id) response = requestor.get(url, api_key=api_key) return response
def get_wisdom(cls, id: int, api_key: str = None) -> FireflyResponse: """ Gets the wisdom data for the user by its ID Args: id (int): wisdom (foresight) ID. api_key (Optional[str]): Explicit `api_key`, not required, if `Whatify.login()` was run prior. Returns: FireflyResponse: Contains wisdom data by ID for the user. """ requestor = APIRequestor() url = '{prefix}/{id}'.format(prefix=cls._CLASS_PREFIX, id=id) response = requestor.get(url, api_key=api_key) return response
def get_base_types(cls, id: int, api_key: str = None) -> FireflyResponse: """ Gets base types of features for a specific Datasource. Args: id (int): Datasource ID. api_key (Optional[str]): Explicit `api_key`, not required, if `fireflyai.authenticate()` was run prior. Returns: FireflyResponse: Contains mapping of feature names to base types. """ requestor = APIRequestor() url = '{prefix}/{id}/data_types/base'.format(prefix=cls._CLASS_PREFIX, id=id) response = requestor.get(url, api_key=api_key) return response
def get_task_result(cls, id: int, api_key: str = None) -> FireflyResponse: """ Gets full results of the Task. Args: id (int): Task ID. api_key (Optional[str]): Explicit api_key, not required if `fireflyai.authenticate` was run prior. Returns: FireflyResponse: Task's full results. """ requestor = APIRequestor() url = "{prefix}/{task_id}/results".format(prefix=cls._CLASS_PREFIX, task_id=id) response = requestor.get(url=url, api_key=api_key) return response
def refit(cls, id: int, datasource_id: int, wait: bool = False, api_key: str = None) -> FireflyResponse: """ Refits the chosen Ensemble of a Task on a specific Datasource. A refit trains the chosen Ensemble's models with the data of the given Datasource. The model training is done from scratch and uses all the given data. A new Ensemble is created that is made of all the refitted models of the chosen Ensemble and their original combination. Args: id (int): Task ID. datasource_id (int): Datasource ID. wait (Optional[bool]): Should the call be synchronous or not. api_key (Optional[str]): Explicit api_key, not required if `fireflyai.authenticate` was run prior. Returns: FireflyResponse: Ensemble ID, if successful and wait=False or Ensemble if successful and wait=True; raises FireflyError otherwise. """ data = { "datasource_id": datasource_id, } ensemble_id = cls.get(id=id, api_key=api_key).get('ensemble_id', None) if not ensemble_id: raise InvalidRequestError( message="No ensemble exists for this Task.") requestor = APIRequestor() url = "ensembles/{ensemble_id}/refit".format(ensemble_id=ensemble_id) response = requestor.post(url=url, body=data, api_key=api_key) new_ens_id = response.get('ensemble_id') if wait: utils.wait_for_finite_state(fireflyai.Ensemble.get, new_ens_id, api_key=api_key) response = fireflyai.Ensemble.get(new_ens_id, api_key=api_key) else: response = FireflyResponse(data={'id': new_ens_id}, headers=response.headers, status_code=response.status_code) return response
def get_ensemble_summary_report(cls, id: int, api_key: str = None) -> FireflyResponse: """ Gets summary report for Ensemble. Args: id (int): Ensemble ID. api_key (Optional[str]): Explicit api_key, not required if `fireflyai.authenticate` was run prior. Returns: FireflyResponse: Summary report. """ requestor = APIRequestor() url = "{prefix}/{id}/summary".format(prefix=cls._CLASS_PREFIX, id=id) response = requestor.get(url=url, api_key=api_key) return response
def update_wisdom(cls, id: int, data: str, api_key: str = None) -> FireflyResponse: """ update wisdom by given data :param id: :param data: :param api_key: :return: """ requestor = APIRequestor() url = '{prefix}/{id}'.format(prefix=cls._CLASS_PREFIX, id=id) response = requestor.patch(url=url, params=data, api_key=api_key) return response
def run_model_sensitivity(cls, ensemble_id: int, api_key: str = None) -> FireflyResponse: """ run the model sensitivity for Ensemble Args: id (int): ensemble ID. api_key (Optional[str]): Explicit `api_key`, not required, if `Whatify.login()` was run prior. Returns: FireflyResponse: Contains status of the trigger. """ requestor = APIRequestor() url = '{prefix}/{ensemble_id}/sensitivity'.format( prefix=cls._CLASS_PREFIX, ensemble_id=ensemble_id) response = requestor.post(url, api_key=api_key) return response
def get_type_warnings(cls, id: int, api_key: str = None) -> FireflyResponse: """ Gets type warning of features for a specific Datasource. Args: id (int): Datasource ID. api_key (Optional[str]): Explicit api_key, not required if `fireflyai.authenticate` was run prior. Returns: FireflyResponse: Contains mapping of feature names to a list of type warnings (can be empty). """ requestor = APIRequestor() url = '{prefix}/{id}/data_types/warning'.format( prefix=cls._CLASS_PREFIX, id=id) response = requestor.get(url, api_key=api_key) return response
def get_ensemble_confusion_matrix(cls, id: int, api_key: str = None) -> FireflyResponse: """ Gets confusion matrix for Ensemble. Args: id (int): Ensemble ID. api_key (Optional[str]): Explicit api_key, not required if `fireflyai.authenticate` was run prior. Returns: FireflyResponse: Confusion matrix. """ requestor = APIRequestor() url = "reports/{prefix}/{id}/confusion".format( prefix=cls._CLASS_PREFIX, id=id) response = requestor.get(url=url, api_key=api_key) return response
def get_model_presentation(cls, id: int, api_key: str = None) -> FireflyResponse: """ Gets presentation of the Ensemble. Args: id (int): Ensemble ID. api_key (Optional[str]): Explicit api_key, not required if `fireflyai.authenticate` was run prior. Returns: FireflyResponse: Ensemble's presentation. """ requestor = APIRequestor() url = "reports/{prefix}/{id}/presentation".format( prefix=cls._CLASS_PREFIX, id=id) response = requestor.get(url=url, api_key=api_key) return response
def get_credentials(cls, user_token: str = None, renew: bool = False): """ get user token and store it in `fireflyai.token` Args: user_token (str): user token renew (bool): if need to renew the token Returns: FireflyResponse: the user token """ if (cls.credentials is None) or renew: url = '/'.join([cls._CLASS_PREFIX, 'whatify_connect_permissions']) requester = APIRequestor() if user_token is None: user_token = fireflyai.token cls.credentials = requester.get(url, params={'jwt': user_token}) return cls.credentials
def remove_ensemble_in_production(cls, ensemble_id: int, api_key: str = None) -> FireflyResponse: """ remove in production Mark from Ensemble Args: id (int): ensemble ID. api_key (Optional[str]): Explicit `api_key`, not required, if `Whatify.login()` was run prior. Returns: FireflyResponse: Contains mapping of wisdoms for the user. """ requestor = APIRequestor() url = '{prefix}/write/{ensemble_id}/remove_from_production'.format( prefix=cls._CLASS_PREFIX, ensemble_id=ensemble_id) response = requestor.post(url, api_key=api_key) return response
def get_download_link(cls, pred_id: int, report_name: str, api_key: str = None) -> FireflyResponse: """ Gets download link by pred id and report name. Args: pred_id : the prediction ID report_name: the report name api_key (Optional[str]): Explicit `api_key`, not required, if `Whatify.login()` was run prior. Returns: str: Link to download prediction report, empty string if could not get the link """ requestor = APIRequestor() url = '/'.join([cls._CLASS_PREFIX, 'predictions/download', str(pred_id), str(report_name)]) response = '' try: response = requestor.get(url, api_key=api_key)['result'] except APIError as ex: print(' '.join(['got Error:', str(ex)])) return response
def login(cls, email: str, password: str) -> FireflyResponse: """ Authenticates user and stores temporary token in `fireflyai.token`. Other modules automatically detect if a token exists and use it, unless a user specifically provides a token for a specific request. The token is valid for a 24-hour period, after which this method needs to be called again in order to generate a new token. Args: email (str): email. password (str): Password. Returns: FireflyResponse: Empty FireflyResponse if successful, raises FireflyError otherwise. """ logging.info(' '.join(['login with user:'******'login' requestor = APIRequestor() try: response = requestor.post(url, body={ 'username': email, 'password': password, 'tnc': None }, api_key="") fireflyai.token = response['token'] my_token = UserToken(fireflyai.token) logging.info(' '.join([ 'user mail:', str(email), '- Login successful, User ID: ', str(my_token.get_user_id()), ' Account ID: ' + str(my_token.get_account_id()) ])) except Exception as ex: logging.warning(' '.join( ['user mail:', str(email), '- Login FAILED'])) raise ex return FireflyResponse(status_code=response.status_code, headers=response.headers)
def get_task_progress(cls, id: int, api_key: str = None) -> FireflyResponse: """ Lists existing Ensembles` scores. Get the Ensembles' scores produced thus far by the task. Enables you to track the progress of the task. Args: id (int): Task ID. api_key (Optional[str]): Explicit api_key, not required if `fireflyai.authenticate` was run prior. Returns: FireflyResponse: List of all the Task's Ensembles' scores. """ requestor = APIRequestor() url = "{prefix}/{task_id}/progress".format(prefix=cls._CLASS_PREFIX, task_id=id) response = requestor.get(url=url, api_key=api_key) return response
def get_suggest_wisdom_list(cls, search_term: str = None, api_key: str = None) -> FireflyResponse: """ Gets the suggest wisdoms list for the user can filter with search_term. Args: api_key (Optional[str]): Explicit `api_key`, not required, if `Whatify.login()` was run prior. search_term (Optional[str]): the search term you want to filter :return: FireflyResponse: Contains mapping of suggest wisdoms for the user. """ requestor = APIRequestor() url = 'suggestions' response = requestor.get(url, api_key=api_key)['result'] if search_term: response = [ d for d in response if str(d['name']).find(search_term) != -1 ] return response
def get_report(cls, report_type: str, entity_id: int, api_key: str = None) -> FireflyResponse: """ Gets the Report by Type and entity ID. Args: report_type: the report type entity_id: the entity_id to get report for api_key (Optional[str]): Explicit `api_key`, not required, if `Whatify.login()` was run prior. Returns: FireflyResponse: Contains mapping of the report for entity ID. """ params = { 'report_type': report_type, 'entity_id': entity_id } requestor = APIRequestor() url = '/'.join([cls._CLASS_PREFIX]) response = requestor.get(url, params=params, api_key=api_key) return response
def get_feature_importance_report(cls, id: int, api_key: str = None) -> FireflyResponse: """ Gets feature importance report for Ensemble. Args: id (int): Ensemble ID. api_key (Optional[str]): Explicit api_key, not required if `fireflyai.authenticate` was run prior. Returns: FireflyResponse: Contains mapping of feature importance for the ensemble_id. """ requestor = APIRequestor() url = "reports/{prefix}/{id}/feature_importance".format( prefix=cls._CLASS_PREFIX, id=id) response = requestor.get(url=url, api_key=api_key) result = response.to_dict() cls.__cleanup_report(result) return FireflyResponse(data=result)
def create(cls, ensemble_id: int, data_id: int = None, file_path: str = None, download_details: Dict = None, remove_header: bool = False, data_name: str = None, header: List = None, wait: bool = None, api_key: str = None) -> FireflyResponse: """ Create a prediction from a given ensemble and prediction datasource. The prediction datasource should include all the of original features, without the target column (unless the ensemble belongs to a timeseries task). The prediction uses the ensemble to produce the prediction's results file. Args: ensemble_id (int): Ensemble to use for the prediction. data_id (int): Datasource to run the prediction on. wait (Optional[bool]): Should the call be synchronous or not. api_key (Optional[str]): Explicit api_key, not required if `fireflyai.authenticate` was run prior. Returns: FireflyResponse: Prediction ID, if successful and wait=False or Prediction if successful and wait=True; raises FireflyError otherwise. """ data_name = data_name or os.path.basename(file_path) if file_path else None data = { "ensemble_id": ensemble_id, "datasource_id": data_id, "header": header, "data_name": data_name, "file_path": file_path, "remove_header": remove_header, } if download_details: data['download_details'] = download_details requestor = APIRequestor() response = requestor.post(url=cls._CLASS_PREFIX, body=data, api_key=api_key) id = response['id'] if wait: utils.wait_for_finite_state(cls.get, id, state_field='stage', api_key=api_key) response = cls.get(id, api_key=api_key) else: response = FireflyResponse(data={'id': id}) return response
def edit_notes(cls, id: int, notes: str, api_key: str = None) -> FireflyResponse: """ Edits notes of the Ensemble. Args: id (int): Ensemble ID. notes (str): New notes value. api_key (Optional[str]): Explicit api_key, not required if `fireflyai.authenticate` was run prior. Returns: FireflyResponse: "submitted" if operation was successful, raises FireflyClientError otherwise. """ requestor = APIRequestor() url = "{prefix}/{id}/notes".format(prefix=cls._CLASS_PREFIX, id=id) response = requestor.put(url=url, body={'notes': notes}, api_key=api_key) return response
def _create(cls, datasource_name, na_values: List[str] = None, wait: bool = False, api_key: str = None): data = { "name": datasource_name, "filename": datasource_name, "analyze": True, "na_values": na_values } requestor = APIRequestor() response = requestor.post(url=cls._CLASS_PREFIX, body=data, api_key=api_key) if wait: id = response['id'] utils.wait_for_finite_state(cls.get, id, api_key=api_key) response = cls.get(id, api_key=api_key) return response
def get_model_sensitivity_report(cls, id: int, api_key: str = None) -> FireflyResponse: """ Gets sensitivity report for Ensemble. Contains each feature's sensitivity score for missing values and feature values. Args: id (int): Ensemble ID. api_key (Optional[str]): Explicit api_key, not required if `fireflyai.authenticate` was run prior. Returns: FireflyResponse: Score for each feature in every sensitivity test. """ requestor = APIRequestor() url = "reports/{prefix}/{id}/sensitivity".format( prefix=cls._CLASS_PREFIX, id=id) response = requestor.get(url=url, api_key=api_key) result = response.to_dict() cls.__cleanup_report(result) return FireflyResponse(data=result)