Pull to refresh

Вместе веселей: python + flask + google app engine

Reading time 6 min
Views 28K
Предыстория: я, как и многие на Хабрахабре, чертовски люблю слушать музыку. Чаще всего делаю это в ВКонтакте. Иногда уже сфомированный плейлист надоедает — хочется чего-нибудь нового; но так, чтобы не сильно отличалось от того, что уже есть. Для этого на всех сервисах, предоставляющих возможность прослушивания музыки, существуют рекомендации. Признаюсь честно, рекомендации в ВКонтакте меня ужасают. Может кому-то нравится, но у меня тамошний подбор вызывает желание закрыть браузер (ИМХО, конечно). В общем, решил я эту ситуацию для себя исправить и реализовать свои собственные рекомендации с использованием API ВКонтакте и Last.fm. Так как я много слышал и читал про Google App Engine, но никогда его не использовал, решено было приобщиться к этой платформе.

Сразу скажу, что тонкости взаимодействия с API или алгоритм подбора рекомендаций здесь я описывать не буду. Об этом — в следующих статьях, может быть. В данной статье описан только процесс создания, настройки и деплоя приложения на платформе Google App Engine с использованием python и flask.
Об опечатках и неточностях просьба сообщать в личку. Спасибо.

Итак, начнем. Идем на appengine.google.com. Там, если вы еще не авторизованы, у вас попросят ввести логин/пароль для своего аккаунта в Google.

После успешной авторизации видим кнопку “Create Application” (или список приложений, если они у вас есть). Насколько мне известно, без дополнительных капиталовложений Google дает возможность создать до 25-ти приложений (поправьте, если я не прав). Со списком других квот можно ознакомиться, перейдя по ссылке.

После нажатия кнопки нас перекидывает на форму, где можно выбрать идентификатор приложения (еще не занятый) и название, а также опции аутентификации. Соглашаемся с Terms of Service и жмем кнопку для создания первого приложения. Создали, радость-то какая. Теперь ваше приложение доступно по адресу http://[identifier].appspot.com, где identifier — выбранный вами уникальный идентификактор приложения. Приложение доступно, но, естественно, не работает — нечему работать. Исправим ситуацию.

Качаем PyCharm, если надо. Есть небольшой нюанс выбора версии редактора: PyCharm, который Professional Edition, имеет встроенную поддержку Google App Engine, что выражается в интегрированных в IDE инструментах деплоя. PyCharm CE такой поддержки не имеет, так что придется деплоить через консоль.

Создаем проект в PyCharm. Если вы используете Professional Edition, то при создании проекта можно выбрать тип “Google App Engine project”. В этом случае придется указать идентификатор вашего приложения (вышеупомянутый identifier), а также путь к App Engine SDK, так что позаботьтесь о его скачивании заранее. Получить SDK для любого поддерживаемого языка программирования можно здесь. PyCharm создаст проект с уже заполненным файлом конфигурации app.yaml и рабочим основным скриптом main.py.

Собственно, основной скрипт:
main.py
import webapp2

class MainHandler(webapp2.RequestHandler):
    def get(self):
        self.response.write('Hello world!')

app = webapp2.WSGIApplication([
    ('/', MainHandler)
], debug=True)

Этот пример приводится и в самом руководстве по Google App Engine для Python, и даже на сайте JetBrains. В скрипте ничего примечательного нет — стандартный HelloWorld. Скажу только для тех, кто не знает, что webapp2 — это легковесный фреймворк, который совместим с Google App Engine и довольно прост в использовании (ну насколько я его пользовал).

Файл конфигурации:
app.yaml
application: pygask
version: 1
runtime: python27
api_version: 1
threadsafe: yes

handlers:
- url: /favicon\.ico
  static_files: favicon.ico
  upload: favicon\.ico

- url: .*
  script: main.app

libraries:
- name: webapp2
  version: "2.5.2"

Разберем конфиг:
  • application — наш идентификатор приложения (пусть ваш не смущает слово «pygask» — это вольное сокращение от python+gae+flask :) );
  • handlers — перечень паттернов URL и описаний как их обрабатывать. В директиве handlers можно использовать два типа обработчиков — обработчики статики и обработчики скриптов. Статику, в данном случае, представляет загрузчик фавикона, скрипты — основной скрипт для запуска приложения main.app (Внимание! Расширение .py указывать не надо);
  • libraries — библиотеки, необходимые приложению для работы; в данном случае, webapp2. Python 2.7, запускаемый на Google App Engine, поддерживает некоторый набор библиотек, работающий «из коробки». Полный список можно найти здесь.

Подробное описание конфигурации приложения Google App Engine лежит тут.

В общем-то, наше первое приложение готово к тому, чтобы проверить его работу. Запускаем проект в PyCharm; на локальной машине он будет доступен по адресу: 127.0.0.1:8080 (если вы ничего не меняли в конфигурации проекта). Если при открытии, видите «Hello world!» — всё работает.

