This asynchronous framework with a modular structure like Django. But with mongodb, jinja2, websocket out of the box, and more than a simple barrier to entry.

Framework Installation

$ pip install tao1

Getting Started

Create a project anywhere:

$ -p name

Create an application in the folder of the project apps:

$ -a name

Run server:

$ python3

Source code

The project is hosted on GitHub

Please feel free to file an issue on the bug tracker if you have found a bug or have some suggestion in order to improve the library.


Python 3.5+ and aiohttp

Installation Python 3.5 for ubuntu:

sudo add-apt-repository ppa:fkrull/deadsnakes
sudo apt-get update
sudo apt-get install python3.5 python3.5-dev


When you develop enough to run the file python3 For production to run, is better to use the supervisor and nginx. Settings supervisor in /etc:


Settings nginx in /etc:

server {
      location / {
     location /ws {
           proxy_http_version 1.1;
           proxy_set_header Upgrade $http_upgrade;
           proxy_set_header Connection "upgrade";


Project structure:

  • In the locale folder there are the translation files.
  • In the static folder are static files, scripts .js, styles .css, images, etc.
  • In the templ folder there are the templates.
  • In folder apps contains app.
  • this is run servers files.
  • this is settings files.
  • this is configuration files for gunicorn. Not mandatory.
  • like but for gunicorn. Not mandatory.

Module structure:



Example route in file

route( 'GET', '/ws',  ws,  'ws' )


In framework integrated jinja2. Templates are always in the templ folder.

To call the template function templ and pass it the template name. If the template is in some sort of module, the call looks like this apps.modul_name.templ_name.

If the template is in the root of the project in the templ folder, then simply write his name.


def page(request):
    return templ('index', request, {'key':'val'} )


The websocket to create games and chat very easy to use.

The first is the need to call route with the template to draw the route and chat with the handler for chat:

route( 'GET', '/ws',   ws,          'ws' )
route( 'GET', '/wsh',  ws_handler,  'ws_handler' )

These routes work you can see an example.

The second is the functions themselves. Function for render chat page

async def ws(request):
    return templ('', request, {} )

Function handler chat:

async def ws_handler(request):
   ws = web.WebSocketResponse()
   await ws.prepare(request)
   async for msg in ws:
       if == aiohttp.MsgType.text:
           if == 'close':
               await ws.close()
               ws.send_str( + '/answer')
       elif == aiohttp.MsgType.error:
           print('ws connection closed with exception %s' % ws.exception())
   print('websocket connection closed')
   return ws


To write the database query you need to request.db and then as usual.

async def test_db(request):
       # save doc{"_id":"test", "status":"success"})
       # find doc
       val = request.db.doc.find_one({"_id":"test"})
       return templ('', request, {'key':val})

Static files

Static files it is better to entrust nginx but tao1 able return files.

All files must be located in the folder static.

If they are the root of the project then the path will be like this /static/static/ If the files are in a certain module, then the path like this /static/module_name/file_name.jpg.


Create cache for function 5 second, the first parameter - name

@cache("main_page", expire=5)
async def page(request):
    return templ('index', request, {'key':'val'} )