コード例 #1
0
    def target_list(
        self,
        request: _RequestObjectProxy,
        context: _Context,  # pylint: disable=unused-argument
    ) -> str:
        """
        Get a list of all targets.

        Fake implementation of
        https://library.vuforia.com/articles/Solution/How-To-Use-the-Vuforia-Web-Services-API.html#How-To-Get-a-Target-List-for-a-Cloud-Database
        """
        database = get_database_matching_server_keys(
            request_headers=request.headers,
            request_body=request.body,
            request_method=request.method,
            request_path=request.path,
            databases=self.databases,
        )

        assert isinstance(database, VuforiaDatabase)
        results = [
            target.target_id
            for target in database.targets
            if not target.delete_date
        ]

        body: Dict[str, Union[str, List[str]]] = {
            'transaction_id': uuid.uuid4().hex,
            'result_code': ResultCodes.SUCCESS.value,
            'results': results,
        }
        return json_dump(body)
コード例 #2
0
def target_list() -> Response:
    """
    Get a list of all targets.

    Fake implementation of
    https://library.vuforia.com/articles/Solution/How-To-Use-the-Vuforia-Web-Services-API.html#How-To-Get-a-Target-List-for-a-Cloud-Database
    """
    databases = get_all_databases()
    database = get_database_matching_server_keys(
        request_headers=dict(request.headers),
        request_body=request.data,
        request_method=request.method,
        request_path=request.path,
        databases=databases,
    )
    assert isinstance(database, VuforiaDatabase)
    results = [target.target_id for target in database.not_deleted_targets]

    body = {
        'transaction_id': uuid.uuid4().hex,
        'result_code': ResultCodes.SUCCESS.value,
        'results': results,
    }
    date = email.utils.formatdate(None, localtime=False, usegmt=True)
    headers = {
        'Connection': 'keep-alive',
        'Content-Type': 'application/json',
        'Server': 'nginx',
        'Date': date,
    }
    return Response(
        status=HTTPStatus.OK,
        response=json_dump(body),
        headers=headers,
    )
コード例 #3
0
    def target_summary(
        self,
        request: _RequestObjectProxy,
        context: _Context,
    ) -> str:
        """
        Get a summary report for a target.

        Fake implementation of
        https://library.vuforia.com/articles/Solution/How-To-Use-the-Vuforia-Web-Services-API.html#How-To-Retrieve-a-Target-Summary-Report
        """
        try:
            run_services_validators(
                request_headers=request.headers,
                request_body=request.body,
                request_method=request.method,
                request_path=request.path,
                databases=self._target_manager.databases,
            )
        except ValidatorException as exc:
            context.headers = exc.headers
            context.status_code = exc.status_code
            return exc.response_text

        database = get_database_matching_server_keys(
            request_headers=request.headers,
            request_body=request.body,
            request_method=request.method,
            request_path=request.path,
            databases=self._target_manager.databases,
        )
        assert isinstance(database, VuforiaDatabase)
        target_id = request.path.split('/')[-1]
        target = database.get_target(target_id=target_id)

        assert isinstance(database, VuforiaDatabase)
        date = email.utils.formatdate(None, localtime=False, usegmt=True)
        body = {
            'status': target.status,
            'transaction_id': uuid.uuid4().hex,
            'result_code': ResultCodes.SUCCESS.value,
            'database_name': database.database_name,
            'target_name': target.name,
            'upload_date': target.upload_date.strftime('%Y-%m-%d'),
            'active_flag': target.active_flag,
            'tracking_rating': target.tracking_rating,
            'total_recos': target.total_recos,
            'current_month_recos': target.current_month_recos,
            'previous_month_recos': target.previous_month_recos,
        }
        body_json = json_dump(body)
        context.headers = {
            'Connection': 'keep-alive',
            'Content-Type': 'application/json',
            'Content-Length': str(len(body_json)),
            'Server': 'nginx',
            'Date': date,
        }

        return body_json
コード例 #4
0
def validate_authorization(
    request_path: str,
    request_headers: Dict[str, str],
    request_body: bytes,
    request_method: str,
    databases: Set[VuforiaDatabase],
) -> None:
    """
    Validate the authorization header given to a VWS endpoint.

    Args:
        request_path: The path of the request.
        request_headers: The headers sent with the request.
        request_body: The body of the request.
        request_method: The HTTP method of the request.
        databases: All Vuforia databases.

    Raises:
        AuthenticationFailure: No database matches the given authorization
            header.
    """
    database = get_database_matching_server_keys(
        request_headers=request_headers,
        request_body=request_body,
        request_method=request_method,
        request_path=request_path,
        databases=databases,
    )

    if database is None:
        raise AuthenticationFailure
