http://habrahabr.ru/post/233181/
    	В этой статье мы соберём вместе aiorest + jinja2 + angular.js + gulp.js + bower.js + nginx. В результате мы получим: 
- авто-перезапуск сервера при изменении python-кода и jinja-шаблонов
 
- сборка, минификация и автоматическая пересборка при изменении клиентского js-кода
 
  Начнём с главного — как пользоваться, а затем я подробнее опишу некоторые моменты реализации. Если вам легче читать код — вот ссылка на 
репу.  
Установка
$ git clone git@github.com:imbolc/aiorest-angular-template.git 
$ cd aiorest-angular-template 
$ sudo npm install -g gulp bower 
$ npm install 
$ bower install 
$ ./bin/buildenv.py 
$ sudo ./bin/configure_nginx.py 
 Добавляем в 
/etc/hosts: 
127.0.1.1   aio-angular.l.com 
 И запускаем сервер разработчика: 
$ gulp 
 Готово, теперь можно открывать в браузере: 
http://aio-angular.l.com/ Использование
  Просто добавляйте обработчики в 
handlers.py, урлы — в 
urls.py, а клиентский код раскладывайте в папке 
client в удобной для вас структуре. 
Конфигурация
aiorest не умеет ничего, кроме как отдавать json, поэтому, для отдачи статики мы будем использовать nginx, шаблон его конфига как и другие настройки находится в папке 
cfg. Там же находится файлик с питон-зависимостями 
pipreq.txt и конфиг для питон-части приложения 
__init__.py + 
local.py (последний в джанга-стайл перезаписывает специфичную для текущего сервера конфигурацию первого). 
   Хранить конфигурацию лучше в одном месте, поэтому клиентский конфиг мы так же генерируем на сервере, а потом подсовываем ангуляру в виде 
value (
templates/client_config.js): 
angular.module('app').value('cfg', << config|tojson|safe >>); 
Сборка js
  Мы будем пользоваться мудростью этой статьи, которую я всячески рекомендую к прочтению: 
Real-World Best Practices for Building Angular.js Apps without Browserify or Require.js. Вкратце: require.js для ангуляра не подходит, browserify — подходит, но нам не нужна большая часть его функционала потому, что в ангуляре уже есть модули. 
   Итак, будем использовать 
gulp.js — современную замену bower.js, он не использует промежуточных файлов, имеет более приятный синтаксис описания задач и уже аналогичную кучу готовых плагинов. Смотрим в 
gulpfile.js: 
gulp.task('js', function () { 
    gulp.src(['client/app.js', 'client/**/*.js']) 
    .pipe(plumber()) 
    .pipe(sourcemaps.init()) 
    .pipe(concat('app.js')) 
    .pipe(ngAnnotate()) 
    .pipe(uglify()) 
    .pipe(sourcemaps.write()) 
    .pipe(gulp.dest('./static/build')); 
}); 
sourcemaps.init + sourcemaps.write добавляют в сборку source map который позволяет в консоли браузера видеть ошибки и лог-сообщения с нумерацией строк исходных файлов 
concat — копирует все файлы в один 
ngAnnotate — нельзя просто так взять и минифицировать ангуляр-код: Dependency Annotation 
uglify — минификация 
plumber — перехватывает ошибки в ходе всего этого, чем не даёт падать авто-персборке 
Авто-перезапуск сервера
gulp.task('dev_server', shell.task([ 
    ('nodemon ./app.py --exec "var/env/bin/python"' + 
    ' --ext "py html" --ignore "static"') 
])); 
 Дада, 
nodemon умеет перезапускать не только node.js :) 
Серверный код
  Приложение начинается в 
app.py: 
import asyncio 
import aiorest 
 
import cfg 
import lib.logging 
import prepare_static 
import urls 
 
 
lib.logging.setup(cfg.LOG_FILE) 
prepare_static.client_config(urls=urls.CLIENT_URLS) 
prepare_static.render_html('index.html') 
 
 
server = aiorest.RESTServer(hostname='127.0.0.1') 
for url in urls.SERVER_URLS: 
    server.add_url(*url) 
 
 
loop = asyncio.get_event_loop() 
loop.run_until_complete(loop.create_server( 
    server.make_handler, '127.0.0.1', cfg.PORT)) 
try: 
    loop.run_forever() 
except KeyboardInterrupt: 
    pass 
 Здесь мы настраиваем логирование, подготавливаем клиентский конфиг описанный выше. Затем рендерим пока единственный шаблон т.к. в нём есть некоторая логика: 
<% if cfg.DEBUG %> 
    <script src="/static/bower/angular/angular.js"></script> 
    <script src="/static/bower/angular-resource/angular-resource.js"></script> 
<% else %> 
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.14/angular.min.js"></script> 
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.14/angular-resource.min.js"></script> 
<% endif %> 
 И да, мы переопределили обозначения управляющих конструкций в jinja2 (
{{ }} => 
<< >>, 
{% %} => 
<% %>), т.к. ангуляр использует такие же. 
   Далее мы создаём aiorest-сервер, добавляем урлы из файлика 
urls.py: 
import handlers 
 
 
SERVER_URLS = [ 
    ('GET', '/hello',        handlers.hello), 
    ('GET', '/hello/{name}', handlers.hello), 
] 
 
CLIENT_URLS = { 
    'hello': '/api/hello/:name', 
} 
CLIENT_URLS — это аякс урлы которые мы будем использовать в браузерном кодe. А хендлеры для серверных урлов находятся в файлике 
handlers.py: 
def hello(name='world'): 
    message = 'Hello, {}!'.format(name) 
    return {'message': message} 
Angular-код
  Описывать hello world на ангуляре пожалуй не буду :) Единственное, обращу внимание на использование клиентского конфига, который мы готовили выше (
client/hello/hello.svc.js): 
angular.module('app') 
    .service('HelloSvc', function ($resource, cfg) { 
        this.fetchGreeting = function () { 
            return $resource(cfg.urls.hello).get.apply(this, arguments); 
        }; 
    });