Причина
Проблема развертывания джанго приложений в продакшене до недавнего времени у меня стояла остро. Моя стандартная связка nginx+threaded fastcgi(flup) была очень не стабильна. Из-за достаточно ограниченных ресурсов (памяти) на серверах (в основном впс с лимитом до 100мб). Постоянно приходилось перезагружать сервер из-за сжирания памяти (неужели в питоне есть утечки памяти, или это из-за корявости моих скриптов?) и умирании процесса. Хорошо когда это было запланировано, а когда случалось неожиданно - это была маленькая катастрофа. Заказчики ругались.
Но в этой связке меня подкупала легковесность nginx и простота настройки. Изначально я ещё попробовал mod_python и apache, но не впечатлило - медленно и сложно. Фастсиджиай работал быстро и радовал глаз (пока работал).
Моя находка
Как то однажды, достаточно давно, заметил в одной из рсс упоминание о WSGI интерфейсе. Быстро осмотрел, понял что к чему и благополучно забыл (был занят другими более важными делами). Но тут уж пришел край и занялся я плотно поиском альтернативы системы размещения, которую я использовал. Тут как нельзя лучше подвернулся пост Пираньи в котором он упоминается mod_wsgi для nginx, нагрянули воспоминания, была поднята "подшивка" рсс (желтые звездочки в ридере рулят:) ) и начался процесс глубокого изучения этой штуки под названием wsgi.
Замечания того же Пираньи, что модуль для nginx'а ещё ...
Недавно встала задача реализовать один сервис(аналог cron) на питоне. Для души так сказать. Одна из подзадачь: организация хранения данных. При первой итерации было решено использовать SQLite бэкэнд. Поскольку одним из требований к сервису был малый объем занимаемой памяти в процессе работы, т.к. ресурсы моего впс ограничены. Но после маленьких испытаний я понял, то SQLite не очень интересен для меня, как для вечно что-то новое пробующего разработчика, и не так уж и лайт, да и ничего нового. Подумал, а почему бы не использовать какой-нибудь из ORM движков. Стал пробовать и SQLAlchemy и SQLObject. Но эти варианты отпугнули своей тяжеловесность, хотя и интересны в плане изучения не джанговского ORM.
И вот однажды, на одном из регулярно читаемых мной форумов заприметил упоминание одной очень занятной библиотеки buzhug. Как обещают её авторы - мне не надо будет писать SQL запросы, а придется писать list comprehensions or generator expressions. Заманчиво и интересно.
Попробовал пример из туториала. Понравилось ещё больше. Всё просто и прозрачно. Решил остановить свой выбор на этой библиотеке и познакомиться с ней поближе.
Когда сервис был завершен в своей первой редакции, я осознал, что сделал правильный выбор. Код получился лаконичным и действительно без SQL запросов. Работать с данными удобно. Немного напрягло то ...
Недавно заприметил один, как мне показалось, занимательный снипет. Это простая реализация конструкции switch/case конструкции для джанго шаблонов. Хотя позиция разработчиков джанги, что шаблонный язык(хотя они говорят даже, что это не язык вовсе) должен быть максимально прост и не напрягать дизайнера/верстальщика своими наворотами. Но такая конструкция из привычный языков программирования высокого уровня вполне была бы к месту.
В базовой поставке кроме вариаций на тему if - тегов условий нет. Вот этот снипет и пытает расширить семантику шаблонизатора в "условном" направлении. Но в нем отсутствуют такие вещи как: default значение и множественный(не правильное наверно слово подобрал) кейс.
Я решил немного доработать и избавить реализацию от ограничений.
Вот мой вариант(файл можно взять отсюда):
from django import template
register = template.Library()
@register.tag
def switch(parser, token):
"""
Switch tag. Usage::
{% switch meal %}
{% case "spam" %}...{% endcase %}
{% case "eggs" %}...{% endcase %}
{% endswitch %}
Note that ``{% case %}`` arguments can be variables if you like (as can
switch arguments, buts that's a bit silly).
"""
# Parse out the arguments.
args = token.split_contents()
if len(args) != 2:
raise template.TemplateSyntaxError("%s tag tags exactly 2 arguments." % args[0])
# Pull out all the children of the switch tag (until {% endswitch %}).
childnodes = parser.parse(("endswitch",))
# Remove the {% endswitch %} node ...
И так, поскольку этот блог является примером проекта написанного на django, то я пожалуй расскажу про его техническую реализацию.
Описание:
- VPS от FirstVDS.ru
- Сервер 192МБ RAM(мне кажется, что это очень важная деталь)
- На том же аккаунте крутится ещё один сайт.
- Python 2.5
- Nginx в роли прокси к threaded flup fastcgi серверу
- Django trunk
- Планируется индексирование контента с помощью xapian. В процессе разработки. Есть плохая реализация. Сейчас провожу рефакторинг
- дополнительные библиотеки:
- PIL - для обработки изображений
- pytils - для создания slug'ов с транслитерацией
- pyCaptcha - для капчи в форме добавления комментария и обратной связи.
Инстанс сайта в среднем "отжирает" 25мб. Что как мне кажется достаточно много.
Особенности:
Проект блога состоит только из внешних универсальных модулей: блоги, профайл, обратная связь и т.д. Которые не знают о существовании друг друга. Это очень характеризует возможности django в плане способствования четкому модульному разделению.
Исходные коды блога я пока не предоставляю. Хотя это и некая традиция джангистов, предоставлять исходники на обозрение сообщества. Поскольку все приложения из которых составлен блог, применяются(да и разрабатывались вообще) в коммерческих проектах. В последствии, я думаю, смогу открыть исходники, о чем обязательно сообщу.
Обновление от января 2008
- Теперь блог хостится в Tektonic
- Памяти стало 256мб
Но на том же ...
Наверно многие как и я активно следят за изменениями в транке джанго. Но не всегда есть возможность мониторить user groups, а вот самого от trac'а получить нужную информацию можно легко.
Он предоставляет rss фид по всем изменениям в вики. Его я и решил забросить себе в reader. Но поскольку страница BackwardsIncompatibleChanges ( где отмечаются радикальные изменения в джанго ) наверно сама интересная в моём случае, то надо как-то отфильтровать именно изменения в ней.
На помощь пришел сервис yahoo! pipes. Замечательное приложения в сегодняшнем мире повальной агрегации контента из разных источников. В нем легко можно составить пайп с необходимыми фильтрами.
На досуге я решил попробовать этот сервис в действии( я долго ждал реальной задачи, чтобы испытать его ) и вот что у меня получилось:
yahoo! pipes мне очень понравился, поэтому скоро может напишу развернутый пост про него. Всем советую попробовать.