示例#1
0
def delete_database(client: AitoClient):
    """`delete the whole database <https://aito.ai/docs/api/#delete-api-v1-schema>`__

    .. note::

        requires the client to be setup with the READ-WRITE API key

    :param client: the AitoClient instance
    :type client: AitoClient
    """
    client.request(request_obj=aito_requests.DeleteDatabaseSchemaRequest())
    LOG.info('database deleted')
示例#2
0
def create_database(client: AitoClient, schema: Union[AitoDatabaseSchema, Dict]):
    """`create a database <https://aito.ai/docs/api/#put-api-v1-schema>`__ using the specified database schema

    .. note::

        requires the client to be setup with the READ-WRITE API key

    :param client: the AitoClient instance
    :type client: AitoClient
    :param schema: the schema of the database
    :type schema: Dict
    """
    client.request(request_obj=aito_requests.CreateDatabaseSchemaRequest(schema=schema))
    LOG.info('database schema created')
示例#3
0
def delete_table(client: AitoClient, table_name: str):
    """`delete the specified table <https://aito.ai/docs/api/#delete-api-v1-schema>`__

    .. note::

        requires the client to be setup with the READ-WRITE API key

    :param client: the AitoClient instance
    :type client: AitoClient
    :param table_name: the name of the table
    :type table_name: str
    """
    client.request(request_obj=aito_requests.DeleteTableSchemaRequest(table_name=table_name))
    LOG.info(f'table `{table_name}` deleted')
示例#4
0
def trigger_file_processing(client: AitoClient, table_name: str, session_id: str):
    """`Trigger file processing of uploading a file to a table
    <https://aito.ai/docs/api/#post-api-v1-data-table-file-uuid>`__

    :param client: the AitoClient instance
    :type client: AitoClient
    :param table_name: the name of the table to be uploaded
    :type table_name: str
    :param session_id: The upload session id from :func:`.initiate_upload_file`
    :type session_id: str
    """
    LOG.debug('triggering file processing...')
    client.request(request_obj=aito_requests.TriggerFileProcessingRequest(table_name=table_name, session_id=session_id))
    LOG.info('triggered file processing')
示例#5
0
def create_client_from_parsed_args(parsed_args, check_credentials=True) -> AitoClient:
    """create client from parsed args with the default aito credentials arguments from
    add_aito_default_credentials_arguments

    """
    def check_flag_env_var_default_credential(flag_name, env_var_name, credential_key):
        if parsed_args[flag_name] != '.env':
            return parsed_args[flag_name]
        if parse_env_variable(env_var_name):
            return parse_env_variable(env_var_name)
        LOG.debug(f"{env_var_name} environment variable not found. Checking credentials file")
        config = get_credentials_file_config()
        profile = parsed_args['profile']
        if not config.has_section(profile):
            raise ParseError(f"profile `{profile}` not found. "
                             f"Please edit the credentials file or run `aito configure`")
        if credential_key not in config[profile]:
            raise ParseError(f"{credential_key} not found in profile `{profile}`."
                             f"Please edit the credentials file or run `aito configure`")
        return config[profile][credential_key]

    instance_url = check_flag_env_var_default_credential('instance_url', 'AITO_INSTANCE_URL', 'instance_url')
    api_key = check_flag_env_var_default_credential('api_key', 'AITO_API_KEY', 'api_key')

    client_args = {
        'instance_url': instance_url,
        'api_key': api_key,
        'check_credentials': check_credentials
    }
    return AitoClient(**client_args)
示例#6
0
def delete_column(client: AitoClient, table_name: str, column_name: str):
    """`delete a column of a table <https://aito.ai/docs/api/#delete-api-v1-schema-column>`__

    .. note::

        requires the client to be setup with the READ-WRITE API key

    :param client: the AitoClient instance
    :type client: AitoClient
    :param table_name: the name of the table containing the column
    :type table_name: str
    :param column_name: the name of the column
    :type column_name: str
    """
    client.request(request_obj=aito_requests.DeleteColumnSchemaRequest(table_name=table_name, column_name=column_name))
    LOG.info(f'column `{table_name}.{column_name}` deleted')
    def parse_and_execute(self, parsed_args: Dict):
        profile = parsed_args['profile']
        existing_instance_url, existing_api_key = get_existing_credentials(
            profile_name=profile)
        if existing_instance_url is not None or existing_api_key is not None:
            if not prompt_confirmation(
                    f'Profile {profile} already exists. Do you want to replace?'
            ):
                return 0

        input_ret_val = input(
            'instance url (i.e: https://instance_name.aito.app): '
            if not existing_instance_url else
            f'instance url [{mask_instance_url(existing_instance_url)}]')
        new_instance_url = input_ret_val if input_ret_val else existing_instance_url
        if not new_instance_url:
            raise ParseError('instance url must not be empty')

        input_ret_val = input(
            'api key [None]' if not existing_instance_url else
            f'api key [{mask_api_key(existing_api_key)}]')
        new_api_key = input_ret_val if input_ret_val else existing_api_key
        if not new_api_key:
            raise ParseError('api_key must not be empty')

        try:
            AitoClient(instance_url=new_instance_url,
                       api_key=new_api_key,
                       check_credentials=True)
        except Error:
            raise ParseError('invalid credentials, please try again')

        write_credentials_file_profile(parsed_args['profile'],
                                       new_instance_url, new_api_key)
