Beispiel #1
0
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)
Beispiel #2
0
    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)
Beispiel #3
0
 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
Beispiel #5
0
    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
Beispiel #19
0
    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
Beispiel #22
0
    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)
Beispiel #27
0
    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)