Skip to Content
Technical Articles

Post image file from SAPUI5 to flask app on CF

Hi All,

I am writing this blog to describe how to develop SAPUI5 and Flask app on Cloud Foundry.

Basically it it difficult to process image data with javascript, so I used python for image processing.

If you don’t know how to deploy application to Cloud Foundry, see another article “Create simple Flask REST API using Cloud Foundry”.

If you want to know more about logging from python on Cloud Foundry, see another article “Output logs from Python Flask application deployed on Cloud Foundry”.

How my program works

1. Open SAPUI5

Open SAPUI5 app with chrome extension “Allow-Control-Allow-Origin”.  I somehow open “extended_runnable_file.html” from Web IDE test and get error.  When opened url path is “extended_runnable_file.html”, then change it to “index.html”.

Click on camera Icon.

2. Select an image file

Select an image file to pass to Flask application.

3. See returned result

Returned result is displayed as an alert screen.

Programs

Flask app on Cloud Foundry

Application is on my GitHub Repository “cloudfoundry-python-flask-image”.

Environment

  • Region: CF Trial (Europe – Frankfurt)
  • Python Buildpack version: 1.6.20
  • Python Version: 3.5.5
  • Used Python Libraries: Flask, pillow, numpy, sap_cf_logging

Python Application(procImage.py)

I used pillow library for image processing.  Received image data via POST method is resized using “thumnail” function.  And I change data format using numpy library.

from flask import Flask, jsonify, request, make_response
from PIL import Image
import numpy as np
import logging, math, os
from sap.cf_logging import flask_logging

app = Flask(__name__)

#Iitialize logging
flask_logging.init(app, logging.INFO)

cf_port = os.getenv('PORT')

# Only get method by default
@app.route('/', methods=["GET", "POST"])
def hello():
    logger = logging.getLogger('my.logger')

    logger.info(request.files)

    image = Image.open(request.files['sampleImage'].stream)
    logger.info(image)

    #Calculate resize ratio
    ratio = math.sqrt(image.width * image.height / 400)

    #If need to make image file smaller
    if ratio > 1:
        image.thumbnail((int(image.width / ratio), int(image.height / ratio)))

    logger.info(image)

    (im_width, im_height) = image.size

    #Change file format for general TensorFlow format
    image_np = np.array(image.getdata()).reshape((im_height, im_width, 3)).astype(np.uint8)
    image_list = image_np.tolist()
    return make_response(jsonify(image_list))

if __name__ == '__main__':
    if cf_port is None:
        app.run(host='0.0.0.0', port=5000, debug=True)
    else:
        app.run(host='0.0.0.0', port=int(cf_port), debug=True)

 

SAPUI5 app developed via Web IDE full-stack

The program is on my GitHub repository “YoheiFukuhara/post-image-from-sapui5-to-flask”.

Environment

  • SAPUI5 version: 1.60.1
  • IDE: Web IDE full-stack on SAP Cloud Platform

Main View(post.view.xml)

Here FileUploader’s attribute is “https://<url>”, so it fails with CORS basically.  It is very easy to avoid CORS by configuring Destination.  Why I don’t use “Destination”is just I want to make the app simpler.  I avoid CORS error by using chrome extension “Allow-Control-Allow-Origin”.

An attribute “name” is so important, since the name “sampleImage” is used in Flask.

<mvc:View controllerName="test.post-image-to-flask.controller.post" xmlns:html="http://www.w3.org/1999/xhtml" xmlns:mvc="sap.ui.core.mvc"
	displayBlock="true" xmlns:unified="sap.ui.unified" xmlns="sap.m">
	<App id="idAppControl">
		<pages>
			<Page title="Post image file to Flask application on Cloud Foundry">
				<content>
					<unified:FileUploader name="sampleImage" uploadUrl="https://flask-image-patient-lynx.cfapps.eu10.hana.ondemand.com/" buttonOnly="true" icon="sap-icon://camera" iconOnly="true"
						sameFilenameAllowed="true" fileType="png,jpeg,jpg,bmp,tiff,tif" mimeType="image/png,image/jpg,image/jpeg,image/bmp,image/tiff"
						uploadComplete="fileUploadComplete" uploadOnChange="true" sendXHR="true"/>
				</content>
			</Page>
		</pages>
	</App>
</mvc:View>

Main Controller(post.controller.js)

Function is called when POST request is completed.

/*eslint-disable no-console, no-alert, */
sap.ui.define([
	"sap/ui/core/mvc/Controller"
], function (Controller) {
	"use strict";
	return Controller.extend("test.post-image-to-flask.controller.post", {
		fileUploadComplete: function (oControlEvent) {
			console.log("response from CF flask API:", oControlEvent.getParameters().responseRaw);
			alert(oControlEvent.getParameters().responseRaw);
		}
	});
});

Conclusion

This is very common way to process image.  I hope it makes your development easier.

Be the first to leave a comment
You must be Logged on to comment or reply to a post.