Framework
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
# 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.