Публикации с меткой «web»

Блог python на хабрахабре

Python / Вышел Tornado Web Server 2.0 RC

Основные изменения:


  • Автоматически добавляются escape-символы при выводе в шаблоны
  • Стандартная реализация AsyncHTTPClient теперь simple_httpclient.
  • Поддержка Python 3.2.


Минорные изменения:


  • Новые теги шаблонизатора:
    — {% autoescape ...%} управление добавлением escape — символов
    — {% raw… %} убрать escape-символы
    — {% module… %} для вызова UIModules
  • {% module Template(path, **kwargs) %} теперь может быть использовано для вызова другого шаблона с независимым пространством имен
  • Все вызовы IOStream callbacks теперь осуществляются напрямую в IOLoop через add_callback.
  • HTTPServer теперь поддерживает IPv6. Для отключения нужно передать параметр family=socket.AF_INET в HTTPServer.bind().
  • HTTPClient теперь поддерживает IPv6, если у запроса установлен параметр allow_ipv6=True
  • RequestHandlers теперь может использовать кодировки, отличные от utf-8 для параметра запроса путем переопределения decode_argument()
  • Улучшена производительность, особенно для приложений, использующих много IOLoop timeouts
  • HTTP OPTIONS метод теперь не требует XSRF token.
  • Вывод в JSON (RequestHandler.write(dict)) теперь устанавливает Content-Type application/json
  • вычисление Etag теперь может быть настроено или отключено путем переопределения RequestHandler.compute_etag
  • USE_SIMPLE_HTTPCLIENT больше не поддерживается, вместо него используйте AsyncHTTPClient.configure.

Берем на GitHub

Копилка опыта

Хостинг для Python

Это мой первый пост в котором не будет ни одной строчки кода. Но тем не менее я не буду отходить от тематики блога. Речь пойдёт о веб проектах на python, точнее о хостинге для них. Не смотря на преимущество в быстродействии и удобстве разработки python, в сфере веб программирования малых и средних проектов, в популярности [...]


Ростислав Дзинько

Как перейти c PHP на Python


Вступление
На форуме python.su, в жизни которого я активно участвую начали появляться темы о том, как перейти с php на python. Естественно, здесь я буду рассматривать только веб-разработку.
В этой статье я бы хотел рязъяснить некоторые моменты, чтобы php разработчикам, которые все-таки решили начинать разрабатывать веб-приложения на python было понятно, что да как.

Как работает php?
Для начала, примем во внимание, что PHP изначально задумывался и разрабатывался исключительно как язык для веб-разработки, и в 99.9% случаев для этого и используется (можно, конечно, писать и GUI-приложения, например, для этого есть GTK-биндинги).

Говоря о том, как работает PHP? я имею в виду то, как принято в большинстве случаев разрабfтывать веб-приложения на PHP. Я не буду углублятся в устройство интерпретатора, расширения, MINT, и т.д. Для пущей простоты примем интерпретатор PHP за некую отдельную сущность. В общем случае, все происходит примерно так:
То есть в самом простом случае, мы создаем html страницу, внутри которой находятся блоки PHP-кода, обрабатывающие запрос и генерирующие динамическое содержимое страницы. Первое, что PHP-программисты при переходе на python обычно делают (по крайней мере те, которые пользуются веб-сервером Apache):
  1. Ставят на Apache mod_python.
  2. Конфигурят директорию в httpd.conf.
  3. Добавляют туда скрипт с содержимым: print "Hello, world!".
  4. Запускают браузер и указывают URL якобы скрипта, например: "localhost/hello.py".
Такое - не работает.

Так что же насчет Python?
Опять же таки вернемся к истории. Исторически и практически Python является языком общего назначения, то есть не нацелен на какую-либо узкую область решения задач. Поэтому он не обладает встроенными средствами работы в веб-среде, как, например, работа с http-сессиями (в отличие от php). Поэтому вариант "создать страничку -> добавить блоки python-кода внутрь" не проканает.

Как разрабатываются веб-приложения на Python?

В отличии от PHP в Python нет стандартных механизмов работы с веб окружением (куки, сессия, и т.д.). Каждый фреймворк и подход имеют свои библиотеки для работы с этими вещами.

