Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
Fukuhara
Advisor
Advisor
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.