コード例 #5
0
def validate_name_does_not_exist_existing_target(
    request_headers: Dict[str, str],
    request_body: bytes,
    request_method: str,
    request_path: str,
    databases: Set[VuforiaDatabase],
) -> None:
    """
    Validate that the name does not exist for any existing target apart from
    the one being updated.

    Args:
        databases: All Vuforia databases.
        request_body: The body of the request.
        request_headers: The headers sent with the request.
        request_method: The HTTP method the request is using.
        request_path: The path to the endpoint.

    Raises:
        TargetNameExist: The target name is not the same as the name of the
            target being updated but it is the same as another target.
    """

    if not request_body:
        return

    request_text = request_body.decode()
    if 'name' not in json.loads(request_text):
        return

    split_path = request_path.split('/')
    if len(split_path) == 2:
        return

    target_id = split_path[-1]

    name = json.loads(request_text)['name']
    database = get_database_matching_server_keys(
        request_headers=request_headers,
        request_body=request_body,
        request_method=request_method,
        request_path=request_path,
        databases=databases,
    )
    assert isinstance(database, VuforiaDatabase)

    matching_name_targets = [
        target for target in database.not_deleted_targets
        if target.name == name
    ]

    if not matching_name_targets:
        return

    [matching_name_target] = matching_name_targets
    if matching_name_target.target_id == target_id:
        return

    raise TargetNameExist
コード例 #6
0
    def add_target(
        self,
        request: _RequestObjectProxy,
        context: _Context,
    ) -> str:
        """
        Add a target.

        Fake implementation of
        https://library.vuforia.com/articles/Solution/How-To-Use-the-Vuforia-Web-Services-API.html#How-To-Add-a-Target
        """
        name = request.json()['name']
        database = get_database_matching_server_keys(
            request_headers=request.headers,
            request_body=request.body,
            request_method=request.method,
            request_path=request.path,
            databases=self.databases,
        )

        assert isinstance(database, VuforiaDatabase)

        targets = (
            target for target in database.targets if not target.delete_date
        )
        if any(target.name == name for target in targets):
            context.status_code = HTTPStatus.FORBIDDEN
            body = {
                'transaction_id': uuid.uuid4().hex,
                'result_code': ResultCodes.TARGET_NAME_EXIST.value,
            }
            return json_dump(body)

        active_flag = request.json().get('active_flag')
        if active_flag is None:
            active_flag = True

        image = request.json()['image']
        decoded = base64.b64decode(image)
        image_file = io.BytesIO(decoded)

        new_target = Target(
            name=request.json()['name'],
            width=request.json()['width'],
            image=image_file,
            active_flag=active_flag,
            processing_time_seconds=self._processing_time_seconds,
            application_metadata=request.json().get('application_metadata'),
        )
        database.targets.add(new_target)

        context.status_code = HTTPStatus.CREATED
        body = {
            'transaction_id': uuid.uuid4().hex,
            'result_code': ResultCodes.TARGET_CREATED.value,
            'target_id': new_target.target_id,
        }
        return json_dump(body)
コード例 #7
0
    def target_list(
        self,
        request: _RequestObjectProxy,
        context: _Context,
    ) -> str:
        """
        Get a list of all targets.

        Fake implementation of
        https://library.vuforia.com/articles/Solution/How-To-Use-the-Vuforia-Web-Services-API.html#How-To-Get-a-Target-List-for-a-Cloud-Database
        """
        try:
            run_services_validators(
                request_headers=request.headers,
                request_body=request.body,
                request_method=request.method,
                request_path=request.path,
                databases=self._target_manager.databases,
            )
        except ValidatorException as exc:
            context.headers = exc.headers
            context.status_code = exc.status_code
            return exc.response_text

        database = get_database_matching_server_keys(
            request_headers=request.headers,
            request_body=request.body,
            request_method=request.method,
            request_path=request.path,
            databases=self._target_manager.databases,
        )

        assert isinstance(database, VuforiaDatabase)
        date = email.utils.formatdate(None, localtime=False, usegmt=True)

        results = [target.target_id for target in database.not_deleted_targets]
        body: Dict[str, str | list[str]] = {
            'transaction_id': uuid.uuid4().hex,
            'result_code': ResultCodes.SUCCESS.value,
            'results': results,
        }
        body_json = json_dump(body)
        context.headers = {
            'Connection': 'keep-alive',
            'Content-Type': 'application/json',
            'Server': 'nginx',
            'Date': date,
            'Content-Length': str(len(body_json)),
        }
        return body_json
コード例 #8
0
def get_duplicates(target_id: str) -> Response:
    """
    Get targets which may be considered duplicates of a given target.

    Fake implementation of
    https://library.vuforia.com/articles/Solution/How-To-Use-the-Vuforia-Web-Services-API.html#How-To-Check-for-Duplicate-Targets
    """
    databases = get_all_databases()
    database = get_database_matching_server_keys(
        request_headers=dict(request.headers),
        request_body=request.data,
        request_method=request.method,
        request_path=request.path,
        databases=databases,
    )

    assert isinstance(database, VuforiaDatabase)
    [target] = [
        target for target in database.targets if target.target_id == target_id
    ]
    other_targets = set(database.targets) - {target}

    similar_targets: list[str] = [
        other.target_id
        for other in other_targets
        if other.image_value == target.image_value
        and TargetStatuses.FAILED.value not in (target.status, other.status)
        and TargetStatuses.PROCESSING.value != other.status
        and other.active_flag
    ]

    body = {
        'transaction_id': uuid.uuid4().hex,
        'result_code': ResultCodes.SUCCESS.value,
        'similar_targets': similar_targets,
    }

    date = email.utils.formatdate(None, localtime=False, usegmt=True)
    headers = {
        'Connection': 'keep-alive',
        'Content-Type': 'application/json',
        'Server': 'nginx',
        'Date': date,
    }
    return Response(
        status=HTTPStatus.OK,
        response=json_dump(body),
        headers=headers,
    )
