Skip to main content

Pygasus web framework working with ExtJs

Project description


Pygasus is a new Python 3 framework to build web applications with Sencha ExtJS. Pygasus is designed to be full customizable for your project.

bst.pygasus and all corresponding submodules are licensed under the ZPL 2.1, see LICENSE.txt for details.



yellow modules are planned to be developed in the near future

The various packages are:

The core package of the framework that assembles all required packages together.
The datamanager manages data coming from the client and data sent to the client’s browser.
This package handles the translation for multilingual sites and applications.
Scaffolding is a package to generate standard models, stores, views and grids for ExtJS.
This package provide a default login mask and a pluggable authentication. In the future we also plan to implement a role based permission model.
This package creates a cookie on client browsers and provides a server side session store.
The layer needed to let the application work as a WSGI server.
This package is responsible to share all needed static resources with the client.

Getting started


The ZCA (Zope component Architectur) is a main element in this framework. If you are not familiar with it, we recommend you first learn its basics. You can follow the links at the bottom of this page. Also other external libraries are already well documented, which is why we didn’t want to do that twice.


We recommend to setup up a buildout for your project. First it will install all required dependencies and the scripts needed to run a server. The boostrap file can be downloaded at

File structure:

├── buildout.cfg
├── etc
│   ├──
│   └──
└── dev
    └── myproject



extends =

develop = dev/myproject
parts =

extensions = mr.developer
auto-checkout =

recipe = collective.recipe.template
input = etc/
output = ${buildout:parts-directory}/etc/${:outfile}
outfile = debug.ini

recipe = collective.recipe.template
input = etc/
output = ${buildout:parts-directory}/etc/${:outfile}
outfile = site.zcml

recipe = zc.recipe.egg:script
eggs =

unzip = true
recipe = zc.recipe.egg
eggs =


path = ${zcml:output}

use = egg:bst.pygasus.wsgi#main

use = egg:waitress#http
host =
port = 5000
threadpool_workers = 1
threadpool_spawn_if_under = 1
threadpool_max_requests = 0


<configure xmlns="">
    <include package="myproject" />

Run your buildout. (You must first create your own project as shown in next part)

$ cd buildout
$ python3
$ ./bin/buildout

Create an application

Proposed File Structure

We propose the following file structure inside your python egg:

├── app
│   ├── application.js
│   ├── controller
│   │   ├── Card.js
│   │   └── Main.js
│   ├── resources
│   │   └── css
│   │       └── styles.css
│   └── view
│       ├── CardView.js
│       └── MainView.js
├── configure.zcml
├── locales
│   ├── bb.extjs.demo.pot
│   └── fr
│       └── LC_MESSAGES
│           ├──
│           └── bst.pygasus.demo.po

setup configure.zcml

<configure xmlns=""

    <include package="bst.pygasus.core" />

    <grok:grok package="." />

    <i18n:registerTranslations directory="locales" />


