{{extend 'layout.html'}} {{import os}} {{include 'shbrush.html'}}
Slashdot Digg Facebook del.icio.us Newsvine StumbleUpon Reddit Yahoo Fark Technorati Furl Ma.gnolia
join our Google group
ask us a question

Gluon Web Framework

Gluon is a full-stack Enterprise Web Framework written in Python and programmable in Python, designed for fast development of secure database-driven applications. GPL2.0 License. It is written by Massimo Di Pierro. Copyright 2007


Some PDF Slides

Check out: {{=A('Gluon vs PHP',_href=URL(r=request,f='gluon_vs_php'))}}, {{=A('FAQ',_href=URL(r=request,f='faq'))}}, {{=A('Security Issues',_href=URL(r=request,f='security'))}}

Download

New Version 1.8 - posted on Oct 19 2007 - please upgrade
for Windows
for Mac
for Unix (source) (requires Python and sqlite3, runs on Windows and most Unix systems, including Linux and BSD)
Production Distribution/VMWare applicance (coming soon)

You like Gluon and you want to help? Talk to your friends about Gluon.

Main Features

Note: technically you can use other ORMs (like SQLAlchemy) and other templating languages, just install them and import them in a Gluon model. Anyway I discourage you from doing so before you try using Gluon as intended to be. Gluon is more than a bunch of components stitched together but a full web application, that is why every component was engineered from scartch.

Acknowledgments

Caveats

After installation, every time you run it, Gluon asks you to choose a password. This password is your administrative password. If the password is left blank, the administrative interface is disabled. The administrative interface /admin/default/index is only accessible via localhost and always requires a password.
Any url /a/b/c maps into a call to application a, controller b.py and function c in that controller.
You are strongly advised to also use Apache with mod_proxy or mod_wsgi to access applications in the framework. This allows bettersecurity and cuncurrency.

Overview

Exposed API

Complete list

Container Objects

Try them here: status

Navigation Functions and Objects

Internationalization

Views Helpers

HTTP Building Objects

Validator Objects

Database API

Database to HTML

Examples

Simple Examples

Here are some working and complete examples that explain the basic syntax of the framework

In controller: simple_examples.py

If the controller function returns a string, that is the body of the rendered page.
Try it here: hello1

In controller: simple_examples.py

The function T() marks strings that need to be translated. Translation dictionaries can be created at /admin/default/design
Try it here: hello2

In controller: simple_examples.py

and view: simple_examples/hello3.html

If you return a dictionary, the variables defined in the dictionery are visible to the view (template).
Try it here: hello3

In controller: simple_examples.py

You can change the view, but the default is /[controller]/[function].html. If the default is not found Gluon tries to render the page using the generic.html view.
Try it here: hello4

In controller: simple_examples.py

You can also generate HTML using helper objects HTML, BODY, H1, etc. Each of these tags is an class and the views know how to render the corresponding objects. The method .xml() serializes them and produce html/xml code for the page. Each tag, DIV for example, takes three types of arguments:


Try it here: hello5

In controller: simple_examples.py

Here we are showing the request, session ad response objects using the generic.html template.
Try it here: status

In controller: simple_examples.py

You can do redirect.
Try it here: redirectme

In controller: simple_examples.py

You can raise HTTP exceptions to return an error page.
Try it here: raisehttp

In controller: simple_examples.py

You can serve other than HTML pages by changing the contenttype vie the response.headers. The gluon.contenttype module can help you figure the type of the file to be server. NOTICE: this is not necessary for static files unless you want to require authorization.
Try it here: servejs

In controller: simple_examples.py

If an exception occurs (other than HTTP) a ticket is generated and the event is logged for the administrator. These tickets and logs can ce accessed, reviewed and deleted and any later time.
Try it here: raiseexception

Session Examples

In controller: session_examples.py

and view: session_examples/counter.html

Click to count. The session.counter is persistent for this user and application. Every applicaiton within the system has its own separate session management.
Try it here: counter

Layout Examples

In controller: layout_examples.py

and view: layout_examples/civilized.html

You can specify the layout file at the top of your view. civilized Layout file is a view that somewhere in the body contains {{include}}.
Try it here: civilized

In controller: layout_examples.py

and view: layout_examples/slick.html

Same here, but using a different template.
Try it here: slick

In controller: layout_examples.py

and view: layout_examples/basic.html

'layout.html' is the default template, every applicaiton has a copy of it.
Try it here: basic

Template Examples

In controller: template_examples.py
and view: template_examples/variables.html

A view (also known as template) is just an HTML file with {{...}} tags. You can put ANY python code into the tags, no need to indent but you must use pass to close bocks. The view is transformed into a python code and then executed. {{=a}} prints a.xml() or escape(str(a)).
Try it here: variables

In controller: template_examples.py