示例#8
0
def poll_file_processing_status(client: AitoClient, table_name: str, session_id: str, polling_time: int = 10):
    """Polling the `file processing status <https://aito.ai/docs/api/#get-api-v1-data-table-file-uuid>`__ until
    the processing finished

    :param client: the AitoClient instance
    :type client: AitoClient
    :param table_name: the name of the table to be uploaded
    :type table_name: str
    :param session_id: The upload session id from :func:`.initiate_upload_file`
    :type session_id: str
    :param polling_time: polling wait time
    :type polling_time: int
    """
    LOG.debug('polling processing status...')
    while True:
        try:
            processing_progress_resp = client.request(
                request_obj=aito_requests.GetFileProcessingRequest(table_name=table_name, session_id=session_id)
            )
            status = processing_progress_resp['status']
            LOG.debug(f"completed count: {status['completedCount']}, throughput: {status['throughput']}")
            if processing_progress_resp['errors']['message'] != 'Last 0 failing rows':
                LOG.error(processing_progress_resp['errors'])
            if status['finished']:
                break
        except Exception as e:
            LOG.debug(f'failed to get file upload status: {e}')
        time.sleep(polling_time)
示例#9
0
def get_database_schema(client: AitoClient) -> AitoDatabaseSchema:
    """`get the schema of the database <https://aito.ai/docs/api/#get-api-v1-schema>`__

    :param client: the AitoClient instance
    :type client: AitoClient
    :return: Aito database schema
    :rtype: Dict
    """
    res = client.request(request_obj=aito_requests.GetDatabaseSchemaRequest())
    return res.schema
示例#10
0
def get_version(client: AitoClient) -> str:
    """get the aito instance version

    :param client: the AitoClient instance
    :type client: AitoClient
    :return: version information in json format
    :rtype: Dict
    """
    resp = client.request(request_obj=aito_requests.GetVersionRequest())
    return resp.version
示例#11
0
def create_table(client: AitoClient, table_name: str, schema: Union[AitoTableSchema, Dict]):
    """`create a table <https://aito.ai/docs/api/#put-api-v1-schema-table>`__
    with the specified table name and schema

    update the table if the table already exists and does not contain any data

    .. note::

        requires the client to be setup with the READ-WRITE API key

    :param client: the AitoClient instance
    :type client: AitoClient
    :param table_name: the name of the table
    :type table_name: str
    :param schema: Aito table schema
    :type schema: an AitoTableSchema object or a Dict, optional
    """
    client.request(request_obj=aito_requests.CreateTableSchemaRequest(table_name=table_name, schema=schema))
    LOG.info(f'table `{table_name}` created')
示例#12
0
def job_request(
        client: AitoClient,
        job_endpoint: Optional[str] = None,
        query: Optional[Union[List, Dict]] = None,
        request_obj: Optional[Union[aito_requests.QueryAPIRequest, aito_requests.CreateJobRequest]] = None,
        polling_time: int = 10
) -> aito_responses.BaseResponse:
    """make a request to an Aito API endpoint using `Job <https://aito.ai/docs/api/#post-api-v1-jobs-query>`__

    This method should be used for requests that take longer than 30 seconds, e.g: evaluate

    The following query evaluate the performance of a predict query that uses the name of
    a product to predict its category

    >>> response = client.job_request(
    ...     job_endpoint='/api/v1/jobs/_evaluate',
    ...     query={
    ...         "test": { "$index": { "$mod": [4, 0] } },
    ...         "evaluate": {
    ...             "from": "products",
    ...             "where": { "name": { "$get": "name" } },
    ...             "predict": "category"
    ...         }
    ...     }
    ... )
    >>> print(response["accuracy"]) # doctest: +ELLIPSIS
    0.72...

    :param client: the AitoClient instance
    :type client: AitoClient
    :param job_endpoint: job end point
    :type job_endpoint: Optional[str]
    :param query: the query for the endpoint
    :type query: Optional[Union[List, Dict]]
    :param request_obj: a :class:`.CreateJobRequest` or an :class:`.QueryAPIRequest` instance
    :type request_obj: Optional[Union[aito_requests.QueryAPIRequest, aito_requests.CreateJobRequest]]
    :param polling_time: polling wait time, defaults to 10
    :type polling_time: int
    :raises RequestError: an error occurred during the execution of the job
    :return: request JSON content
    :rtype: Dict
    """
    create_job_req = _create_job_request(job_endpoint=job_endpoint, query=query, request_obj=request_obj)
    create_job_resp = client.request(request_obj=create_job_req)
    job_id = create_job_resp.id
    LOG.debug(f'polling job {job_id} status...')
    while True:
        job_status_resp = get_job_status(client, job_id)
        if job_status_resp.finished:
            LOG.debug(f'job {job_id} finished')
            break
        time.sleep(polling_time)
    job_result_resp = get_job_result(client, job_id)
    casted_job_result_resp = create_job_req.result_response_cls(job_result_resp.json)
    return casted_job_result_resp