コード例 #9
0
def get_target(target_id: str) -> Response:
    """
    Get details of a target.

    Fake implementation of
    https://library.vuforia.com/articles/Solution/How-To-Use-the-Vuforia-Web-Services-API.html#How-To-Retrieve-a-Target-Record
    """
    databases = get_all_databases()
    database = get_database_matching_server_keys(
        request_headers=dict(request.headers),
        request_body=request.data,
        request_method=request.method,
        request_path=request.path,
        databases=databases,
    )

    assert isinstance(database, VuforiaDatabase)
    [target] = [
        target for target in database.targets if target.target_id == target_id
    ]

    target_record = {
        'target_id': target.target_id,
        'active_flag': target.active_flag,
        'name': target.name,
        'width': target.width,
        'tracking_rating': target.tracking_rating,
        'reco_rating': target.reco_rating,
    }

    date = email.utils.formatdate(None, localtime=False, usegmt=True)
    headers = {
        'Connection': 'keep-alive',
        'Content-Type': 'application/json',
        'Server': 'nginx',
        'Date': date,
    }
    body = {
        'result_code': ResultCodes.SUCCESS.value,
        'transaction_id': uuid.uuid4().hex,
        'target_record': target_record,
        'status': target.status,
    }
    return Response(
        status=HTTPStatus.OK,
        response=json_dump(body),
        headers=headers,
    )
コード例 #10
0
def database_summary() -> Response:
    """
    Get a database summary report.

    Fake implementation of
    https://library.vuforia.com/articles/Solution/How-To-Use-the-Vuforia-Web-Services-API.html#How-To-Get-a-Database-Summary-Report
    """
    databases = get_all_databases()
    database = get_database_matching_server_keys(
        request_headers=dict(request.headers),
        request_body=request.data,
        request_method=request.method,
        request_path=request.path,
        databases=databases,
    )

    assert isinstance(database, VuforiaDatabase)
    body = {
        'result_code': ResultCodes.SUCCESS.value,
        'transaction_id': uuid.uuid4().hex,
        'name': database.database_name,
        'active_images': len(database.active_targets),
        'inactive_images': len(database.inactive_targets),
        'failed_images': len(database.failed_targets),
        'target_quota': database.target_quota,
        'total_recos': database.total_recos,
        'current_month_recos': database.current_month_recos,
        'previous_month_recos': database.previous_month_recos,
        'processing_images': len(database.processing_targets),
        'reco_threshold': database.reco_threshold,
        'request_quota': database.request_quota,
        # We have ``self.request_count`` but Vuforia always shows 0.
        # This was not always the case.
        'request_usage': 0,
    }
    date = email.utils.formatdate(None, localtime=False, usegmt=True)
    headers = {
        'Connection': 'keep-alive',
        'Content-Type': 'application/json',
        'Server': 'nginx',
        'Date': date,
    }
    return Response(
        status=HTTPStatus.OK,
        response=json_dump(body),
        headers=headers,
    )
コード例 #11
0
def delete_target(target_id: str) -> Response:
    """
    Delete a target.

    Fake implementation of
    https://library.vuforia.com/articles/Solution/How-To-Use-the-Vuforia-Web-Services-API.html#How-To-Delete-a-Target
    """
    databases = get_all_databases()
    database = get_database_matching_server_keys(
        request_headers=dict(request.headers),
        request_body=request.data,
        request_method=request.method,
        request_path=request.path,
        databases=databases,
    )

    assert isinstance(database, VuforiaDatabase)
    [target] = [
        target for target in database.targets if target.target_id == target_id
    ]

    if target.status == TargetStatuses.PROCESSING.value:
        raise TargetStatusProcessing

    target_manager_base_url = os.environ['TARGET_MANAGER_BASE_URL']
    databases_url = f'{target_manager_base_url}/databases'
    requests.delete(
        url=f'{databases_url}/{database.database_name}/targets/{target_id}',
    )

    body = {
        'transaction_id': uuid.uuid4().hex,
        'result_code': ResultCodes.SUCCESS.value,
    }
    date = email.utils.formatdate(None, localtime=False, usegmt=True)
    headers = {
        'Connection': 'keep-alive',
        'Content-Type': 'application/json',
        'Server': 'nginx',
        'Date': date,
    }
    return Response(
        status=HTTPStatus.OK,
        response=json_dump(body),
        headers=headers,
    )
