Skipole WSGI generator.

Topics:

Introduction Getting Started Your Code skiadmin start_call submit_data end_call Exceptions PageData SectionData skicall Serving wsgi Code Examples

Development at GitHub:

github.com/bernie-skipole/skipole

Your project Python code

The projectfiles directory containing project myproj should have been created as previously described. Within it you will be developing ...projectfiles/myproj.py

myproj.py will already be set up to do most of the following work, but in summary, it needs to import the WSGIApplication class.

Creating an instance of this WSGISpplication object creates an 'application' which can be used by any WSGI web server.

An instance is created within myproj.py with the lines:


    from skipole import WSGIApplication
    application = WSGIApplication(project='myproj',
                                  projectfiles=PROJECTFILES,
                                  proj_data={},
                                  start_call=start_call,
                                  submit_data=submit_data,
                                  end_call=end_call,
                                  url="/",
                                  proj_ident=None)


project is your project name.

projectfiles is the path to your projectfiles directory - this informs the object where the project JSON files can be found.

proj_data is a dictionary which you can optionally set with values which will be passed to your functions.

start_call, submit_data and end_call are three functions that you will provide. Minimum versions are available in myproj.py which you will develop further. They are called during the progress of a call

url is the path where the project is served

proj_ident - added for skipole version 5.5.2 and later, if this is left at its default None value, then it will be automatically set to the project name. However it can be set to a different string here which may be useful if multiple instances of this project are to be added to a parent 'root' project. Each unique proj_ident will then define each of the sub applications.

The functions

start_call(called_ident, skicall)

start_call is called when the server initially receives an incoming call. The parameter called_ident is a tuple of (proj_ident, pagenumber) which defines the page called from the incoming call URL. It will be 'None' if the ident of the requested page is unknown. The parameter skicall is an object containing further information and methods which will be described later in this documentation.

The function would normally return the 'called_ident' tuple, to pass the call on to the page requested, but it could return a different ident tuple which would divert the call to a different page.

submit_data(skicall)

submit_data is called by Responder pages, in this function you would typically handle any data submitted and create the response by filling in the data for a template page.

end_call(page_ident, page_type, skicall)

end_call is called prior to returning the page. Any final widget fields can be set here.

These functions can in turn call on any further modules you wish to include within the package - hence you can access your own databases and functionality.

You will notice the framework passes the skicall object to your functions which contains a good deal of information you will need, more about it is given here:skicall

In particular your functions will create a PageData object, which is a dictionary-like object where widget field values can be set. These will be set in the page finally returned to the client. For further details:PageData

The skis project

A project can have further 'sub-projects' added to it at a given path. The 'skis' sub project is provided by the skipole framework, before your application is ready it needs to have the application from the 'skis' project added to it. Within myproj.py you will see this is done with:


    from skipole import skis
    skis_application = skis.makeapp()
    application.add_project(skis_application, url='/lib')

This 'skis' application serves javascript files used by the framework, so it is always needed.

add_project

This is a method of the WSGIApplication.

application.add_project(subapplication, url=None, check_cookies=None)

Your main application, generally served at '/' can have another 'sub' application added at a given path, so if you want to add a subapplication you would typically:

Place the sub project code location on your sys.path

Import the sub project to obtain its wsgi application

Call application.add_project with the sub project application and the url where it will be served.

The optional check_cookies argument can be set to a function which you would create, with signature:

def my_check_cookies_function(received_cookies, proj_data):

When a call is received, with a url that routes it to the sub application, if this function is defined, and set in the add_project method:

application.add_project(subapplication, url="/suburl", check_cookies=my_check_cookies_function)

Then initially, before the call is routed to the subapplication, your my_check_cookies_function is called, with the received_cookies dictionary, and with your application's proj_data dictionary. If your function returns None, the call proceeds unhindered to the subapplication. If however your function returns an ident tuple, of the form (projectname, pagenumber), then the call is routed to that page instead.

This is typically used to limit access to the subproject. For example your my_check_cookies_function could check for a valid received cookie, and if present, would return None, allowing access, but if not present, it would return the ident of a login page.

Besides an ident tuple, the function could just return a pagenumber, in which case the corresponding page of the root application would be called, or it could return a label, in which case the root application would check its label ident dictionary and find the target ident that way. The label should not point to a URL.

Exceptions

Your myproj.py module can also import exceptions which you can use in your functions:

from skipole import FailPage, GoTo, ValidateError, ServerError, ServeFile

Further information about the exceptions and their arguments can be found at:

FailPage(message = '', section='', widget='', failpage=None)

GoTo(target, clear_submitted=False, clear_page_data=False)

ValidateError(message = '', section='', widget='', status='400 Bad Request')

ServerError(message = '', section='', widget='', status='500 Internal Server Error', code=0)

ServeFile(server_file, status='200 OK', headers=None, enable_cache=None, mimetype=None)