Framework

The Appengine Project Apr 05, 2020
Open the webapplication

The framework is a series of javascript and python modules helping you with the client-server communiction and enabeling you to focus on the application logic.

Javascript (client-side)

HTTP

Import the module:

<script src="/js/framework/HTTP.D2O.js"></script>

With the HTTP module loaded in your index head sectiont the following functionality is available in your javascript modules.

// HTTP.get & HTTP.post

HTTP.get("{procedure.name}/{var_1}/{var_n}",callback,query_parameters)

/* procedure.name = The module name (procedure) that should be triggered server side
 * {var_n} = Path variables or uri variables (Optional)
 * query_parameters = A dictionary that is added to the request url as query_parameters -> https:/uri/uri/?key=value&key2=value2 (Optional)
 * callback = A javascript function that should be triggerd on the response e.g.
 */

query_parameters = {
  'key' : 'value'
}
function callback(data){
  console.log(data);
}

HTTP.post("{procedure.name}/{var_1}/{var_n}",callback,body,query_parameters)
/* Same variables as the get method with the added:
 * body = Data to be send to server (JSON serializable)
 */

STOMP

Wat is STOMP
Import the module:

<script src="/js/framework/STOMP.D2O.js"></script>

With the STOMP module loaded in your index head sectiont the following functionality is available in your javascript modules.

STOMP.connect();
// Connect to D2O STOMP message broker, should be executed only once

STOMP.postconnect = function(){
  console.log("Connected");
}
// Optional, add a function to be executed after the connection is established

STOMP.subscribe('{queueName}',onMessage);
// Subscribe on a queue dedicated for the current user and callback onMessage e.g.
function onMessage(data){
  console.log(data);
}

STOMP.subscribeTopic("{topicName}", onMessage);
// Subscribe on topic (broadcast) and callback onMessage

STOMP.disconect();
// Disconect from d@O STOMP message broker

STOMP.predisconnect = function(){
  console.log();
}
// Optional, add a function to be executed just before the connection is closed by client

STOMP.SEND("{procedure.name}",request);
// procedure.name = The module name (procedure) that should be triggered server side
// Data to be send to server (JSON serializable)

SplashScreen (Bootstrap only)

Adds a splashscreen automatically,  the splashsreen fills the entire page and will disapear when the python node is up and running.

<script src="/js/framework/splashscreen.js"></script>

This module is optional and can be easily implemented yourself if you require customization, just take a peek

Notify.js

Add module notify.js (optional)

<script src="/js/framework/notify.js"></script>

Alert

Add module alert (optional)

<script src="/js/framework/alert.js"></script>

Python (server-side)

Procedure

A python procedure can be triggered by HTTP (synchronous) or STOMP (asynchronous), it is executed as a script and has the following variables and functions

Variables

  • userID = A String containing the requestor username.
  • request = A Python dictionary containing the request data
  • response = A python dictionary inwhere the response data can be stored

Functions

Logger

There are 5 log levels, all accept a single string as input, optionally you can use concatanation, formatting or  advanced formatting to create the log message.

# Trace logging accepts a string
logger.trace("message as a string")

# Debug logging, optionally use string formatting 
logger.debug("message as %s string" % 1)

# Info logging, optionally use string formatting 
logger.info("message as %s %s" % (1, "string"))

# Warning logging, optionally use string concatanation
logger.warn("message: " + "Hello World!")

# Error logging
logger.error("message")

STOMP

Wat is STOMP
Queues & Topics

# Push data to requestor
stomp.push("queuename",data)

# Push data to specific user
stomp.pushToUser("queuename",data,userName)

# Broadcast data to topic
stomp.topic("topicname",data)

Take a look at the chat demo to see an example using STOMP.

Library Code

all modules defined in the library section are available.

Example

logger.info("User [%s] send in request [%s]" % (userID,request))

# If HTTP call
response["Hello"] = "World!"

# If stomp call
stomp.push("foobar",{"Hello" : "World!"})

Library

Here you can define your standard libray files they should be stateless, so only root level functions and no global variables.
All functions defined in these files are available in the procedures, so make sure their names are unique e.g. define your library as
classes with static methods. Take a look at the getting started tutorial.

Example

Example from the demo: chat

from models import *
import time

class UserService:
  def getUser(name):
    user = User.objects(name=name).first()
    if user == None:
      user = User(name=name)
      user.save()
      logger.info("Saved user %s" % name)        
    return user 

  def setOnline(name):
    user = UserService.getUser(name)
    user.stamp = time.time()
    user.save()

  def updateStatus():
    exp = time.time() - 35
    users = []
    for user in User.objects:
      if user.stamp < exp:
        user.online = False
      else:
        user.online = True
      user.save()
      users.append({
          "name" : user.name,
          "online" : user.online
      }) 
    return users

Models

A model is the single, definitive source of information about your data. It contains the essential fields and behaviors of the data you’re storing. Each model maps to a single collection in your database.
In other words An instance of your model relates to a document (record) in your database.

The D2O framework uses the mongoengine project
MongoEngine is a Document-Object Mapper (think ORM, but for document databases) for working with MongoDB from Python. It uses a simple declarative API, similar to the Django ORM.

Your python node connects to a Database on the Mongo server automatically. This database is dedicated for you application & environment, in other words, each application has 2 databases Dev & Prod. Because the node automatically connects to the correct database you only have to worry about defining your document mapping, managing your document instances & querying the database.

Great! You've successfully subscribed.
Great! Next, complete checkout for full access.
Welcome back! You've successfully signed in.
Success! Your account is fully activated, you now have access to all content.