コード例 #12
0
def target_summary(target_id: str) -> Response:
    """
    Get a summary report for a target.

    Fake implementation of
    https://library.vuforia.com/articles/Solution/How-To-Use-the-Vuforia-Web-Services-API.html#How-To-Retrieve-a-Target-Summary-Report
    """
    databases = get_all_databases()
    database = get_database_matching_server_keys(
        request_headers=dict(request.headers),
        request_body=request.data,
        request_method=request.method,
        request_path=request.path,
        databases=databases,
    )

    assert isinstance(database, VuforiaDatabase)
    [target] = [
        target for target in database.targets if target.target_id == target_id
    ]
    body = {
        'status': target.status,
        'transaction_id': uuid.uuid4().hex,
        'result_code': ResultCodes.SUCCESS.value,
        'database_name': database.database_name,
        'target_name': target.name,
        'upload_date': target.upload_date.strftime('%Y-%m-%d'),
        'active_flag': target.active_flag,
        'tracking_rating': target.tracking_rating,
        'total_recos': target.total_recos,
        'current_month_recos': target.current_month_recos,
        'previous_month_recos': target.previous_month_recos,
    }
    date = email.utils.formatdate(None, localtime=False, usegmt=True)
    headers = {
        'Connection': 'keep-alive',
        'Content-Type': 'application/json',
        'Server': 'nginx',
        'Date': date,
    }
    return Response(
        status=HTTPStatus.OK,
        response=json_dump(body),
        headers=headers,
    )
コード例 #13
0
def validate_target_id_exists(
    request_path: str,
    request_headers: Dict[str, str],
    request_body: bytes,
    request_method: str,
    databases: Set[VuforiaDatabase],
) -> None:
    """
    Validate that if a target ID is given, it exists in the database matching
    the request.

    Args:
        request_path: The path of the request.
        request_headers: The headers sent with the request.
        request_body: The body of the request.
        request_method: The HTTP method of the request.
        databases: All Vuforia databases.

    Raises:
        UnknownTarget: There are no matching targets for a given target ID.
    """
    split_path = request_path.split('/')

    if len(split_path) == 2:
        return

    target_id = split_path[-1]
    database = get_database_matching_server_keys(
        request_headers=request_headers,
        request_body=request_body,
        request_method=request_method,
        request_path=request_path,
        databases=databases,
    )

    assert isinstance(database, VuforiaDatabase)

    try:
        [_] = [
            target
            for target in database.targets
            if target.target_id == target_id and not target.delete_date
        ]
    except ValueError as exc:
        raise UnknownTarget from exc
コード例 #14
0
    def get_duplicates(
        self,
        request: _RequestObjectProxy,
        context: _Context,  # pylint: disable=unused-argument
    ) -> str:
        """
        Get targets which may be considered duplicates of a given target.

        Fake implementation of
        https://library.vuforia.com/articles/Solution/How-To-Use-the-Vuforia-Web-Services-API.html#How-To-Check-for-Duplicate-Targets
        """
        target = _get_target_from_request(
            request_path=request.path,
            databases=self.databases,
        )
        database = get_database_matching_server_keys(
            request_headers=request.headers,
            request_body=request.body,
            request_method=request.method,
            request_path=request.path,
            databases=self.databases,
        )

        assert isinstance(database, VuforiaDatabase)
        other_targets = set(database.targets) - set([target])

        similar_targets: List[str] = [
            other.target_id
            for other in other_targets
            if Image.open(other.image) == Image.open(target.image)
            and TargetStatuses.FAILED.value
            not in (target.status, other.status)
            and TargetStatuses.PROCESSING.value != other.status
            and other.active_flag
        ]

        body = {
            'transaction_id': uuid.uuid4().hex,
            'result_code': ResultCodes.SUCCESS.value,
            'similar_targets': similar_targets,
        }

        return json_dump(body)
コード例 #15
0
    def target_summary(
        self,
        request: _RequestObjectProxy,
        context: _Context,  # pylint: disable=unused-argument
    ) -> str:
        """
        Get a summary report for a target.

        Fake implementation of
        https://library.vuforia.com/articles/Solution/How-To-Use-the-Vuforia-Web-Services-API.html#How-To-Retrieve-a-Target-Summary-Report
        """
        target = _get_target_from_request(
            request_path=request.path,
            databases=self.databases,
        )
        database = get_database_matching_server_keys(
            request_headers=request.headers,
            request_body=request.body,
            request_method=request.method,
            request_path=request.path,
            databases=self.databases,
        )

        assert isinstance(database, VuforiaDatabase)
        body = {
            'status': target.status,
            'transaction_id': uuid.uuid4().hex,
            'result_code': ResultCodes.SUCCESS.value,
            'database_name': database.database_name,
            'target_name': target.name,
            'upload_date': target.upload_date.strftime('%Y-%m-%d'),
            'active_flag': target.active_flag,
            'tracking_rating': target.tracking_rating,
            'total_recos': 0,
            'current_month_recos': 0,
            'previous_month_recos': 0,
        }
        return json_dump(body)