and view: template_examples/test_for.html

You can do for and while loops.
Try it here: test_for

In controller: template_examples.py

and view: template_examples/test_if.html

You can do if, elif, else.
Try it here: test_if

In controller: template_examples.py

and view: template_examples/test_try.html

You can do try, except, finally.
Try it here: test_try

In controller: template_examples.py

and view: template_examples/test_def.html

You can write functions in HTML too.
Try it here: test_def

In controller: template_examples.py

and view: template_examples/escape.html

The argument of {{=...}} is always escaped unless it is an object with a .xml() method such as link, A(...), a FORM(...), a XML(...) block, etc.
Try it here: escape

In controller: template_examples.py

and view: template_examples/xml.html

If you do not want to esacpe the argument of {{=...}} mark it as XML.
Try it here: xml

In controller: template_examples.py

and view: template_examples/beautify.html

You can use BEUTIFY to turn lists and dictionaries into organized HTML.
Try it here: beautify

Form Examples

In controller: form_examples.py

You can use HTML helpers like FORM, INPUT, TEXTAREA, OPTION, SELECT to build forms. the "value=" attribute sets the initial value of the field (works for TEXTAREA and OPTION/SELECT too) and the requires attribute sets the validators. FORM.accepts(..) trys to validate the form and, on success, stores vars into form.vars. On failure the error messages are stored into form.errors and shown in the form.
Try it here: form

Database Examples

Let's create a simple model with users, dogs, products and purchases (the database of an animal store). Users can have many dogs (ONE TO MANY), can buy many producs and every product can have many buyers (MANY TO MANY).
in model: db.py


Tables are created if they do not exist (try... except). Here "purchased" is an SQLQuery object, "db(purchased)" would be a SQLSet obejcts. A SQLSet object can be selected, updated, deleted. SQLSets can also be intersacated. Allowed field types are string, integer, password, blob, upload, date, time, datetime, references(*), and id(*). The id field is there by default and must not be declared. references are for one to many and many to many as in the example above. For strings you should specify a length or you get length=32.

You can use db.tablename.fieldname.requires= to set restrictions on the field values. These restrictions are automatically converted into widgets when generating forms from the table with SQLFORM(db.tablename).

define_tables creates the table and attempts a migration if table has changed or if database name has changed since last time. If you know you already have the table in the database and you do not want to attemt a migration add one last argument to define_table migrate=False.

In controller: database_examples.py

and view: database_examples/register_user.html

This is a simple user registration form. SQLFORM takes a table and returns the corresponding entry form with validators, etc. SQLFORM.accepts is similar to FORM.accepts but, if form is validated, the corresponding insert is also performed. SQLFORM can also do update and edit if a record is passed as its second argument. SQLTABLE instead turns a set of records (result of a select) into an HTML table with links as specified by its optional parameters. The response.menu on top is just a variable used by the layout to make the navigation menu for all functions in this controller.
Try it here: register_user

In controller: database_examples.py

and view: database_examples/register_dog.html

Here is a dog registration form. Notice that the "image" (type "upload") field is rendered into a <INPUT type="file"> html tag. SQLFORM.accepts(...) handles the upload of the file into the uploads/ folder.
Try it here: register_dog

In controller: database_examples.py

and view: database_examples/register_product.html

Nothing new here.
Try it here: register_product

In controller: database_examples.py

and view: database_examples/buy.html

Here is a rather sophisticated buy form. It checks that the buyer and the product are in the database and updates the corresponding record or inserts a new purchase. It also does a JOIN to list all purchases.
Try it here: buy

In controller: database_examples.py

Try it here: delete_purchased

In controller: database_examples.py

This is an update on an SQLSet. (db.purchase.id>0 identifies the set containing only table db.purchases.)
Try it here: reset_purchased

In controller: database_examples.py

This controller allows users to download the uploaded pictures of the dogs. Remember the upload=URL(...'download'...) statement in the register_dog function. Notice that in the URL path /application/controller/function/a/b/etc a, b, etc are passed to the controller as request.args[0], request.args[1], etc. Since the URL is validated request.args[] always contain valid filenames and no '~' or '..' etc. This is usefult to allow visitors to link uploaded files.

License

Copyright (c) 2007 by Massimo Di Pierro
All rights reserved.

Licensed under GPL v2 agreement.

In particular, redistribution and use in source and binary forms are permitted
provided that the following conditions are met:

    1. Redistributions of source code must retain the above copyright notice, 
       this list of conditions and the following disclaimer.
    
    2. Redistributions in binary form must reproduce the above copyright 
       notice, this list of conditions and the following disclaimer in the
       documentation and/or other materials provided with the distribution.

    3. Neither the name of Gluon nor the names of its contributors may be used
       to endorse or promote products derived from this software without
       specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.