示例#13
0
def create_column(client: AitoClient, table_name: str, column_name: str, schema: Dict):
    """`add or replace a column <https://aito.ai/docs/api/#put-api-v1-schema-table-column>`__

    .. note::

        requires the client to be setup with the READ-WRITE API key

    :param client: the AitoClient instance
    :type client: AitoClient
    :param table_name: the name of the table containing the column
    :type table_name: str
    :param column_name: the name of the column
    :type column_name: str
    :param schema: the schema of the column
    :type schema: Dict
    """
    client.request(request_obj=aito_requests.CreateColumnSchemaRequest(
        table_name=table_name, column_name=column_name, schema=schema)
    )
    LOG.info(f'column `{table_name}.{column_name}` created')
 def setUpClass(cls):
     super().setUpClass()
     cls.input_folder = cls.input_folder.parent.parent / 'sample_invoice'
     cls.default_main_parser_args = {
         'verbose': False, 'version': False, 'quiet': False,
         'driver': '.env', 'server': '.env', 'port': '.env', 'database': '.env', 'username': '******',
         'password': '******'
     }
     cls.default_client_args = {'profile': 'default', 'api_key': '.env', 'instance_url': '.env'}
     cls.client = AitoClient(os.environ['AITO_INSTANCE_URL'], os.environ['AITO_API_KEY'])
     cls.default_table_name = f"invoice_{str(uuid4()).replace('-', '_')}"
示例#15
0
def copy_table(client: AitoClient, table_name: str, copy_table_name: str, replace: bool = False):
    """`copy a table <https://aito.ai/docs/api/#post-api-v1-schema-copy>`__

    .. note::

        requires the client to be setup with the READ-WRITE API key

    :param client: the AitoClient instance
    :type client: AitoClient
    :param table_name: the name of the table to be copied
    :type table_name: str
    :param copy_table_name: the name of the new copy table
    :type copy_table_name: str
    :param replace: replace an existing table of which name is the name of the copy table, defaults to False
    :type replace: bool, optional
    """
    client.request(
        method='POST',
        endpoint='/api/v1/schema/_copy',
        query={'from': table_name, 'copy': copy_table_name, 'replace': replace}
    )
示例#16
0
def rename_table(client: AitoClient, old_name: str, new_name: str, replace: bool = False):
    """`rename a table <https://aito.ai/docs/api/#post-api-v1-schema-rename>`__

    .. note::

        requires the client to be setup with the READ-WRITE API key

    :param client: the AitoClient instance
    :type client: AitoClient
    :param old_name: the name of the table to be renamed
    :type old_name: str
    :param new_name: the new name of the table
    :type new_name: str
    :param replace: replace an existing table of which name is the new name, defaults to False
    :type replace: bool, optional
    """
    client.request(
        method='POST',
        endpoint='/api/v1/schema/_rename',
        query={'from': old_name, 'rename': new_name, 'replace': replace}
    )
def get_requests_resp_and_aito_resp(aito_client: AitoClient,
                                    request_obj: aito_requests.AitoRequest):
    """returns the json content from requests lib response and aito response for comparison"""
    raw_resp_obj = requests.request(method=request_obj.method,
                                    url=aito_client.instance_url +
                                    request_obj.endpoint,
                                    headers=aito_client.headers,
                                    json=request_obj.query)
    raw_resp_json = raw_resp_obj.json()

    aito_resp = aito_client.request(request_obj=request_obj)
    return raw_resp_json, aito_resp