コード例 #16
0
def validate_project_state(
    request_path: str,
    request_headers: Dict[str, str],
    request_body: bytes,
    request_method: str,
    databases: Set[VuforiaDatabase],
) -> None:
    """
    Validate the state of the project.

    Args:
        request_path: The path of the request.
        request_headers: The headers sent with the request.
        request_body: The body of the request.
        request_method: The HTTP method of the request.
        databases: All Vuforia databases.

    Raises:
        ProjectInactive: The project is inactive and this endpoint does not
            work with inactive projects.
    """
    database = get_database_matching_server_keys(
        request_headers=request_headers,
        request_body=request_body,
        request_method=request_method,
        request_path=request_path,
        databases=databases,
    )

    assert isinstance(database, VuforiaDatabase)
    if database.state != States.PROJECT_INACTIVE:
        return

    if request_method == 'GET' and 'duplicates' not in request_path:
        return

    raise ProjectInactive
コード例 #17
0
    def delete_target(
        self,
        request: _RequestObjectProxy,
        context: _Context,
    ) -> str:
        """
        Delete a target.

        Fake implementation of
        https://library.vuforia.com/articles/Solution/How-To-Use-the-Vuforia-Web-Services-API.html#How-To-Delete-a-Target
        """
        try:
            run_services_validators(
                request_headers=request.headers,
                request_body=request.body,
                request_method=request.method,
                request_path=request.path,
                databases=self._target_manager.databases,
            )
        except ValidatorException as exc:
            context.headers = exc.headers
            context.status_code = exc.status_code
            return exc.response_text

        body: Dict[str, str] = {}
        database = get_database_matching_server_keys(
            request_headers=request.headers,
            request_body=request.body,
            request_method=request.method,
            request_path=request.path,
            databases=self._target_manager.databases,
        )

        assert isinstance(database, VuforiaDatabase)
        target_id = request.path.split('/')[-1]
        target = database.get_target(target_id=target_id)

        if target.status == TargetStatuses.PROCESSING.value:
            target_processing_exception = TargetStatusProcessing()
            context.headers = target_processing_exception.headers
            context.status_code = target_processing_exception.status_code
            return target_processing_exception.response_text

        now = datetime.datetime.now(tz=target.upload_date.tzinfo)
        new_target = dataclasses.replace(target, delete_date=now)
        database.targets.remove(target)
        database.targets.add(new_target)
        date = email.utils.formatdate(None, localtime=False, usegmt=True)

        body = {
            'transaction_id': uuid.uuid4().hex,
            'result_code': ResultCodes.SUCCESS.value,
        }
        body_json = json_dump(body)
        context.headers = {
            'Connection': 'keep-alive',
            'Content-Type': 'application/json',
            'Server': 'nginx',
            'Date': date,
            'Content-Length': str(len(body_json)),
        }
        return body_json
コード例 #18
0
def add_target() -> Response:
    """
    Add a target.

    Fake implementation of
    https://library.vuforia.com/articles/Solution/How-To-Use-the-Vuforia-Web-Services-API.html#How-To-Add-a-Target
    """
    processing_time_seconds = float(
        os.environ.get('PROCESSING_TIME_SECONDS', '0.5'),
    )
    databases = get_all_databases()
    database = get_database_matching_server_keys(
        request_headers=dict(request.headers),
        request_body=request.data,
        request_method=request.method,
        request_path=request.path,
        databases=databases,
    )

    assert isinstance(database, VuforiaDatabase)

    # We do not use ``request.get_json(force=True)`` because this only works
    # when the content type is given as ``application/json``.
    request_json = json.loads(request.data)
    name = request_json['name']
    active_flag = request_json.get('active_flag')
    if active_flag is None:
        active_flag = True

    new_target = Target(
        name=name,
        width=request_json['width'],
        image_value=base64.b64decode(request_json['image']),
        active_flag=active_flag,
        processing_time_seconds=processing_time_seconds,
        application_metadata=request_json.get('application_metadata'),
    )

    target_manager_base_url = os.environ['TARGET_MANAGER_BASE_URL']
    databases_url = f'{target_manager_base_url}/databases'
    requests.post(
        url=f'{databases_url}/{database.database_name}/targets',
        json=new_target.to_dict(),
    )

    date = email.utils.formatdate(None, localtime=False, usegmt=True)
    headers = {
        'Connection': 'keep-alive',
        'Content-Type': 'application/json',
        'Server': 'nginx',
        'Date': date,
    }
    body = {
        'transaction_id': uuid.uuid4().hex,
        'result_code': ResultCodes.TARGET_CREATED.value,
        'target_id': new_target.target_id,
    }

    return Response(
        status=HTTPStatus.CREATED,
        response=json_dump(body),
        headers=headers,
    )
