Skip to Content

I am playing a little bit with Google App Engine (GAE) and as first thing I tried to integrate OpenUI5 in a demo app.

My app is just showing a list of projects and let the user to create a new project.

Here a screen:

Screen Shot 2014-08-01 at 12.54.25.png

Detailed info for Google App Engine SDK installation can be found in the official documentation:

Download the Google App Engine SDK – Google App Engine — Google Developers

I also used PyDev eclipse plugin as IDE.

For OpenUI5 SDK, you can download it from here (I used version 1.22.4):

OpenUI5 – Download

On App Engine side, my application is built on three main python modules:

models/project.py –> it is the model; it creates one Datastore entity – Projects – with two characteristics: project_id and project_description and it implements three functions:

  1. get_projects: returns all created projects
  2. get_project: returns one single project
  3. put_project: creates a new project

from google.appengine.ext import db
class Projects(db.Model):
    project_id = db.StringProperty(required=True, )
    project_description = db.StringProperty(required=True)
def get_projects():
    list_of_projects = []
    q = db.GqlQuery("SELECT * FROM Projects")
    for p in q.run():
        current_project = { 'project_id' : p.project_id, 'project_description' : p.project_description}
        list_of_projects.append(current_project)
    return list_of_projects
def get_project(project_id=None):
    if not project_id:
        return None
    key = db.Key.from_path('Projects', project_id)
    project = db.get(key)
    if not project:
        return None
    return project
def put_project(project_id, project_description):
    query = Projects.all(keys_only=True).filter('project_id', project_id)
    entity = query.get()
    if entity:
        raise Exception('unique_property must have a unique value!')
    project = Projects(project_id=project_id, project_description=project_description)
    project.put()

main.py –> Is the main request handler for the GAE application (MainPage class is the handler)


import datetime
import jinja2
import os
import webapp2
from google.appengine.api import users
template_env = jinja2.Environment(
  loader=jinja2.FileSystemLoader(os.getcwd()))
class MainPage(webapp2.RequestHandler):
    def get(self):
        current_time = datetime.datetime.now()
        current_user = users.get_current_user()
        login_url = users.create_login_url(self.request.path)
        logout_url = users.create_logout_url(self.request.path)
        template = template_env.get_template('templates/index.html')
        context = {
                  'current_time' : current_time,
                  'current_user' : current_user,
                  'login_url' : login_url,
                  'logout_url' : logout_url,
                  }
        self.response.out.write(template.render(context))
application = webapp2.WSGIApplication([('/', MainPage)],
                                      debug=True)

projects_handler.py –> is the handler for a POST request to create a new project and a GET request to get all projects in a JSON format (I haven’t found a good solution to espose the data via odata in python, some comments here would be really appreciated)


import webapp2
import json
from models import projects
class PostProject(webapp2.RequestHandler):
    def post(self):
        try:
            project_id = self.request.get('project_id')
            project_description = self.request.get('project_description')
            projects.put_project(project_id, project_description)
        except:
            self.response.set_status(500)
            return
        self.response.set_status(200)
   
class GetProjects(webapp2.RequestHandler):
    def get(self):
        self.response.headers['Content-Type'] = 'application/json'
        obj = projects.get_projects()
        self.response.out.write(json.dumps(obj))
application = webapp2.WSGIApplication([('/post_project', PostProject)],
                                      debug=True)
application_get_projects = webapp2.WSGIApplication([('/get_projects', GetProjects)],
                                      debug=True)

app.yaml is the GAE configuration file in python, I defined 4 static handlers for directories and three script handlers for the http requests (one for main page GET, one for GET the list of projects as Json file, one for POST a new project):


application: com-oloconsulting-damien
version: 1
runtime: python27
api_version: 1
threadsafe: true
handlers:
- url: /css
  static_dir: css
- url: /js
  static_dir: js
- url: /openui5
  static_dir: openui5-runtime-1.22.4
- url: /ui
  static_dir: ui
- url: /post_project
  script: projects_handler.application
- url: /get_projects
  script: projects_handler.application_get_projects
- url: .*
  script: main.application
libraries:
- name: webapp2
  version: "2.5.1"
- name: jinja2
  version: latest
- name: markupsafe
  version: latest

Basically the app is working in this way: first page is managed by main.py, POST and GET requests on Projects model are managed by module projects_handler.py.

From OpenUI5 side, I created two views and put them in the same page:

ProjectList view (it implements a table for the list of projects):