Что делать, если вы не используете PyCharm, а запустить проект всё равно хочется?
Linux way: в терминале выполняем команду в следующем формате:
<path to python interpeter> <path to SDK>/dev_appserver.py --host 127.0.0.1 <path to project>
Для пояснения приведу команду, которую я использую, чтобы запустить pygask в консоли (при условии, что и SDK, и папка проекта находятся в /var/www/):
andymitrich@pc:~$ python /var/www/google_appengine/dev_appserver.py --host 127.0.0.1 /var/www/pygask/
Набираем что-то подобное в терминале и открываем 127.0.0.1:8080 и, надеюсь, видим «Hello world!».

Касательно пользователей Windows — там всё немного по-другому. SDK скачивается и устанавливается на компьютер и для запуска проекта используется Google App Engine Launcher. По поводу Mac OS ничего сказать не могу — возможно в комментариях кто-нибудь расскажет.

К сожалению, фреймворк webapp2 — это не то, что нам нужно. Поэтому, айда подключать flask.

Так как в списке работающих по-умолчанию библиотек, flask не значится, то нам, в первую очередь, надо позаботиться о его подключении. Google App Engine поддерживает возможность отдельного конфигурирования используемых модулей. Делается это в файле с именем appengine_config.py. Подробней о нем здесь. Будем использовать его для подключения фреймворка. Для этого с помощью pip установим flask во внутреннюю директорию, назовем её lib. Делаем это либо вручную
andymitrich@pc:~$ pip install -t /var/www/pygask/lib/ flask
Либо с помощью файла requirements.txt
andymitrich@pc:~$ pip install -r /var/www/pygask/requirements.txt -t /var/www/pygask/lib/
Обратите внимание на параметр -t — он содержит путь для установки пакета.

Flask установлен, можно использовать — перепишем немного конфиг и основной скрипт:
  1. Из конфига приложения app.yaml можно убрать участок с директивой libraries — она нам не нужна.
  2. Основной скрипт теперь выглядит следующим образом:
    main.py
    from flask import Flask
    
    app = Flask(__name__)
    
    @app.route('/')
    def home():
         return 'Hello world!'
    

Чтобы приложение подхватило установленный flask, укажем в файле appengine_config.py место его нахождения.
appengine_config.py
import site
import os.path

site.addsitedir(os.path.join(os.path.dirname(__file__), 'lib'))

Пробуем запустить — видим всё тот же «Hello world!».

Доведем проект до более-менее кошерного вида: добавим пакет application, папки для статических файлов и шаблонов, вынесем обработчики и представления в отдельные файлы; поступайте так, как будто собираете обычный проект на flask. После всех проведенных манипуляций дерево проекта выглядит следующим образом:

Дальше можно развивать его в какую угодно сторону.

Обращу ваше внимание на то, как изменились первоначальные файлы:
  • основной скрипт, который теперь состоит из одной строки
    main.py
    import application
    
  • файл конфигурации проекта
    app.yaml
    application: pygask
    version: 1
    runtime: python27
    api_version: 1
    threadsafe: yes
    
    handlers:
    - url: /favicon\.ico
      static_files: favicon.ico
      upload: favicon\.ico
    
    - url: .*
      script: main.application.app

В файле конфигурации изменился путь к основному скрипту — добавилось указание пакета application.

Допустим, выведенного на экран «Hello world!» нам достаточно на первый раз. Давайте деплоить на appspot.com. Собственно, здесь ничего сложного также нет. Но, перед тем, как начать, хочу сказать об одной важной весчи: в процессе разработки появляется много рабочих файлов, которые на сервере не нужны. Для того, чтобы они не попали туда при деплое, в конфиге приложения можно в директиве skip_files указать всё то, что не должно выкладываться. Подробнее.

Если вы счастливый пользователь PyCharm, то потрудитесь проделать «сложнейшую» операцию: Tools -> Google App Engine -> Upload App Engine app… Далее, если это первый деплой, выберите подходящий вам способ авторизации (я с парой email/password не разобрался — почему-то данные не подошли, поэтому использовал OAuth2 и не заморачивался) и, вуаля, можно идти на http://[identifier].appspot.com (в данном случае, pygask.appspot.com) и смотреть на результат своих трудов.

Если вы по каким-то причинам не используете вышеупомянутую IDE, для вас рецепт в одну строку (Linux way):
<path to python interpeter> <path to SDK>/appcfg.py <path to project>
Соответственно, я использую:
andymitrich@pc:~$ python /var/www/google_appengine/appcfg.py --oauth2 /var/www/pygask/

Обратите внимание на параметр --oauth2, он нужен для авторизации через OAuth2. Не укажете его — попросят ввести email/password. В случае успешного завершения исполнения команды, ваш проект будет доступен по соответствующему адресу.

На этом всё, надеюсь, что материал окажется кому-нибудь полезен. Если будет интересно, в дальнейшем расскажу как в рамках данной идеи я развлекался с API Вконтакте и Last.fm и к чему всё это привело. Спасибо за внимание.

P.S. Код лежит на гитхабе: pygask.
Tags:
Hubs:
+19
Comments 18
Comments Comments 18

Articles