コード例 #19
0
    def database_summary(
        self,
        request: _RequestObjectProxy,
        context: _Context,  # pylint: disable=unused-argument
    ) -> str:
        """
        Get a database summary report.

        Fake implementation of
        https://library.vuforia.com/articles/Solution/How-To-Use-the-Vuforia-Web-Services-API.html#How-To-Get-a-Database-Summary-Report
        """
        body: Dict[str, Union[str, int]] = {}

        database = get_database_matching_server_keys(
            request_headers=request.headers,
            request_body=request.body,
            request_method=request.method,
            request_path=request.path,
            databases=self.databases,
        )

        assert isinstance(database, VuforiaDatabase)
        active_images = len(
            [
                target
                for target in database.targets
                if target.status == TargetStatuses.SUCCESS.value
                and target.active_flag
                and not target.delete_date
            ],
        )

        failed_images = len(
            [
                target
                for target in database.targets
                if target.status == TargetStatuses.FAILED.value
                and not target.delete_date
            ],
        )

        inactive_images = len(
            [
                target
                for target in database.targets
                if target.status == TargetStatuses.SUCCESS.value
                and not target.active_flag
                and not target.delete_date
            ],
        )

        processing_images = len(
            [
                target
                for target in database.targets
                if target.status == TargetStatuses.PROCESSING.value
                and not target.delete_date
            ],
        )

        body = {
            'result_code': ResultCodes.SUCCESS.value,
            'transaction_id': uuid.uuid4().hex,
            'name': database.database_name,
            'active_images': active_images,
            'inactive_images': inactive_images,
            'failed_images': failed_images,
            'target_quota': 1000,
            'total_recos': 0,
            'current_month_recos': 0,
            'previous_month_recos': 0,
            'processing_images': processing_images,
            'reco_threshold': 1000,
            'request_quota': 100000,
            # We have ``self.request_count`` but Vuforia always shows 0.
            # This was not always the case.
            'request_usage': 0,
        }
        return json_dump(body)
コード例 #20
0
    def update_target(
        self,
        request: _RequestObjectProxy,
        context: _Context,
    ) -> str:
        """
        Update a target.

        Fake implementation of
        https://library.vuforia.com/articles/Solution/How-To-Use-the-Vuforia-Web-Services-API.html#How-To-Update-a-Target
        """
        try:
            run_services_validators(
                request_headers=request.headers,
                request_body=request.body,
                request_method=request.method,
                request_path=request.path,
                databases=self._target_manager.databases,
            )
        except ValidatorException as exc:
            context.headers = exc.headers
            context.status_code = exc.status_code
            return exc.response_text

        database = get_database_matching_server_keys(
            request_headers=request.headers,
            request_body=request.body,
            request_method=request.method,
            request_path=request.path,
            databases=self._target_manager.databases,
        )

        assert isinstance(database, VuforiaDatabase)

        target_id = request.path.split('/')[-1]
        target = database.get_target(target_id=target_id)
        body: Dict[str, str] = {}

        date = email.utils.formatdate(None, localtime=False, usegmt=True)

        if target.status != TargetStatuses.SUCCESS.value:
            exception = TargetStatusNotSuccess()
            context.headers = exception.headers
            context.status_code = exception.status_code
            return exception.response_text

        width = request.json().get('width', target.width)
        name = request.json().get('name', target.name)
        active_flag = request.json().get('active_flag', target.active_flag)
        application_metadata = request.json().get(
            'application_metadata',
            target.application_metadata,
        )

        image_value = target.image_value
        if 'image' in request.json():
            image_value = base64.b64decode(request.json()['image'])

        if 'active_flag' in request.json() and active_flag is None:
            fail_exception = Fail(status_code=HTTPStatus.BAD_REQUEST)
            context.headers = fail_exception.headers
            context.status_code = fail_exception.status_code
            return fail_exception.response_text

        if (
            'application_metadata' in request.json()
            and application_metadata is None
        ):
            fail_exception = Fail(status_code=HTTPStatus.BAD_REQUEST)
            context.headers = fail_exception.headers
            context.status_code = fail_exception.status_code
            return fail_exception.response_text

        # In the real implementation, the tracking rating can stay the same.
        # However, for demonstration purposes, the tracking rating changes but
        # when the target is updated.
        available_values = list(set(range(6)) - {target.tracking_rating})
        processed_tracking_rating = random.choice(available_values)

        gmt = ZoneInfo('GMT')
        last_modified_date = datetime.datetime.now(tz=gmt)

        new_target = dataclasses.replace(
            target,
            name=name,
            width=width,
            active_flag=active_flag,
            application_metadata=application_metadata,
            image_value=image_value,
            processed_tracking_rating=processed_tracking_rating,
            last_modified_date=last_modified_date,
        )

        database.targets.remove(target)
        database.targets.add(new_target)

        body = {
            'result_code': ResultCodes.SUCCESS.value,
            'transaction_id': uuid.uuid4().hex,
        }
        body_json = json_dump(body)
        context.headers = {
            'Connection': 'keep-alive',
            'Content-Type': 'application/json',
            'Server': 'nginx',
            'Date': date,
            'Content-Length': str(len(body_json)),
        }
        return body_json
