Esempio n. 1
0
        def batch_file_classify(image_file):
            try:
                files = []
                total_batch_size = 0
                for file in image_file:
                    file_obj = self.filereader.get_file(file)
                    file_size = os.fstat(file_obj.fileno()).st_size

                    if file_size > MAX_LOCAL_IMAGE_SIZE:
                        raise error.InvalidQueryError(
                            message=
                            'File %s is larger than the limit of %d megabytes'
                            % (file_obj.name,
                               self.bytes_to_mb(MAX_LOCAL_IMAGE_BATCH_SIZE)))

                    files.append(('file', file_obj))
                    total_batch_size += file_size

                if total_batch_size > MAX_LOCAL_IMAGE_BATCH_SIZE:
                    raise error.InvalidQueryError(
                        message='Max batch upload size is %d megabytes.' %
                        (self.bytes_to_mb(MAX_LOCAL_IMAGE_BATCH_SIZE)))

                return requests.request(
                    method, endpoint, **{
                        'headers': headers,
                        'files': files,
                        'data': data
                    })
            finally:
                for file_tuple in files:
                    (key, file) = file_tuple
                    file.close()
Esempio n. 2
0
    def classify_video(self, detector_id, video_url=None, video_file=None):
        """
    Classify a video from a url with a detector

    detector_id: a unique id for the detector
    video_url: internet URL for the video to classify
    """

        MAX_LOCAL_VIDEO_SIZE = 300 * 1024 * 1024

        (endpoint, method) = self.endpoints['classify_video']

        if not video_url and not video_file:
            raise error.InvalidQueryError(
                message='Missing required parameter: video_url or video_file')

        if video_url and video_file:
            raise error.InvalidQueryError(
                message=
                'Cannot classify a URL and local file in the same request')

        if isinstance(video_file, list):
            raise error.InvalidQueryError(
                message='Only one video can be uploaded at a time')

        endpoint = endpoint.replace(':key', detector_id)

        try:
            headers = {'Authorization': self.token.authorization_header()}
            data = {'detector_id': detector_id}
            if video_url:
                data['url'] = video_url
                return requests.request(method, endpoint, **{
                    'headers': headers,
                    'data': data
                })
            elif video_file:
                with self.filereader.get_file(video_file) as file_to_upload:
                    files = {'file': file_to_upload}
                    file_size = os.fstat(file_to_upload.fileno()).st_size

                    if file_size > MAX_LOCAL_VIDEO_SIZE:
                        raise error.InvalidQueryError(
                            message=
                            'File %s is larger than the limit of %d megabytes'
                            % (file_to_upload.name,
                               self.bytes_to_mb(MAX_LOCAL_VIDEO_SIZE)))

                    return requests.request(
                        method, endpoint, **{
                            'headers': headers,
                            'files': files,
                            'data': data
                        })
        except error.InvalidQueryError as e:
            raise e
        except Exception as e:
            raise error.APIConnectionError(message=e)
Esempio n. 3
0
def classify_video(self, detectorId, url=None, file=None, **options):
    """
  Classify a video from a url with a detector

  detectorId: a unique id for the detector
  url: internet URL for the video to classify
  """

    MAX_LOCAL_VIDEO_SIZE = 300 * 1024 * 1024

    (endpoint, method) = self.endpoints["classify_video"]

    if not url and not file:
        raise error.InvalidQueryError(message="Missing required parameter: url or file")

    if url and file:
        raise error.InvalidQueryError(
            message="Cannot classify a URL and local file in the same request"
        )

    if isinstance(file, list):
        raise error.InvalidQueryError(
            message="Only one video can be uploaded at a time"
        )

    endpoint = endpoint.replace(":key", detectorId)

    try:
        headers = {"Authorization": self.token.authorization_header()}
        data = {"detectorId": detectorId}
        data.update(options)

        if url:
            data["url"] = url
            return requests.request(
                method, endpoint, **{"headers": headers, "data": data}
            )
        elif file:
            with self.filereader.get_file(file) as file_to_upload:
                files = {"file": file_to_upload}
                file_size = os.fstat(file_to_upload.fileno()).st_size

                if file_size > MAX_LOCAL_VIDEO_SIZE:
                    raise error.InvalidQueryError(
                        message="File %s is larger than the limit of %d megabytes"
                        % (file_to_upload.name, self.bytes_to_mb(MAX_LOCAL_VIDEO_SIZE))
                    )

                return requests.request(
                    method,
                    endpoint,
                    **{"headers": headers, "files": files, "data": data},
                )
    except error.InvalidQueryError as e:
        raise e
    except Exception as e:
        raise error.APIConnectionError(message=e)