Create an application context (

from fanstatic import Library
from fanstatic import Resource
from bst.pygasus.core import ext

library = Library('demo', 'app')

class DemoContext(ext.ApplicationContext):

    title = 'Demo'
    application = 'bst.pygasus.demo.Application'
    namespace = 'bst.pygasus.demo'
    resources = Resource(library, 'application.js',

Register additional ExtJS paths (

ExtJS needs to know where additional ExtJS-Classes can be loaded. This is why each namespace used in ExtJS needs to be registred. In this example we regstister two namespaces for ‘bst.pygasus.demo.view’ and ‘bst.pygasus.demo.controller’. The path usually begins with ‘fanstatic’, followed by your library name (e.g. “demo”) ( Library(‘demo’, ‘app’) ) and then, at the end, a subdirectory.

class ViewClassPathMapping(ext.ClassPathMapping):
    namespace = 'bst.pygasus.demo.view'
    path = 'fanstatic/demo/view'

class ViewClassPathMapping(ext.ClassPathMapping):
    namespace = 'bst.pygasus.demo.contoller'
    path = 'fanstatic/demo/controller'

Define a schema (

With this schema different ExtJS-Classes like form, store or model, are auto generated on the fly. Look at the package bst.pygasus.scaffolding for the supported types and class generation. Feel free to extend this with your own generators of ExtJS classes for your project. This schema will also be used to transform json to a python model or vice versa.

from bst.pygasus.core import ext

from zope import schema
from zope.interface import Interface

@ext.scaffolding('Card', 'Magic the Gathering')
class ICard(Interface):
    id = schema.Id(title='ID', required=False)

    name = schema.TextLine(title='Name', required=True)

    costs = schema.Int(title='Costs', required=False)

    publication = schema.Date(title='Publication', required=True)

Create a Model (

The model is used to transfer data from the server to client and back.

from bst.pygasus.core import ext
from bst.pygasus.demo import schema
from zope.schema.fieldproperty import FieldProperty

class Card(ext.Model):

    id = FieldProperty(ICard['id'])
    name = FieldProperty(ICard['name'])
    costs = FieldProperty(ICard['costs'])
    publication = FieldProperty(ICard['publication'])

Create a handler for CRUD requests (

The handler for an definded model provides the CRUD operations. Now it is up to you to implement whatever you need in these methods.

class CardHandler(ext.AbstractModelHandler):
    ext.adapts(model.Card, IRequest)

    def get(self, model, batch):
        start, limit = self.slice()
        property, direction = self.sort()

        return cardIndexer.search_index(start, limit, property, direction)

    def create(self, model, batch): = cardIndexer.get_next_id()

        return [model], 1

    def update(self, model, batch):

        return [model], 1

    def delete(self, model, batch):

        return [model], 1

i18n (Internationalization)

Usually you define a domain name for each package. In order to do that you create an instance of MessageFactory in the file:

from zope.i18nmessageid import MessageFactory

_ = MessageFactory('bst.pygasus.demo')

Now you can use translation messages anywhere you want to translate a string to multiple languages:

publication = schema.Date(title=_('publication_title', default='Publication'), required=True)

If you want use translations in ExtJS, it works similar to translations in python. Simply write a variable at the top of the file and pass the domain name in the MessageFactory:

var _ = i18n('bst.pygasus.demo');

Ext.define('bst.pygasus.demo.view.MainView', {
    extend: 'Ext.container.Viewport',


Now you can translate messages with the variable defined anywhere in the class:

items: [{
    xtype: 'button',
    action: 'save',
    text: _('tr_save', 'Save'),

You can use the lingua package to crawl translation from python and ExtJS files and generate a .pot file with it. This application is already installed by buildout. After generating a .pot file you can use different kinds of gettext tools to merge and build the final .po and .mo files for each language:

./bin/pot-create –d <domain> -o <filename>.pot <source>

Using Scaffolding

Scaffolding provides default ExtJS-classes that can be directly used. Use the the “required” attribute to load a scaffolding class. In follow example we have defined the xtype to “DisplayCard”. This will generate a read only view with all fields from the schema ICard.

Ext.define('bst.pygasus.demo.view.CardView', {
    extend: 'Ext.window.Window',

    requires: [

    itemId: 'cardView',
    layout: 'vbox',

    initComponent: function() {
        var me = this;

        me.items = [{
            xtype: 'DisplayCard',
            itemId: 'displayCard',
            title: '',
            maxWidth: '500'
            xtype: 'button',
            text: 'Delete',
            action: 'delete'

        me.bodyPadding = '5 5 5 5';



As an another example we use buffered store from scaffolding:

Ext.define('bst.pygasus.demo.controller.Main', {
    extend: '',

    requires: [


Demo application

We have a demo application that you can easily install with a buildout file. If you are interested, please follow the instruction at bst.pygasus.demo.

About us

We are the IT Services of Biel/Bienne, Switzerland.


1.0.1 (2015-08-19)

  • Use complete

1.0 (2015-08-03)

  • Initial public release [codeix]

Project details

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Filename, size & hash SHA256 hash help File type Python version Upload date
bst.pygasus.core-1.0.1.tar.gz (77.5 kB) Copy SHA256 hash SHA256 Source None Aug 19, 2015

Supported by

Elastic Elastic Search Pingdom Pingdom Monitoring Google Google BigQuery Sentry Sentry Error logging AWS AWS Cloud computing DataDog DataDog Monitoring Fastly Fastly CDN DigiCert DigiCert EV certificate StatusPage StatusPage Status page