コード例 #21
0
    def get_duplicates(
        self,
        request: _RequestObjectProxy,
        context: _Context,
    ) -> str:
        """
        Get targets which may be considered duplicates of a given target.

        Fake implementation of
        https://library.vuforia.com/articles/Solution/How-To-Use-the-Vuforia-Web-Services-API.html#How-To-Check-for-Duplicate-Targets
        """
        try:
            run_services_validators(
                request_headers=request.headers,
                request_body=request.body,
                request_method=request.method,
                request_path=request.path,
                databases=self._target_manager.databases,
            )
        except ValidatorException as exc:
            context.headers = exc.headers
            context.status_code = exc.status_code
            return exc.response_text

        database = get_database_matching_server_keys(
            request_headers=request.headers,
            request_body=request.body,
            request_method=request.method,
            request_path=request.path,
            databases=self._target_manager.databases,
        )
        assert isinstance(database, VuforiaDatabase)
        target_id = request.path.split('/')[-1]
        target = database.get_target(target_id=target_id)

        other_targets = set(database.targets) - {target}

        similar_targets: list[str] = [
            other.target_id
            for other in other_targets
            if other.image_value == target.image_value
            and TargetStatuses.FAILED.value
            not in (target.status, other.status)
            and TargetStatuses.PROCESSING.value != other.status
            and other.active_flag
        ]

        date = email.utils.formatdate(None, localtime=False, usegmt=True)
        body = {
            'transaction_id': uuid.uuid4().hex,
            'result_code': ResultCodes.SUCCESS.value,
            'similar_targets': similar_targets,
        }
        body_json = json_dump(body)
        context.headers = {
            'Connection': 'keep-alive',
            'Content-Type': 'application/json',
            'Server': 'nginx',
            'Date': date,
            'Content-Length': str(len(body_json)),
        }

        return body_json
コード例 #22
0
    def update_target(
        self,
        request: _RequestObjectProxy,
        context: _Context,
    ) -> str:
        """
        Update a target.

        Fake implementation of
        https://library.vuforia.com/articles/Solution/How-To-Use-the-Vuforia-Web-Services-API.html#How-To-Update-a-Target
        """
        target = _get_target_from_request(
            request_path=request.path,
            databases=self.databases,
        )
        body: Dict[str, str] = {}
        database = get_database_matching_server_keys(
            request_headers=request.headers,
            request_body=request.body,
            request_method=request.method,
            request_path=request.path,
            databases=self.databases,
        )

        assert isinstance(database, VuforiaDatabase)

        if target.status != TargetStatuses.SUCCESS.value:
            context.status_code = HTTPStatus.FORBIDDEN
            body = {
                'transaction_id': uuid.uuid4().hex,
                'result_code': ResultCodes.TARGET_STATUS_NOT_SUCCESS.value,
            }
            return json_dump(body)

        if 'width' in request.json():
            target.width = request.json()['width']

        if 'active_flag' in request.json():
            active_flag = request.json()['active_flag']
            if active_flag is None:
                body = {
                    'transaction_id': uuid.uuid4().hex,
                    'result_code': ResultCodes.FAIL.value,
                }
                context.status_code = HTTPStatus.BAD_REQUEST
                return json_dump(body)
            target.active_flag = active_flag

        if 'application_metadata' in request.json():
            if request.json()['application_metadata'] is None:
                body = {
                    'transaction_id': uuid.uuid4().hex,
                    'result_code': ResultCodes.FAIL.value,
                }
                context.status_code = HTTPStatus.BAD_REQUEST
                return json_dump(body)
            application_metadata = request.json()['application_metadata']
            target.application_metadata = application_metadata

        if 'name' in request.json():
            name = request.json()['name']
            other_targets = set(database.targets) - set([target])
            if any(
                other.name == name
                for other in other_targets
                if not other.delete_date
            ):
                context.status_code = HTTPStatus.FORBIDDEN
                body = {
                    'transaction_id': uuid.uuid4().hex,
                    'result_code': ResultCodes.TARGET_NAME_EXIST.value,
                }
                return json_dump(body)
            target.name = name

        if 'image' in request.json():
            image = request.json()['image']
            decoded = base64.b64decode(image)
            image_file = io.BytesIO(decoded)
            target.image = image_file

        # In the real implementation, the tracking rating can stay the same.
        # However, for demonstration purposes, the tracking rating changes but
        # when the target is updated.
        available_values = list(set(range(6)) - set([target.tracking_rating]))
        target.processed_tracking_rating = random.choice(available_values)

        gmt = ZoneInfo('GMT')
        now = datetime.datetime.now(tz=gmt)
        target.last_modified_date = now

        body = {
            'result_code': ResultCodes.SUCCESS.value,
            'transaction_id': uuid.uuid4().hex,
        }
        return json_dump(body)
コード例 #23
0
    def add_target(
        self,
        request: _RequestObjectProxy,
        context: _Context,
    ) -> str:
        """
        Add a target.

        Fake implementation of
        https://library.vuforia.com/articles/Solution/How-To-Use-the-Vuforia-Web-Services-API.html#How-To-Add-a-Target
        """
        try:
            run_services_validators(
                request_headers=request.headers,
                request_body=request.body,
                request_method=request.method,
                request_path=request.path,
                databases=self._target_manager.databases,
            )
        except ValidatorException as exc:
            context.headers = exc.headers
            context.status_code = exc.status_code
            return exc.response_text

        database = get_database_matching_server_keys(
            request_headers=request.headers,
            request_body=request.body,
            request_method=request.method,
            request_path=request.path,
            databases=self._target_manager.databases,
        )

        assert isinstance(database, VuforiaDatabase)

        given_active_flag = request.json().get('active_flag')
        active_flag = {
            None: True,
            True: True,
            False: False,
        }[given_active_flag]

        application_metadata = request.json().get('application_metadata')

        new_target = Target(
            name=request.json()['name'],
            width=request.json()['width'],
            image_value=base64.b64decode(request.json()['image']),
            active_flag=active_flag,
            processing_time_seconds=self._processing_time_seconds,
            application_metadata=application_metadata,
        )
        database.targets.add(new_target)

        date = email.utils.formatdate(None, localtime=False, usegmt=True)
        context.status_code = HTTPStatus.CREATED
        body = {
            'transaction_id': uuid.uuid4().hex,
            'result_code': ResultCodes.TARGET_CREATED.value,
            'target_id': new_target.target_id,
        }
        body_json = json_dump(body)
        context.headers = {
            'Connection': 'keep-alive',
            'Content-Type': 'application/json',
            'Server': 'nginx',
            'Date': date,
            'Content-Length': str(len(body_json)),
        }
        return body_json
