def handle_annotation()

in src/gcf/main.py [0:0]


def handle_annotation(request):
    """Executes online image annotations.

    Handles GET and POST methods.
    The form in POST method can have image as URI  in the <image_uri> variable
    or base64 encoded image in <image> form variable.
    Optional variable is <features> which overrides a list of
    vision.Feature.Type(s) defined in the environment variable "FEATURES".

    In GET method the image is referenced by the URI in the <image_uri> variable.
    Optional variable is <features> which overrides a list of
    vision.Feature.Type(s) defined in the environment variable "FEATURES".
    Due to the request size limit, GET method can't submit the image.
    """

    features_env = os.environ.get(FEATURES_ENV, None)
    image_uri = None
    image_bin = None
    features_http = None
    # read variables from POST or GET request
    if request.method == "POST":
        content = request.form or request.json
        logging.info("Received content in POST: content=%s" % content)
        features_http = content.get("features")
        image_uri = content.get("image_uri")
        image_b64 = content.get("image")
        if image_b64:
            logging.debug("image_b64 size=%s" % len(image_b64))
            image_bin = image_b64.encode()
            logging.debug("Image size=%s" % len(image_bin))
            logging.info("Converted base64 encoded image from the form.")
        if image_bin is None and request.files and "image" in request.files:
            logging.info(
                "Reading image from attached file %s" % request.files["image"].filename
            )
            file_object = request.files.get("image")
            image_bin = file_object.read()
            logging.debug("image_bin size=%s" % len(image_bin))
    elif request.method == "GET":
        logging.info(
            "Received form in GET path=%s, args=%s" % (request.path, request.args)
        )
        image_uri = request.args.get("image_uri", None)
        features_http = request.args.get("features")
        if not image_uri:  # check if URI is encoded in the path
            path_items = request.path.split("?")  # separate args
            path_items = path_items[0].split("/", 2)
            if len(path_items) >= 3:
                image_uri = path_items[2]
    else:
        return make_response("Not supported", 501)
    # is image input p[resent?
    if image_uri is None and image_bin is None:
        return make_response("No image data", 412)
    # build a list of requested annotation features form environment variable
    features_list = []
    if features_env:
        logging.info("Env. features: %s", features_env)
        features_list = build_features_list(features_env)
    # override annotation features with the ones from the request if provided
    if features_http:
        if isinstance(features_http, list):
            features_http = ','.join(features_http)
        logging.info("Request features: %s", features_http)
        features_list = build_features_list(features_http)
    logging.info("Annotating for features: %s", features_list)
    result = None
    # call Vision image annotation API
    if image_uri:
        logging.info(f"Annotating image from URI {image_uri}")
        result = annotate_image_uri(image_uri, features_list)
    else:
        logging.info("Annotating uploaded image.")
        vision_image = vision.Image(content=image_bin)
        result = annotate_image(vision_image, features_list)
    if result:
        if result.find('"error"') > 0 and result.find('"code":') > 0:
            logging.error("Vision API returned error, check JSON result for details.")
            return make_response(result, 412)  # Vision API returned JSON with an error
        logging.info("Returning annotation result as JSON.")
        return make_response(result, 200)
    logging.error("Annotation result is None.")
    return make_response("Annotation result is None.", 500)