sap.ui.jsview('ui.ProjectList', {
  getControllerName : function() {
  return 'ui.ProjectList';
  },
  createContent : function(oController) {
  var oTable = new sap.ui.table.Table({editable:false});
  var oControl = new sap.ui.commons.TextView({text: '{project_id}'});
  oTable.addColumn(new sap.ui.table.Column({
  label: new sap.ui.commons.Label({text: oBundle.getText('ProjectId')}),
  template: oControl, sortProperty: 'project_id',
  filterProperty: 'project_id', width: '50px'}));
  var oControl = new sap.ui.commons.TextView({text: '{project_description}'});
  oTable.addColumn(new sap.ui.table.Column({
  label: new sap.ui.commons.Label({text: oBundle.getText('ProjectDescription')}),
  template: oControl, sortProperty: 'project_description',
  filterProperty: 'project_description', width: '200px'}));
  var aData = oController.getProjects();
  var oModel = new sap.ui.model.json.JSONModel();
  oModel.setData({modelData: aData});
  oTable.setModel(oModel);
  oTable.bindRows('/modelData');
  oTable.sort(oTable.getColumns()[0]);
  return oTable;
  }
});

The controller is implementing only one function to get the list of the projects (it is called in the view to fill the model data: var aData = oController.getProjects();)


getProjects: function() {
  var aUrl = '/get_projects';
  var aData = [];
  jQuery.ajax({
  url: aUrl,
  async: false,
  type: 'GET',
  success: function(data, textStatus, jqXHR) {
  //alert('success to post');
  aData = data;
  },
  error: function(jqXHR, textStatus, errorThrown) {
  alert('fail to post');
  }
  });
  return aData;
  }

ProjectCreation view (it defines a form with a couple of textFields and a button):


sap.ui.jsview('ui.ProjectCreation', {
  getControllerName : function() {
  return 'ui.ProjectCreation';
  },
  createContent : function(oController) {
  var oLayout = new sap.ui.layout.form.GridLayout('ProjectCreationFormLayout');
  var oForm = new sap.ui.layout.form.Form('ProjectCreationForm',{
  title: new sap.ui.core.Title({
  text: oBundle.getText('CreateProject')
  }),
  width: '50%',
  layout: oLayout,
  formContainers: [
                  new sap.ui.layout.form.FormContainer('ProjectCreationFC', {
                  formElements: [
                                  new sap.ui.layout.form.FormElement({
                                  fields: [
                                          new sap.ui.commons.Label('lblProjectId', {
                                          text: oBundle.getText('ProjectId')
                                          }),
                                          new sap.ui.commons.TextField('txtProjectId')
                                          ]
                                  }),
                                  new sap.ui.layout.form.FormElement({
                                  fields: [
                                          new sap.ui.commons.Label('lblProjectDescription', {
                                          text: oBundle.getText('ProjectDescription')
                                          }),
                                          new sap.ui.commons.TextField('txtProjectDescription')
                                          ]
                                  }),
                                  new sap.ui.layout.form.FormElement({
                                  fields: [
                                          new sap.ui.commons.Button('ProjectCreationButton', {
                                          text: 'Insert',
                                          tooltip: oBundle.getText('CreateProject'),
                                          press: function(oEvent){
                                                oController.onCreateButtonPress(oEvent,oController);
                                                }
                                          })
                                          ]
                                  })
                                ]
                  })
                  ]
  });
  return oForm;
  }
});

The controller is implementing the function for inserting a new project:


onCreateButtonPress: function(oEvent, oController) {
  var oProjectId = sap.ui.getCore().byId('txtProjectId');
  var oProjectDescription = sap.ui.getCore().byId('txtProjectDescription');
  var aUrl = '/post_project';
  var formData = {
      project_id: oProjectId.getValue(),
      project_description: oProjectDescription.getValue()
  };
  jQuery.ajax({
      url: aUrl,
      type: 'POST',
      data: formData,
      success: function(data, textStatus, jqXHR) {
            alert(oBundle.getText('ProjectCreationOk'));
            location.reload();
      },
      error: function(jqXHR, textStatus, errorThrown) {
            alert(oBundle.getText('ProjectCreationError'));
      }
  });
}

You can test the application at this link:

http://com-oloconsulting-damien.appspot.com/

here it is a snapshot of the GAE datastore after a couple of projects creation:

Screen Shot 2014-08-01 at 12.50.20.png

To report this post you need to login first.

Be the first to leave a comment

You must be Logged on to comment or reply to a post.

Leave a Reply