Esempio n. 4
0
def batch_file_request(uploaded_files,
                       method,
                       endpoint,
                       headers,
                       data,
                       file_keyword="file"):
    # pylint: disable = no-value-for-parameter
    filereader = FileReader()

    try:
        files = []
        total_batch_size = 0
        for file in uploaded_files:
            file_obj = filereader.get_file(file)
            file_size = check_file_size(file_obj)

            files.append((file_keyword, file_obj))
            total_batch_size += file_size

        if total_batch_size > MAX_LOCAL_IMAGE_BATCH_SIZE:
            raise error.InvalidQueryError(
                message="Max batch upload size is %d megabytes." %
                (bytes_to_mb(MAX_LOCAL_IMAGE_BATCH_SIZE)))

        return requests.request(
            method, endpoint, **{
                "headers": headers,
                "files": files,
                "data": data
            })
    finally:
        for file_tuple in files:
            (key, file) = file_tuple
            file.close()
Esempio n. 5
0
    def create_detector(self, zip_file, name, detector_type):
        """
    Create a new detector with the contents of the zip file

    detector_type: general, facial_recognition, or facial_characteristics
    name: the detector's display name
    zip_file: a zip file containing the images to be used in the detector creation
              the root folder should contain only directories which will become the labels for detection
              each of these directories should contain only images corresponding to that label.

              However, there is an exception if you want to add negative examples to a label.
              In that case, put the negative images for the label in a folder called "negative" inside the corresponding label.

              To include bounding boxes, include one file called bbox.csv in the top level directory.
              Each line of this file should be formatted as follows:
                0.25, 0.3, 0.75, 0.8, cat, positive, image.jpg
                0.25, 0.4, 0.55, 0.7, dog, positive, picture.jpg
                0.0, 0.1, 0.2, 0.3, cat, negative, raccoon.jpg

              Column definitions:
                top left X coordinate, top left Y coordinate, bottom right X coordinate, bottom right Y coordinate, label, positive or negative example, file name

              Max 300 MB zip file upload

      structure example:
        cat/
          garfield.jpg
          nermal.png
        dog/
          odie.TIFF
          negative/
            lobo.jpg
        bbox.csv
    """
        MAX_LOCAL_ZIP_SIZE = 300 * 1024 * 1024

        (endpoint, method) = self.endpoints['create_detector']

        try:
            headers = {'Authorization': self.token.authorization_header()}
            data = {'name': name, 'detector_type': detector_type}
            with self.filereader.get_file(zip_file) as file_to_upload:
                files = {'file': file_to_upload}
                file_size = os.fstat(file_to_upload.fileno()).st_size

                if file_size > MAX_LOCAL_ZIP_SIZE:
                    raise error.InvalidQueryError(
                        message=
                        'File %s is larger than the limit of %d megabytes' %
                        (file_to_upload.name,
                         self.bytes_to_mb(MAX_LOCAL_ZIP_SIZE)))

                return requests.request(
                    method, endpoint, **{
                        'headers': headers,
                        'files': files,
                        'data': data
                    })
        except Exception as e:
            raise error.APIConnectionError(message=e)
Esempio n. 6
0
def get_annotations(self, **options):
    """Get annotations. Requires processing=false. Note: you need to provide at least one of the three ids to query"""
    (endpoint, method) = self.endpoints["get_annotations"]

    detector_id = options.get("detectorId")
    label_ids = options.get("labelIds")
    image_id = options.get("imageId")

    if not detector_id and not label_ids and not image_id:
        raise error.InvalidQueryError(
            message=
            "Missing required parameter: detectorId, labelIds or imageId")

    try:
        headers = {"Authorization": self.token.authorization_header()}
        params = {
            "detectorId": detector_id,
            "labelIds": label_ids,
            "imageId": image_id,
        }
        return requests.request(method, endpoint, **{
            "headers": headers,
            "params": params
        })
    except Exception as e:
        raise error.APIConnectionError(message=e)
Esempio n. 7
0
def import_detector(self, name, **options):
    """
  Note: certain combination of parameters can be supplied: file_detector, file_proto + file_label (+ file_label_ind), or file_proto + labels (+ label_inds). Parentheses part can be optionally supplied for object detection.
  """
    (endpoint, method) = self.endpoints["import_detector"]

    data = {
        "name": name,
    }

    def get_data_info():
        data["inputTensor"] = (options.get("inputTensor"), )
        data["outputTensor"] = (options.get("outputTensor"), )
        data["detectorType"] = (options.get("detectorType"), )

    if options.get("fileDetector"):
        file_paths = {"fileDetector": options.get("fileDetector")}
    elif options.get("fileProto") and options.get("fileLabel"):
        file_paths = {
            "fileProto": options.get("fileProto"),
            "fileLabel": options.get("fileLabel"),
            "fileLabelInd": options.get("fileLabelInd"),
        }
        get_data_info()
    elif options.get("fileProto") and options.get("labels"):
        file_paths = {
            "fileProto": options.get("fileProto"),
        }
        data["labels"] = options.get("labels")
        data["labelInds"] = options.get("labelInds")
        get_data_info()
    else:
        raise error.InvalidQueryError(message="Invalid parameter combination")

    file_objs = {}
    for file_keyword, file_path in file_paths.items():
        file_obj = self.filereader.get_file(file_path)
        file_objs[file_keyword] = file_obj

    try:
        headers = {"Authorization": self.token.authorization_header()}
        return requests.request(
            method, endpoint, **{
                "headers": headers,
                "files": file_objs,
                "data": data
            })
    except IOError as e:
        raise e
    except error.InvalidQueryError as e:
        raise e
    except Exception as e:
        raise error.APIConnectionError(message=e)
    finally:
        for file_keyword, file_obj in file_objs.items():
            if isinstance(file_obj, io.IOBase):
                file_obj.close()