示例#18
0
def get_job_result(client: AitoClient, job_id: str) -> aito_responses.BaseResponse:
    """`Get the result of a job <https://aito.ai/docs/api/#get-api-v1-jobs-uuid-result>`__ with the specified job id

    :param client: the AitoClient instance
    :type client: AitoClient
    :param job_id: the id of the job
    :type job_id: str
    :return: the job result
    :rtype: Dict
    """
    resp = client.request(request_obj=aito_requests.GetJobResultRequest(job_id=job_id))
    return resp
示例#19
0
def get_table_schema(client: AitoClient, table_name: str) -> AitoTableSchema:
    """`get the schema of the specified table <https://aito.ai/docs/api/#get-api-v1-schema-table>`__

    :param client: the AitoClient instance
    :type client: AitoClient
    :param table_name: the name of the table
    :type table_name: str
    :return: the table schema
    :rtype: AitoTableSchema
    """
    resp = client.request(request_obj=aito_requests.GetTableSchemaRequest(table_name=table_name))
    return resp.schema
示例#20
0
def get_job_status(client: AitoClient, job_id: str) -> aito_responses.GetJobStatusResponse:
    """`Get the status of a job <https://aito.ai/docs/api/#get-api-v1-jobs-uuid>`__ with the specified job id

    :param client: the AitoClient instance
    :type client: AitoClient
    :param job_id: the id of the job session
    :type job_id: str
    :return: job status
    :rtype: Dict
    """
    resp = client.request(request_obj=aito_requests.GetJobStatusRequest(job_id=job_id))
    return resp
示例#21
0
def initiate_upload_file(client: AitoClient, table_name: str) -> Dict:
    """`Initial uploading a file to a table <https://aito.ai/docs/api/#post-api-v1-data-table-file>`__

    :param client: the AitoClient instance
    :type client: AitoClient
    :param table_name: the name of the table to be uploaded
    :type table_name: str
    :return: The details to execute the S3 upload and the upload session's id
    :rtype: Dict
    """
    LOG.debug('initiating file upload...')
    r = client.request(request_obj=aito_requests.InitiateFileUploadRequest(table_name=table_name))
    return r.json
示例#22
0
def get_column_schema(client: AitoClient, table_name: str, column_name: str) -> AitoColumnTypeSchema:
    """`get the schema of the specified column <https://aito.ai/docs/api/#get-api-v1-schema-table-column>`__

    :param client: the AitoClient instance
    :type client: AitoClient
    :param table_name: the name of the table containing the column
    :type table_name: str
    :param column_name: the name of the column
    :type column_name: str
    :return: the column schema
    :rtype: AitoColumnTypeSchema
    """
    resp = client.request(request_obj=aito_requests.GetColumnSchemaRequest(table_name=table_name, column_name=column_name))
    return resp.schema
示例#23
0
def optimize_table(client: AitoClient, table_name, use_job: bool = True):
    """`optimize <https://aito.ai/docs/api/#post-api-v1-data-table-optimize>`__
    the specified table after uploading the data. By default uses a job for the operation

    :param client: the AitoClient instance
    :type client: AitoClient
    :param table_name: the name of the table
    :type table_name: str
    :param use_job: use a job to run the optimize
    :type use_job: bool
    """
    try:
        if use_job:
            job_request(client,
                        job_endpoint=f'/api/v1/jobs/data/{table_name}/optimize',
                        query={},
                        polling_time=5)

        else:
            client.request(method='POST', endpoint=f'/api/v1/data/{table_name}/optimize', query={})
        LOG.info(f'table {table_name} optimized')
    except Exception as e:
        LOG.error(f'failed to optimize: {e}')
        traceback.print_tb(e.__traceback__)
示例#24
0
def delete_entries(client: AitoClient, query: Dict, use_job: bool = True):
    """`Delete the entries <https://aito.ai/docs/api/#post-api-v1-data-delete>`__ according to the criteria
    given in the query

    :param client: the AitoClient instance
    :type client: AitoClient
    :param query: the query to describe the target table and filters for which entries to delete.
    :type query: Dict
    :param use_job: use a job to run the optimize
    :type use_job: bool
    """
    try:
        if use_job:
            job_request(client,
                        job_endpoint=f'/api/v1/jobs/data/_delete',
                        query=query,
                        polling_time=5)
        else:
            client.request(request_obj=aito_requests.DeleteEntriesRequest(query=query))

        LOG.info(f'entries deleted')
    except Exception as e:
        LOG.error(f'failed to delete: {e}')
        traceback.print_tb(e.__traceback__)