Вариант 1. Почти как в PHP. Называется это Python server pages - проект умер в зародыше, а кто так пишет подвергается в Python-сообществе остракизму. Возможен благодаря mod_python. Более детально можно почитать здесь.

Вариант 2. WSGI (web server gateway interface). Являет собой стандарт взаимодейтсвия веб-сервера и веб-приложения Python. В качестве веб-сервера можно использовать Apache с mod_wsgi, nginx с uWsgi, CherryPy и другие. На базе этого стандарта работают многие фреймворки для веб-разработки, в том числе и популярнейший из них - Django. В общем случае, для того, чтобы разрабатывать веб приложения, вам нужно обратится к документации к одному из этих фреймворков. Вот несколько из них:
Вариант 3. Неблокирующий веб-сервер и фреймворк к нему, которые написаны на Python. Имеют свои специфические API. Примеры:
  • Tornado
  • Zope3
  • Twisted (это скорее средство построения фреймворков и серверов)
Данные фреймворки написаны в стиле событийно-ориентированного программирования.

От себя
От себя порекомендую для начала разработки веб-приложений на Python обратится к одному из простых фреймворков, так называемых, микрофреймворков, например, Flask.

Полезные ссылки

Ростислав Дзинько

Встроенный Django сервер тормозит на Windows 7


Столкнулся с такой вот проблемой, что встроенный сервер Django очень долго обрабатывает запросы в операционной системе Windows 7. Ситуация примерно такая. Запускаем сервер:
python ./manage.py runserver 127.0.0.1:3333
Заходим на сайт:
http://localhost:3333/
После этого получаем контент только после долгой задержки, что не очень приятно в процессе активной разработки или тестирования сайта. Оказывается, проблема возникает из-за, кто бы подумал, IPv6, так как понятие localhost в контексте наличия разных протоколов уже не такое однозначное. Поэтому делаем 2 шага:

1. Раскомментируем строчки (у кого они не раскомментированы в C:/Windows/System32/drivers/etc/hosts)
127.0.0.1 localhost
#::1 localhost
2. Заходим на сайт не через localhost, а по 127.0.0.1.

Удачного джангирования!

Ростислав Дзинько

Статика и девелоперский сервер на большом Django-проекте


Что есть девелоперский сервер?
Хотел бы поделиться одним своим наблюдением насчет работы со статикой сервера django, который из коробки, и, собственно, не рекомендуемый для использования в production-среде. Для простоты использования статических файлов, то бишь всяких там стилей, картинок и клиентских скриптов, разработчики django-фреймворка втулили некое представление:
django.views.static.serve
Наверное большиство django-программистов используют эту вещь в работе, как и девелоперский сервер:
python ./manage.py runserver :
Более того, по статистике djangosites 1.2% пользователей не заморачиваются со всякими там инжиниксами, и апачами, и публикуют свои приложение таким вот нехитрым способом.

Проблемка
При этом всем, наверное, немногие сталкивались с тем, даже в довольно крупных проектах, что девелоперский сервер зависает на каждом втором-третьем запросе, что не просто раздражает, а делает разработку практически невозможной. С одной из причин такого зависания я недавно столкнулся. А дело было в статических ресурсах, которые должны были отдаваться клиенту, но по объективным причинам не отдавалий, то есть на каждый запрос по требованию картинки, скрипта, и т.д. приходил ответ 404. Так вот, если таких ресурсов накопится 20-30, сервер виснет уже на 2-3 запросе.

Вместо заключения
Причина этого кроется в том, что над такими проблемами с сервером никто не заморачивается, так как для работы в production-среде он не предназначен, и уж тем более для обслуживания статики.

Копилка опыта

Вывод массива в html таблицу (php)

Просмотрел свои последние посты и понял что сильно ушёл в python. Язык он конечно достойный но не единственный . Тематику webpy я обязательно продолжу но как нибудь потом. Очень часто несмотря на мои личные предпочтения мне приходится работать в php. В основном это веб приложения. Даже не в основном а именно только они . Ну [...]


Ростислав Дзинько

Django: подлый request.is_ajax()

Наверное все, ну, или почти все Django-разработчики сталкивались с потребностью использовать Ajax в своих проектах. Нет, я не буду рассказывать об ajax в Django вообще, а только о замечательном методе is_ajax() объекта request, который, как известно, передается параметром в обработчик вида. Насколько мне известно по своему опыту и по опыту моих знакомых часто с ним возникает один замечательный казус. Давайте взглянем на следующие строчки кода:


def my_view(request, *args, **kwargs):
...
if request.is_ajax:
...


def my_view(request, *args, **kwargs):
...
if request.is_ajax():
...


Как вы успели догадаться, правильной является вторая запись. Примечательно то, что название метода так и подкупает подумать, что это не метод, а свойсто, то бишь @property, а первый вариант всегда будет возвращать True в условии. Не попадайтесь =).

Блокнот разработчика

DevPoint 2

Итак — Devpoint2. Для начала — небольшое вступление: конференция проходила в конгресс-холле отеля «Новосибирск», организация мероприятия на уровне, обстановка и сопутствующие плюшки в виде кофе/чая/плюшек/обедов/виски порадовали.


Отдельно порадовали две замечательные барышни (aka поэтессы) в цветах и тегах основных тезисов мероприятия. Народ с воодушевлением использовал живой элемент декора по прямому назначению — фотографировался с дамами. Чему они, собственно, и способствовали.
Из минусов — немного огорчил доклад Владислава Семенова, посвященный MongoDB. На мой вкус — неуверенно, слегка поверхностно. Мало цифр и хороших примеров. Аудитория временами скучала.
Вообще, если по чесноку, чувствовался разрыв между новосибирскими докладчиками и гостями. Видимо сказывается опыт публичных выступлений.
Я же, в свою очередь, провёл большую часть конференции в компании ребят из Unigine и Константина Каплинского, CEO Glavsoft и по совместительству — разработчика TightVNC
Со слов присутствовавших (сам я в это время был на докладе Ильи Кантора) во время доклада, посвященному IE9 и всем тем новым проблемам, которые он доставит не одному поколению верстальщиков, чувак на инвалидном кресле встал и пошел:
А теперь по-порядку:
Владислав Семенов (Taba.ru, Новосибирск)«Бинго-бонго любит Mongo». Личная оценка — 3/5. Можно лучше, аудитория местами спала или просыпалась. Местами сбивчиво. Вкусные штуки MongoDB не казались такими вкусными и волшебными, какими их презентовали ребята из 10gen. Тренировать ораторский скилл однозначно.
Илья Кантор (Javascript.ru, Москва)«Кросс-доменная авторизация для DDOS-устойчивого сайта (Redis + Varnish+ Javascript)». Всё круто, быстро, стотыщмиллионов запросов, отсечение ботов, отсечение паразитного трафика, руление кэшем, но некоторые велосипеды лучше не изобретать. Это относится к предложенному решению. Возможно, я не исключаю, что в реалиях Ильи это было единственным верным решеним. Но в моей практике django такие конструкции не имеют прецедентов для появления. И да — такое решение ни разу не гибко. Непонятно как поддерживать, человек, пришедший в проект присядет однозначно и на продакшне абстрагированном от разработчика это потребует дополнительного административного ресурса. Пока что вижу больше минусов, чем плюсов.
Максим Лапшин (Evil Martians, Москва) — «Организация видеотрансляций в интернете». Ёмко, точно, честно, просто. И да, это всё работает. Тема наинтереснейшая. Применение технологии — шире некуда. От вещания потока с вебкамеры, нацеленной на любимую сраную кошку до онлайн-киношек и в дальнейшем — абонированию игр с переносом обсчета графики на сервер и доставки конечного видео/звука/интерактива клиенту. Но даже это — далеко не всё.
Евгений Степченко (Percona Inc, Новосибирск) — «Percona Server — MySQL на стероидах». Пропустил начало, от посещения продолжения меня честно отговорили. На самом деле я бы таки пошел. Но я больше люблю Postgres и NoSQL решения. Исторически так сложилось и это меня вполне устраивает. В общем-то не жалею, ибо пропустил я этот доклад увлёкшись общением с Максом Лапшиным. Ибо erlyvideo. Ибо есть идеи, нужны были практические советы взлетит/не взлетит и интересовали планы и направления дальнейшего развития.
Кирилл Коринский (RooX, Санкт-Петербург) и Олег Царев (Percona, Санкт-Петербург)«Сравнительный анализ хранилищ данных». Парни проделали колоссальную работу по сравнению/анализу/выявлению узких мест различных хранилищ данных. SQL/NOSQL — варинты применения, связки. Вопросы/ответы порадовали глубиной знания, непосредственностью и здоровым цинизмом.
Андрей Аксёнов (Sphinx, Воронеж)«Sphinx 2010». От и до Андрей жег. Как я уже отметил в тви — жег напалмом. Более ярких и искрометных докладов изобилующих тех. подробностями, примерами из опыта, юмором, матами и непосредственностью докладчика я в своей жизни не видел. Честно. Хочу видео этого и завершительного доклада по теме «Как не писАть».
По сфинксу всё ясно. Продукт вполне зрелый, но куда расти всё же есть. Roadmap-ы, ожидания, нюансы, немного сравнений. Обсудили пару моментов с юзабилити апи. Буду писать фич-реквест в трекер проекта, ибо есть о чём.
«Как не писать» — второй доклад Андрея. Как говорится — в каждой шутке есть доля шутки. Рекомендации и личный опыт по части, что оптимизировать, а что нет. Когда же остановиться в стремлении к идеалам и начать решать проблему. Как не включать мозг, а работать. Необходимый минимум для программиста. Тесты, рефакторинг. Не тестировать. Тестировать. Не бояться копипасты. Бороться с копипастой. Буду добиваться видео его докладов. Круто как и в первом докладе. Зал рукоплескал раз несколько.
Александр Орлов (Happy-PM.com, Санкт-Петербург) — «10 ошибок начинающих ИТ менеджеров». Разбор ошибок и способов их избежания при росте из инженера в руководителя. Живо, с отсылкой к первоисточникам и авторитетам. Примеры личного топтания граблей. Интересно. Всем, у кого в планах карьерный рост — слушать.
Сергей Чикуенок («Аймобилко», Москва)«Рабочий процесс при разработке клиентской части приложения в средних и малых проектах, workflow в JS, CSS (структура каталогов, дизайн кода, паттерны, принципы построения проекта, взаимодействие с CSS, структура CSS. Хуйня. Полная. Забивание гвоздей микроскопом. Технологии 20-го века. Единственное, для его может послужить такой доклад — руководство «как не надо делать». Не выдержал и ушел в кулуары.
Игорь Сысоев («Рамблер», Москва)«Масштабируемая конфигурация nginx: конфигурация, которую легко поддерживать». Доклад начался с овации. Автор и разработчик nginx. Это много. Создать и развивать конкурентоспособный продукт в существующей и давно занятой нише — для этого нужно проделать немало работы. По теме доклада — магия location. Что есть что, несколько хаков, которые, впрочем, описаны документацией. Четкое разделение — какие задачи решает nginx, какие не решает. Мои внутренние вопросы относительно областей и способов его применения нашли свои внешние ответы.
Итог: побольше бы таких мероприятий. На DevPoint, каким он стал — стоит равняться, но стремиться к лучшему не возбраняется. Неформальная обстановка, возможность тесно пообщаться с докладчиком, это всё было. Уже вчера.

Ростислав Дзинько

Замена сигнала m2m_changed для Django 1.1.x


Вот столкнулся с необходимостью использовать в проекте сигнал на изменения связей многие ко многим. Для тех, кто с этим не сталкивался коротко объясню. Вот пример:

"Нужно выполнить некие действия над пользователем в случае, когда его включают в группу, или выключают из нее".

В Django 1.2.x существует замечательный сигнал m2m_changed для обработки таких событий, чего лишена версия 1.1.x, о которой я сейчас и пишу.

Первое, что приходит в голову - писать обработчик сигнала post_save для модели django.contrib.auth.User. Но, попробовав такое сделать, мы увидим, что в обработчике сигнала мы получили изменения в объекте-пользователе, но группы, в которых он состоит не поменялись. Проблема в том, что связь многие ко многим осуществляется через доп. таблицу, и на этом этапе мы не получаем изменения так как они еще не произошли.

Есть разные пути решения проблемы, которые подходят при разных требованиях к задачи.

1. Создаем свой собственный менеджер моделей (django.db.models.Manager)

Данный подход, наверное, получится самым универсальным для данной задачи. Создав свой менеджер, можно переопределить методы add, clear, добавив туда необходимый функционал. Таким образом указываем действия, которые можно выполнить, в одном месте.

2. Запоминаем измененные объекты, и делаем последующую обработку в планируемой задаче.

Этот вариант подойдет только тогда, когда влияние изменений некритичны для работы проекта, и действия могут быть выполнены через определенное время после внесения изменений в объекты.

3. Используем save_model класса ModelAdmin.

Метод save_model примечателен тем, что получает в качестве аргументов кроме модели еще и форму, что позволяет сравнить старое состояние объекта и новое через form.cleaned_data, на основе чего можно выполнять необходимые дополнительные действия. Использовать следует тогда, когда гарантируется изменения модели через админ. часть сайта.

4. Делаем действия в виде или форме при сохранении объекта.

Аналогично предыдущему методу, только такое надо делать во всех формах и видах, которые участвуют в изменении нужного атрибута объекта.

Копилка опыта

web.form (webpy)

Давно я ничего не писал в блог. Лето, жара отнюдь не способствуют повышению мозговой деятельности Но всё же я решил заставить себя, и по просьбам читателей описать создание и управление веб формами. Практически ни одно интернет приложение не обходится без форм. Это своего рода интерфейс взаимодействия пользователя и приложения. В рассматриваемом нами фреймворке за формы [...]


Копилка опыта

web.database (webpy)

В предыдущей статье я довольно кратко описал Python фреймворк webpy, не заостряя ваше внимание на тонкостях реализации. Для обзора этого было вполне достаточно. Теперь же я хочу расширить эту тему, и более подробно рассказать о некоторых инструментах. В этой статье – именно про работу с базой данных. В данный момент ORM webpy поддерживает работу со [...]

Копилка опыта

web.py

Одной из главных сфер применения языка Python является web-программирование. Благодаря своей внутренней красоте и элегантности в реализации алгоритмов, Python продолжает пополнять ряды своих поклонников среди web-разработчиков. На данный момент существует масса фреймворков, популярных и повсеместно известных как django, и не очень, позволяющих быстро и эффективно создавать сайты в интернет практически любой сложности. Какой же из [...]

Копилка опыта

Яндекс.XML Python

Яндекс. Ну кто его не знает Одни его обожают, другие ненавидят. Для одних он масса полезных и не очень сервисов и средство для поиска информации, для других рабочий инструмент. Те кто относятся ко второй категории думаю знают что такое Яндекс.XML. Яндекс.XML — это сервис, позволяющий делать автоматические поисковые запросы к Яндексу и публиковать его ответы у себя [...]

Дневник одного змеевода

Блокировка объектов при редактировании в админке

Одна из недавних встреч питонеров (Moscow Python meetup) была посвещена теме NoSQL. Я отношу скептически к повсеместному переходу на NoSQL, но всё же нахожу ему применение в отдельных задачах. Так, на встрече я рассказал про блокирование редактируемых объектов на базе memcache. Проблема вполне типичная для всех редакторских интерфейсов в CMS. Один и тот же объект могут одновременно начать редактировать несколько пользователей, в этом случае правки одного из пользователей перетираются другим. Более того, иногда возникают ситуации, когда у одного пользователя оказываются открыты несколько окон редактирования одного объекта и он перетирает собственные изменения.
В моём варианте решения при открытии страницы редактирования берётся блокировка (если объект ещё не заблокирован), а затем со страницы периодически шлётся AJAX запрос на её обновление. Ответ может быть как успешный, так и нет, если другой редактор насильно перехватил блокировку. При завершении редактирования или уходе со страницы блокировка снимается. Кроме того, если блокировку не обновлять, то она через некоторое время протухает автоматически — это решает проблему снятия блокировки, хоть и с запозданием, при закрытии окна (падении браузера, выключении питания у компьютера и т.д.). Переменная edit_session необходима для решения проблемы нескольких открытых окон редактирования одного объекта, фактически она содержит идентификатор одного такого окна. Для обновления блокировки используются команды memcache gets и cas, чтобы обеспечить атомарность операций (исключить условие гонки). Ниже приведена серверная часть, слегка переписанная, чтобы оторвать от контекста нашего движка (функции и переменные сделаны глобальными).
import os, logging
from time import time

logger = logging.getLogger(__name__)

class LockError(Exception):
    def __str__(self):
        return 'Problems with object lock'

class LockedByOther(LockError):
    def __init__(self, user):
        LockError.__init__(self, user)
        self.user = user
    def __str__(self):
        return 'Object is already locked by user: %s (%s)' % \
                                (self.user.name, self.user.login)

class LockIsLost(LockError):
    def __str__(self):
        return 'The object lock is lost'

def create_lock(obj_key, user, force=False):
    '''Marks model object as editted. Returns edit session on success or
    raises exception. obj_key is global identifier of object. When force is
    True the current lock is ignored.'''
    CACHE.clear_cas()
    edit_session = os.urandom(5).encode('hex')
    value = dict(edit_session=edit_session,
                 user_id=user.id,
                 time=time())
    if force:
        if CACHE.set(obj_key, value, time=MODEL_LOCK_TIMEOUT):
            return edit_session
        else:
            raise LockError()
    for i in range(3):
        if CACHE.add(obj_key, value, time=MODEL_LOCK_TIMEOUT):
            return edit_session
        old_value = CACHE.gets(obj_key)
        if old_value is None:
            # Should try add() again
            continue
        if not old_value or time()-old_value['time'] > MODEL_LOCK_TIMEOUT:
            # Somebody's lock is already expired
            if CACHE.cas(obj_key, value, time=MODEL_LOCK_TIMEOUT):
                return edit_session
            else:
                continue
        # Somebody holds active lock, no farther attempts
        break
    else:
        logger.error('Failed to lock model object. Problem with memcached?')
        raise LockError()
    lock_user = get_user(id=old_value['user_id'])
    assert lock_user is not None
    raise LockedByOther(lock_user)

def update_lock(obj_key, user, edit_session):
    '''Updates model object lock as being active. Raises exception on
    error. obj_key is global identifier of object.'''
    CACHE.clear_cas()
    for i in range(3):
        old_value = CACHE.gets(obj_key)
        if not old_value:
            raise LockIsLost()
        elif old_value['edit_session']!=edit_session:
            lock_user = get_user(id=old_value['user_id'])
            assert lock_user is not None
            raise LockedByOther(lock_user)
        new_value = dict(edit_session=edit_session,
                         user_id=user.id,
                         time=time())
        if CACHE.cas(obj_key, new_value, time=MODEL_LOCK_TIMEOUT):
            return
    else:
        # No runtime error here since we want to give user a chance to
        # restore lock.
        raise LockIsLost()

def remove_lock(obj_key, edit_session):
    '''Removes lock for model object. obj_key is global identifier of
    object.'''
    CACHE.clear_cas()
    # We can't garuantee memcache's delete method will remove only our
    # lock, so we update the record with empty value and minimal (1 sec)
    # timeout.
    old_value = CACHE.gets(obj_key)
    # It's too late to do something in case of error, so we just ignore
    # returned value.
    if old_value and old_value['edit_session']==edit_session:
        CACHE.cas(obj_key, '', time=1)
Надеюсь, назначение и работа методов понятна из названий и комментариев.
А какие способы используете вы для организации одновременного редактирования объектов?

Копилка опыта

Java Applet на Python

Для тех кто ещё не знаком с Jython хочу рассказать немного об этой весьма интересной реализации языка Python. А точнее об одной из многочисленных его возможностей, создании Java-апплетов – программ исполняемых в окне браузера Web-страниц. В наших руках инструмент обладающий мощью Java и гибкостью, лаконичностью Python. Возможность использование в Python скриптах Java библиотек, например таких как [...]

Метки

.net .NET C# .sort 1.2 2009 2010 404 error admin ajax amazon analytics and apache api archlinux asp.net async asynchronous autocomplete bash blender blog blogengine blogs book bootstrap bot bpython buildout byteflow bzr C c plus plus C++ cache cbv Chaco checkio chrome ci ckeditor class based views clojure closure cms cms с удобной админкой code coding style collectd COM comet competition conference ConfigParser contest Context continuous integration CouchDB coverage CppCMS cpyext cpython crud csrf CSS ctypes curl custom model fields cx_freeze cython database db dbm dbqueries debian debug debugging decorator decorators deploy deployment descriptor design dev devconf developers development diveintopython Django django 1.2 django 1.3 django advent django framework django template django trunk django weblog django-admin-tools django-cms django-compressor django-hosts django-piston django-registration django-sphinx django.admin djangoadvent djangocms djangodash doc documentation drupal e-legion eclipse EGit emacs encoding Enthought epoll erlang event exception ExtJS fabric facebook fastcgi finaloption fixtures fonts forms formset fp framework freebsd freeswitch fs2web ftp fun funcparserlib functional gae gamin gandi generic views gettext gevent gil git github gitosis Google Google App Engine google picasa Google Translate google wave Google Web Toolkit grab grablab greenlet gtd gui haskell hg hgshelve highlighter host hosting how-to howto html html5lib Hudson humor i18n icfpc ide idiomatic image-scripting improvements Internet interpreter ipython ironpython izmenimsya.ru jabber java javascript jenkins jetbrains JIT job jquery json jstree jython kde kiev kiyv kyivpy l10n ldap library libs Life Links linux Linux & Unix LLVM logging logs lxml Mac OS X magic mail markdown Matplotlib Mayavi maybe mediavirus meetup memcache Memcached memory messages metaclass middleware migration mikrotik mkd model models mod_python mod_wsgi mongodb monitoring mptt musicmans.ru musicx mvc my-projects mysql netCDF networkx newforms newforms-admin news nginx Nhibernate nix nose NoSQL numpy oop open source OpenID openoffice opster optimization oracle orm os pagination parsing path patterns pdf PDF-принтер PEP PEP8 performance performance optimization perl personality photo php picture-driven computing PIL pinax pingback pip plasma plone plugin plugins postgresql programming progress bar psycopg2 py2exe pybb pybbm pycamp pycharm pycon pycow pycurl pydev pygtk pylons PyNGL pypy pyqt PyQt4 pyrad pyramid PySide Python Python 2.5 python 2.7 python 3 python c api python speed python-mssql python3 pywinauto Qt Qt4 queue rabbitmq radius raw sql re redis redsolution redsolution cms regexp regular expressions release repoze.bfg RequestContext reusable apps robokassa rss ru ruby ruby-on-rails sample satchmo scalability SciPy scraping screencast search selenium self.error seo server setattr settings setuptools shell sikuli sms snippet socket.io software sorting south sphinx spider sql sqlalchemy sqlite ssh startup step-by-step subdomain subversion svn SyntaxHighlighter system tags tdd tddspry teh drama template templates templatetags test testing thinkpad threading threads tips tips and tricks tools tornadio tornado tornado server tricks tutorial tweepy twisted twitter typography uapycon Ubuntu ucsvlog uml Uncategorized unicode unit test unit testing UnitTest Unladen Swallow upload urllib urls utf-8 uwsgi validation vcs versioning video vim virtualenv Visual Studio vkontakte voip wave web web-devel web-services web-разработка webdev webfaction webkit webpy websockets webtest widget widgets Win API windows Wirbel work wrapper wsgi wxPython wxWidgets wysiwyg xapian xml xmonad xmpp xpath yandex youtube zip zomg zope [cdata[cbv]] [cdata[ci]] [cdata[class based views]] [cdata[continuous integration]] [cdata[django framework]] [cdata[django-sphinx]] [cdata[django]] [cdata[nginx]] [cdata[python]] [cdata[virtualenv]] [cdata[программирование]] автоматизация администрирование администрирование django админка алгоритмы архитектура атрибуты базы данных Без рубрики безопасность библиотеки блоге бот веб-разработка видео Визуализация данных вконтакте Все записи гвидо ван россум граббер графика графы декоратор декораторы дескриптор дескрипторы документация заметки игра жизнь идея интересное киев Клиентам книги конференция личное математика метаклассы модели модули монады морфология мысли невозможное новости о облачные вычисления обо мне Обработка данных оптимизация оптимизация кода Основная лента основы парсинг парсинг сайтов перевод песочница Питон поебень поиск правила кодирования программирование Проектирование производительность работа рабочее размышлизмы Разное разработка разработка приложений разработки регулярные выражения сайт событие события ссылки статьи тестирование тесты Тюмень убунтариум фигня философия формы форум Хабрахабр хакинг хостинг шаблоны шаблоны проектирования эксперимент Эксперименты юмор я пиарюсь Яндекс