Esempio n. 8
0
def add_feedback(self, detectorId, feedback, file=None, url=None):
    """
  Add feedback to a detector using a local file or image URL
  """
    (endpoint, method) = self.endpoints["add_feedback"]
    endpoint = endpoint.replace(":detector_id", detectorId)

    if not url and not file:
        raise error.InvalidQueryError(
            message="Missing required parameter: file or URL")

    if url and file:
        raise error.InvalidQueryError(
            message="You may only specify a file or a URL, not both")

    data = {"feedback": format_feedback(feedback)}

    image_file = None
    files = None

    try:
        if url:
            data["url"] = url
        else:
            image_file = self.filereader.get_file(file)
            files = {"file": image_file}

        headers = {"Authorization": self.token.authorization_header()}
        return requests.request(
            method, endpoint, **{
                "headers": headers,
                "files": files,
                "data": data
            })
    except IOError as e:
        raise e
    except error.InvalidQueryError as e:
        raise e
    except Exception as e:
        raise error.APIConnectionError(message=e)
    finally:
        if isinstance(image_file, io.IOBase):
            image_file.close()
Esempio n. 9
0
def check_file_size(file):
    # pylint: disable = no-value-for-parameter
    file_size = os.fstat(file.fileno()).st_size

    if file_size > MAX_LOCAL_IMAGE_SIZE:
        raise error.InvalidQueryError(
            message="File %s is larger than the limit of %d megabytes" %
            (file.name, bytes_to_mb(MAX_LOCAL_IMAGE_SIZE)))

    return file_size
Esempio n. 10
0
def query_collection_by_image(self, taskId, url=None, file=None, **options):
    """
  Query against a collection index (CollectionManagerTask) using an image as key.
  Takes in an image file or url and returns similar media from the collection.
  """
    (endpoint, method) = self.endpoints["query_collection_by_image"]
    endpoint = endpoint.replace(":key", taskId)

    if not file and not url:
        raise error.InvalidQueryError(
            message="Missing required parameter: file or url")

    try:
        file_to_upload = None
        headers = {"Authorization": self.token.authorization_header()}
        data = {
            "boundingBox": json.dumps(options.get("boundingBox")),
            "numResults": options.get("num_results"),
        }

        if file:
            file_to_upload = self.filereader.get_file(file)
            files = {"file": file_to_upload}
            return requests.request(
                method, endpoint, **{
                    "headers": headers,
                    "files": files,
                    "data": data
                })
        else:
            data["url"] = url
            return requests.request(method, endpoint, **{
                "headers": headers,
                "data": data
            })
    except IOError as e:
        raise e
    except error.InvalidQueryError as e:
        raise e
    except Exception as e:
        raise error.APIConnectionError(message=e)
    finally:
        if file_to_upload:
            file_to_upload.close()
Esempio n. 11
0
def classify_image(self, detectorId, file=None, url=None, **options):
    """
  Classify an image with a detector

  detectorId: a unique id for the detector
  file: path to local image file to classify
  url: internet URL for the image to classify
  """

    (endpoint, method) = self.endpoints["classify_image"]

    if not url and not file:
        raise error.InvalidQueryError(
            message="Missing required parameter: file or url")

    endpoint = endpoint.replace(":key", detectorId)

    try:
        headers = {"Authorization": self.token.authorization_header()}
        data = {"detectorId": detectorId}
        data.update(options)

        if url:
            data["url"] = url
        if file:
            if not isinstance(file, list):
                file = [file]

            return batch_file_request(file, method, endpoint, headers, data)
        else:
            return requests.request(method, endpoint, **{
                "headers": headers,
                "data": data
            })
    except IOError as e:
        raise e
    except error.InvalidQueryError as e:
        raise e
    except Exception as e:
        raise error.APIConnectionError(message=e)