コード例 #24
0
def update_target(target_id: str) -> Response:
    """
    Update a target.

    Fake implementation of
    https://library.vuforia.com/articles/Solution/How-To-Use-the-Vuforia-Web-Services-API.html#How-To-Update-a-Target
    """
    # We do not use ``request.get_json(force=True)`` because this only works
    # when the content type is given as ``application/json``.
    request_json = json.loads(request.data)
    databases = get_all_databases()
    database = get_database_matching_server_keys(
        request_headers=dict(request.headers),
        request_body=request.data,
        request_method=request.method,
        request_path=request.path,
        databases=databases,
    )

    assert isinstance(database, VuforiaDatabase)
    [target] = [
        target for target in database.targets if target.target_id == target_id
    ]

    if target.status != TargetStatuses.SUCCESS.value:
        raise TargetStatusNotSuccess

    update_values = {}
    if 'width' in request_json:
        update_values['width'] = request_json['width']

    if 'active_flag' in request_json:
        active_flag = request_json['active_flag']
        if active_flag is None:
            raise Fail(status_code=HTTPStatus.BAD_REQUEST)
        update_values['active_flag'] = active_flag

    if 'application_metadata' in request_json:
        application_metadata = request_json['application_metadata']
        if application_metadata is None:
            raise Fail(status_code=HTTPStatus.BAD_REQUEST)
        update_values['application_metadata'] = application_metadata

    if 'name' in request_json:
        name = request_json['name']
        update_values['name'] = name

    if 'image' in request_json:
        image = request_json['image']
        update_values['image'] = image

    target_manager_base_url = os.environ['TARGET_MANAGER_BASE_URL']
    put_url = (
        f'{target_manager_base_url}/databases/{database.database_name}/'
        f'targets/{target_id}'
    )
    requests.put(url=put_url, json=update_values)

    date = email.utils.formatdate(None, localtime=False, usegmt=True)
    headers = {
        'Connection': 'keep-alive',
        'Content-Type': 'application/json',
        'Server': 'nginx',
        'Date': date,
    }
    body = {
        'result_code': ResultCodes.SUCCESS.value,
        'transaction_id': uuid.uuid4().hex,
    }
    return Response(
        status=HTTPStatus.OK,
        response=json_dump(body),
        headers=headers,
    )
コード例 #25
0
    def database_summary(
        self,
        request: _RequestObjectProxy,
        context: _Context,
    ) -> str:
        """
        Get a database summary report.

        Fake implementation of
        https://library.vuforia.com/articles/Solution/How-To-Use-the-Vuforia-Web-Services-API.html#How-To-Get-a-Database-Summary-Report
        """
        try:
            run_services_validators(
                request_headers=request.headers,
                request_body=request.body,
                request_method=request.method,
                request_path=request.path,
                databases=self._target_manager.databases,
            )
        except ValidatorException as exc:
            context.headers = exc.headers
            context.status_code = exc.status_code
            return exc.response_text

        body: Dict[str, str | int] = {}

        database = get_database_matching_server_keys(
            request_headers=request.headers,
            request_body=request.body,
            request_method=request.method,
            request_path=request.path,
            databases=self._target_manager.databases,
        )

        assert isinstance(database, VuforiaDatabase)
        date = email.utils.formatdate(None, localtime=False, usegmt=True)
        body = {
            'result_code': ResultCodes.SUCCESS.value,
            'transaction_id': uuid.uuid4().hex,
            'name': database.database_name,
            'active_images': len(database.active_targets),
            'inactive_images': len(database.inactive_targets),
            'failed_images': len(database.failed_targets),
            'target_quota': database.target_quota,
            'total_recos': database.total_recos,
            'current_month_recos': database.current_month_recos,
            'previous_month_recos': database.previous_month_recos,
            'processing_images': len(database.processing_targets),
            'reco_threshold': database.reco_threshold,
            'request_quota': database.request_quota,
            'request_usage': 0,
        }
        body_json = json_dump(body)
        context.headers = {
            'Connection': 'keep-alive',
            'Content-Type': 'application/json',
            'Server': 'nginx',
            'Date': date,
            'Content-Length': str(len(body_json)),
        }
        return body_json