Package: bst.pygasus.core
ContentsIntroductionArchitectureGetting startedRecommendationBuildoutCreate an applicationProposed File Structuresetup configure.zcmlCreate an application context (extjs.py)Register additional ExtJS paths (extjs.py)Define a schema (schema.py)Create a Model (model.py)Create a handler for CRUD requests (handler.py)i18n (Internationalization)Using ScaffoldingDemo applicationExternal ReferencesAbout usChangelog1.0.1 (2015-08-19)1.0 (2015-08-03)IntroductionPygasus is a new Python 3 framework to build web applications withSencha 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.Architectureyellow modules are planned to be developed in the near futureThe various packages are:bst.extjs.coreThe core package of the framework that assembles all required packages together.bst.extjs.datamanagerThe datamanager manages data coming from the client and data sent to the client’s browser.bst.extjs.i18nThis package handles the translation for multilingual sites and applications.bst.extjs.scaffoldingScaffolding is a package to generate standard models, stores, views and grids for ExtJS.bst.extjs.securityThis package provide a default login mask and a pluggable authentication. In the future we also plan to
implement a role based permission model.bst.extjs.sessionThis package creates a cookie on client browsers and provides a server side session store.bst.extjs.wsgiThe layer needed to let the application work as a WSGI server.bst.extjs.resourcesThis package is responsible to share all needed static resources with the client.Getting startedRecommendationThe 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.BuildoutWe 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 athttps://bootstrap.pypa.io/bootstrap-buildout.py.File structure:buildout
├── bootstrap.py
├── buildout.cfg
├── etc
│   ├── deploy.ini.in
│   └── site.zcml.in
└── dev
    └── myprojectbuildout.cfg[buildout]extends=https://raw.githubusercontent.com/bielbienne/bst.pygasus.demo/master/sources.cfghttps://raw.githubusercontent.com/bielbienne/bst.pygasus.demo/master/versions.cfgdevelop=dev/myprojectparts=appzcmllinguaextensions=mr.developerauto-checkout=js.extjsbst.pygasus.corebst.pygasus.wsgibst.pygasus.scaffoldingbst.pygasus.datamanagerbst.pygasus.resourcesbst.pygasus.securitybst.pygasus.sessionbst.pygasus.i18nbst.pygasus.demo[debug_ini]recipe=collective.recipe.templateinput=etc/deploy.ini.inoutput=${buildout:parts-directory}/etc/${:outfile}outfile=debug.ini[zcml]recipe=collective.recipe.templateinput=etc/site.zcml.inoutput=${buildout:parts-directory}/etc/${:outfile}outfile=site.zcml[app]recipe=zc.recipe.egg:scriptarguments="${debug_ini:output}"eggs=bst.pygasus.wsgimyproject[lingua]unzip=truerecipe=zc.recipe.eggeggs=linguabst.pygasus.i18netc/deploy.ini.in[zcml]path=${zcml:output}[app:main]use=egg:bst.pygasus.wsgi#main[server:debug]use=egg:waitress#httphost=127.0.0.1port=5000threadpool_workers=1threadpool_spawn_if_under=1threadpool_max_requests=0etc/site.zcml.in<configurexmlns="http://namespaces.zope.org/zope"><includepackage="myproject"/></configure>Run your buildout. (You must first create your own project as shown in next part)$cdbuildout$python3boostrap.py$./bin/buildoutCreate an applicationProposed File StructureWe 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
├── extjs.py
├── handler.py
├── __init__.py
├── locales
│   ├── bb.extjs.demo.pot
│   └── fr
│       └── LC_MESSAGES
│           ├── bst.pygasus.demo.mo
│           └── bst.pygasus.demo.po
├── model.py
└── schema.pysetup configure.zcml<configurexmlns="http://namespaces.zope.org/zope"xmlns:grok="http://namespaces.zope.org/grok"xmlns:i18n="http://namespaces.zope.org/i18n"i18n_domain="myproject"><includepackage="bst.pygasus.core"/><grok:grokpackage="."/><i18n:registerTranslationsdirectory="locales"/></configure>Create an application context (extjs.py)fromfanstaticimportLibraryfromfanstaticimportResourcefrombst.pygasus.coreimportextlibrary=Library('demo','app')classDemoContext(ext.ApplicationContext):title='Demo'application='bst.pygasus.demo.Application'namespace='bst.pygasus.demo'resources=Resource(library,'application.js',depends=[ext.extjs_resources])Register additional ExtJS paths (extjs.py)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.classViewClassPathMapping(ext.ClassPathMapping):namespace='bst.pygasus.demo.view'path='fanstatic/demo/view'classViewClassPathMapping(ext.ClassPathMapping):namespace='bst.pygasus.demo.contoller'path='fanstatic/demo/controller'Define a schema (schema.py)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.frombst.pygasus.coreimportextfromzopeimportschemafromzope.interfaceimportInterface@ext.scaffolding('Card','Magic the Gathering')classICard(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 (model.py)The model is used to transfer data from the server to client and back.frombst.pygasus.coreimportextfrombst.pygasus.demoimportschemafromzope.schema.fieldpropertyimportFieldPropertyclassCard(ext.Model):ext.schema(schema.ICard)id=FieldProperty(ICard['id'])name=FieldProperty(ICard['name'])costs=FieldProperty(ICard['costs'])publication=FieldProperty(ICard['publication'])Create a handler for CRUD requests (handler.py)The handler for an definded model provides the CRUD operations. Now it is up to you to implement whatever you need in these methods.classCardHandler(ext.AbstractModelHandler):ext.adapts(model.Card,IRequest)defget(self,model,batch):start,limit=self.slice()property,direction=self.sort()returncardIndexer.search_index(start,limit,property,direction)defcreate(self,model,batch):model.id=cardIndexer.get_next_id()cardIndexer.extend_index(model)return[model],1defupdate(self,model,batch):cardIndexer.update_index(model)return[model],1defdelete(self,model,batch):cardIndexer.reduce_index(model)return[model],1i18n (Internationalization)Usually you define a domain name for each package. In order to do that you create an instance of MessageFactory in the __init__.py file:fromzope.i18nmessageidimportMessageFactory_=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 ScaffoldingScaffolding 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:['scaffolding.display.Card'],itemId:'cardView',layout:'vbox',initComponent:function(){varme=this;me.items=[{xtype:'DisplayCard',itemId:'displayCard',title:'',maxWidth:'500'},{xtype:'button',text:'Delete',action:'delete'}];me.bodyPadding='5 5 5 5';me.callParent(arguments);}});As an another example we use buffered store from scaffolding:Ext.define('bst.pygasus.demo.controller.Main',{extend:'Ext.app.Controller',requires:['scaffolding.bufferedstore.Card'],....Demo applicationWe have a demo application that you can easily install with a buildout file. If you are interested, please follow the instruction atbst.pygasus.demo.External Referenceshttp://zopeinterface.readthedocs.org/en/latest/http://zopecomponent.readthedocs.org/en/latest/https://www.python.org/dev/peps/pep-0333/https://pypi.python.org/pypi/martianhttps://pypi.python.org/pypi/zc.buildout/2.4.0http://grok.zope.org/documentation/tutorial/grok-poller-tutorial/adaptershttp://www.fanstatic.org/en/latest/About usWe are the IT Services of Biel/Bienne, Switzerland.http://foss.biel-bienne.ch/blog/Changelog1.0.1 (2015-08-19)Use complete MANIFEST.in1.0 (2015-08-03)Initial public release [codeix]