Esempio n. 12
0
def localize_image(self, localizer, localizerLabel, **options):
    """
  Note: this API is very similar to Images/Classify;
  however, it can be used to update bounding boxes of existing training images
  by supplying update=true, labelId, and one of imageId or imageIds, and it has
  access to the internal face localizer
  (localizer="DEFAULT_FACE" and localizerLabel="face").
  """
    (endpoint, method) = self.endpoints["localize_image"]

    data = {
        "localizer": localizer,
        "localizerLabel": localizerLabel,
    }

    update = options.get("update")

    if update:
        image_id = options.get("imageId")
        image_ids = options.get("imageIds")

        if not image_id and not image_ids:
            raise error.InvalidQueryError(
                message=
                "Missing required parameter for update: imageId or imageIds")

        if image_id:
            data["imageId"] = image_id
        else:
            data["imageIds"] = image_ids
    else:
        files = options.get("file")
        urls = options.get("url")

        if not files and not urls:
            raise error.InvalidQueryError(
                message="Missing required parameter: files or urls")

        data.update({
            "files": files,
            "urls": urls,
        })

    try:
        headers = {"Authorization": self.token.authorization_header()}

        data.update({
            "confidence": options.get("confidence"),
            "update": "true" if update else "",
            "maxFaces": options.get("maxFaces"),
            "labelId": options.get("labelId"),
        })

        if update:
            return requests.request(method, endpoint, **{
                "headers": headers,
                "data": data
            })

        if files:
            if not isinstance(files, list):
                files = [files]
            return batch_file_request(files, method, endpoint, headers, data)
        else:
            if isinstance(urls, list):
                data["urls"] = urls
            else:
                data["url"] = urls
            return requests.request(method, endpoint, **{
                "headers": headers,
                "data": data
            })
    except IOError as e:
        raise e
    except error.InvalidQueryError as e:
        raise e
    except Exception as e:
        raise error.APIConnectionError(message=e)
Esempio n. 13
0
    def classify_image(self, detector_id, image_file=None, image_url=None):
        """
    Classify an image with a detector

    detector_id: a unique id for the detector
    image_file: path to local image file to classify
    image_url: internet URL for the image to classify
    """

        MAX_LOCAL_IMAGE_SIZE = 50 * 1024 * 1024
        MAX_LOCAL_IMAGE_BATCH_SIZE = 50 * 1024 * 1024

        def batch_file_classify(image_file):
            try:
                files = []
                total_batch_size = 0
                for file in image_file:
                    file_obj = self.filereader.get_file(file)
                    file_size = os.fstat(file_obj.fileno()).st_size

                    if file_size > MAX_LOCAL_IMAGE_SIZE:
                        raise error.InvalidQueryError(
                            message=
                            'File %s is larger than the limit of %d megabytes'
                            % (file_obj.name,
                               self.bytes_to_mb(MAX_LOCAL_IMAGE_BATCH_SIZE)))

                    files.append(('file', file_obj))
                    total_batch_size += file_size

                if total_batch_size > MAX_LOCAL_IMAGE_BATCH_SIZE:
                    raise error.InvalidQueryError(
                        message='Max batch upload size is %d megabytes.' %
                        (self.bytes_to_mb(MAX_LOCAL_IMAGE_BATCH_SIZE)))

                return requests.request(
                    method, endpoint, **{
                        'headers': headers,
                        'files': files,
                        'data': data
                    })
            finally:
                for file_tuple in files:
                    (key, file) = file_tuple
                    file.close()

        (endpoint, method) = self.endpoints['classify_image']

        if not image_url and not image_file:
            raise error.InvalidQueryError(
                message='Missing required parameter: image_file or image_url')

        endpoint = endpoint.replace(':key', detector_id)

        try:
            headers = {'Authorization': self.token.authorization_header()}
            data = {'detector_id': detector_id}
            if image_url:
                data['url'] = image_url
            if image_file:
                if isinstance(image_file, list):
                    return batch_file_classify(image_file)
                else:
                    with self.filereader.get_file(
                            image_file) as file_to_upload:
                        files = {'file': file_to_upload}
                        file_size = os.fstat(file_to_upload.fileno()).st_size

                        if file_size > MAX_LOCAL_IMAGE_SIZE:
                            raise error.InvalidQueryError(
                                message=
                                'File %s is larger than the limit of %d megabytes'
                                % (file_to_upload.name,
                                   self.bytes_to_mb(MAX_LOCAL_IMAGE_SIZE)))

                        return requests.request(
                            method, endpoint, **{
                                'headers': headers,
                                'files': files,
                                'data': data
                            })
            else:
                return requests.request(method, endpoint, **{
                    'headers': headers,
                    'data': data
                })
        except IOError as e:
            raise e
        except error.InvalidQueryError as e:
            raise e
        except Exception as e:
            raise error.APIConnectionError(message=e)