示例#25
0
    def top_recommendation(self):
        AITO_INSTANCE_URL = 'https://junction-test.aito.app'
        AITO_API_KEY = '4yaBPf9Kmk9xHNW30jBop7ieEmWMz2eSpmKyWvBi'

        client = AitoClient(instance_url=AITO_INSTANCE_URL,
                            api_key=AITO_API_KEY)
        queries = self.request.query_params
        query_type = queries.get("type", "Mexican")

        limit = int(queries.get("limit", 0))
        user_id = queries.get("userID")

        wh = {
            "placeID.cuisine": query_type,
        }
        if user_id:
            like_places = list(
                map(
                    lambda t: {"placeID": t},
                    UserLike.objects.exclude(user_id=user_id).values_list(
                        "place__aito_id", flat=True)))
            if like_places:
                query = {
                    "from": "ratings",
                    "where": {
                        "$and": like_places
                    },
                }
                res = aito_api.generic_query(client=client, query=query)
                user_ids = py_.map(res["hits"], "userID")
                wh["userID"] = {"$and": user_ids}

        rec_query = {
            "from": "ratings",
            "where": wh,
            "recommend": "placeID",
            "goal": {
                "rating": 2
            },
        }
        if limit:
            rec_query['limit'] = int(limit)

        res = aito_api.recommend(client=client, query=rec_query)
        return res.json['hits']
示例#26
0
def recommend(
        client: AitoClient, query: Dict, raise_for_status: Optional[bool] = None, use_job: bool = False
) -> Union[aito_responses.RecommendResponse, RequestError]:
    """send a query to the `Recommend API <https://aito.ai/docs/api/#post-api-v1-recommend>`__

    :param client: the AitoClient instance
    :type client: AitoClient
    :param query: the recommend query
    :type query: Dict
    :param raise_for_status: raise :class:`.RequestError` if the request fails instead of returning the error
        If set to None, value from Client will be used. Defaults to None
    :type raise_for_status: Optional[bool]
    :param use_job: use job fo request that takes longer than 30 seconds, defaults to False
    :type use_job: bool
    :return: :class:`.RecommendResponse`  or :class:`.RequestError` if an error occurred and not raise_for_status
    :rtype: Union[RecommendResponse, RequestError]
    """
    req = aito_requests.RecommendRequest(query)
    if use_job:
        return job_request(client=client, request_obj=req)
    return client.request(request_obj=req, raise_for_status=raise_for_status)
示例#27
0
    def top_recommendation(self):
        AITO_INSTANCE_URL = 'https://junction-test.aito.app'
        AITO_API_KEY = '4yaBPf9Kmk9xHNW30jBop7ieEmWMz2eSpmKyWvBi'

        client = AitoClient(instance_url=AITO_INSTANCE_URL, api_key=AITO_API_KEY)
        queries = self.request.query_params
        query_type = queries.get("type", "Mexican")

        limit = int(queries.get("limit", 0))
        rec_query = {
            "from": "ratings",
            "where": {
                "placeID.cuisine": query_type,
            },
            "recommend": "placeID",
            "goal": {"rating": 2},
        }
        if limit:
            rec_query['limit'] = int(limit)

        res = aito_api.recommend(client=client, query=rec_query)
        return res.json['hits']
示例#28
0
def create_job(
        client: AitoClient,
        job_endpoint: Optional[str] = None,
        query: Optional[Union[List, Dict]] = None,
        request_obj: Optional[Union[aito_requests.QueryAPIRequest, aito_requests.CreateJobRequest]] = None,
) -> aito_responses.CreateJobResponse:
    """Create a `job <https://aito.ai/docs/api/#post-api-v1-jobs-query>`__
    for a query that takes longer than 30 seconds to run

    :param client: the AitoClient instance
    :type client: AitoClient
    :param job_endpoint: the job endpoint
    :type job_endpoint: Optional[str]
    :param query: the query for the endpoint
    :type query: Optional[Union[List, Dict]]
    :param request_obj: a :class:`.CreateJobRequest` or an :class:`.QueryAPIRequest` instance
    :type request_obj: Optional[Union[aito_requests.QueryAPIRequest, aito_requests.CreateJobRequest]]
    :return: job information
    :rtype: Dict
    """
    create_job_req = _create_job_request(job_endpoint=job_endpoint, query=query, request_obj=request_obj)
    resp = client.request(request_obj=create_job_req)
    return resp
示例#29
0
def grocery_demo_client():
    return AitoClient(get_env_var('AITO_GROCERY_DEMO_INSTANCE_URL'),
                      get_env_var('AITO_GROCERY_DEMO_API_KEY'))
示例#30
0
def default_client():
    return AitoClient(get_env_var('AITO_INSTANCE_URL'),
                      get_env_var('AITO_API_KEY'))