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)