OAuth и django rest framework

OAuth и django rest framework

Тема избитая, но мне не удалось найти готового решения, которое полностью бы меня устроило. Поэтому пишу сам :).

Итак, у нас есть "одностраничный" веб сайт, который общается с бекендом посредством REST API. Клиентская часть может быть написана с помощью ember, angularjs или чего-то подобного. Бекенд - django rest framework (DRF). И есть тривиальная задача - добавить вход через социальные сети (OAuth протокол).

Как бы это выглядело в случае обычного (олд-скульного) сайта? Пользователь нажимает логин, открывается страница социальной сети ...

Добавлено 2015-07-18

Tornado и pgettext

Tornado и pgettext

Недавно (26 мая 2015 года) вышел релиз tornado 4.2. В него вошли разные дополнения, пожалуй основные из них - модули tornado.locks и tornado.queues. Они перекочевали из пакета Toro, подробное описание процесса от Jesse Jiryu Davis в его блоге.

Здесь же хочу рассказать о другой маленькой функции, которая была добавлена с моей помощью - pgettext.

Она может быть полезна, когда вы создаете перевод для неоднозначных строк. Допустим есть слово "bat", которое нужно вывести либо на ...

Добавлено 2015-06-05

OAuth по шагам

OAuth по шагам

OAuth протокол бывает двух версий: 1.0 и 2.0.

Большинство сервисов сегодня используют версию 2.0, вероятно потому что ее проще реализовать. Так же версию 2.0 можно относительно безопасно использовать в standalone-приложениях (те, которые без сервера).

Для понимания протоколов очень полезно взглянуть на их реализацию. Тут я приведу несколько скриптов, которые общаются с OAuth-провайдерами разных версий. Т.е. все скрипты реализуют функционал клиента (не сервера). Используются только стандартные python библиотеки. Вот почему ...

Добавлено 2015-05-16

Python tips & tricks

Base python tips & tricks

Недавно прочитал книгу Марка Лутца "Learning Python", 5-ое издание. Привожу список самых интересных фишек (по моему мнению) оттуда, что-то вроде конспекта.

  • генерация set'a:

    {x for x in [1,2]}
    set(x for x in [1,2])
    assert set(x for x in [1,2]) == {x for x in [1,2]}
    
  • генерация dict'а:

    {x:x**2 for x in [1,2]}
    dict((x, x**2) for x in [1,2])
    assert {x:x**2 ...

Добавлено 2015-04-30

Слушаем wifi с помощью wireshark

Слушаем wifi с помощью wireshark

Всегда знал, что можно посмотреть сетевые пакеты, которые передаются по wifi сети. Но на практике этого не делал (на работе анализировал сетевые пакеты, но то был не HTTP протокол). Решил восполнить этот пробел, ведь это интересно и полезно. Более стройно выстраивается понимание протоколов TCP-IP и HTTP. Видно, как летят наши пароли и сессии, после такого опыта поневоле начинаешь относиться к безопасности сайта с большим трепетом.

Трафик будем слушать с помощью программы Wireshark. Есть много утилит ...

Добавлено 2015-04-17

Отладка SQL в django тестах

Отладка SQL в django тестах

В django тестах можно замерять количество сделанных SQL запросов:

def test_home(self):
    with self.assertNumQueries(1):
        response = self.client.get('/')
    self.assertEqual(response.status_code, 200)

Если код в контексте assertNumQueries сделает иное количество обращений к БД, чем ожидается (здесь 1), то тест выдает ошибку. Но когда такой тест не проходит, бывает трудно определить лишний отправленный запрос. Для отладки такого случая удобно вывести в консоль отправленные SQL запросы. Далее опишу, как этого добиться.

Кстати, если вы ...

Добавлено 2015-03-04

Tornado i18n and l10n

Tornado i18n and i10n

Статья о том, что такое i18n и i10n и как это реализовать в приложении на tornado. Получилось довольно много букв, но хотелось рассказать доступно обо всем процессе. Сама пошаговая инструкция - во второй половине статьи.

Общие определения

i18n

i18n - сокращение от internationalization. Так называют процесс поддержки разных языков в приложении. Это не сам перевод, а именно техническая составляющая проекта, которая позволяет отображать текст на разных языках, в зависимости от предпочтений пользователя. Обычно реализацией занимается разработчик.

l10n ...

Добавлено 2015-01-31

Timestamp и ObjectId в mongoDB

Timestamp и ObjectId из mongoDB

У каждой записи в mongoDB есть поле _id, которое должно быть уникальным в коллекции. По умолчанию тип этого поля - ObjectId, и оно присваивается автоматически, если поле не заполнено при сохранении.

Давайте рассмотрим, что из себя представляет тип ObjectId.
Это 12 байт, которые состоят из:

  • 4 байта, содержащие количество секунд с начала Unix эпохи
  • 3 байта, содержащие идентификатор устройства
  • 2 байта, содержащие id процесса
  • 3 байта, содержащие счетчик, который стартует со случайного значения

Как видим, первые ...

Добавлено 2015-01-18

Задание url для обработчиков Tornado

Задание url для обработчиков Tornado

В tornado, для привязки обработчиков к url'ам, можно передать список из кортежей (url regex, handler) при инициализации приложения:

application = tornado.web.Application([
    (r"/", MainHandler),
    (r"/some/path/page/(?P<pk>[0-9]+)$", PageHandler),
])

Но не секрет, что гораздо удобнее использовать обертку tornado.web.url, которая позволяет присваивать имена для путей (похожа на django'вский url).

Однако, в паре рабочих проектах, с которыми приходилось работать, эта обертка не использовалась. А так же в некоторых примерах из ...

Добавлено 2014-12-15

Подключение celery к django

Подключение celery к django

Для подключения celery к новому проекту так или иначе приходится подглядывать в предыдущие, чтобы вспомнить необходимые шаги: какие настройки задавать, как запускать, как останавливать и т.д.

Хочу собрать все в одном месте.

Что нужно получить в итоге

  1. Посредством celery добавить возможность django проекту выполнять задачи в фоне, чтобы не загружать текущий python процесс. Пример таких задач: отправка емейлов, работа со сторонним апи, долгие вычисления и т.д.
  2. В качестве брокера используем redis.
  3. В админке ...

Добавлено 2014-11-02

Вложенные SQL запросы в Django

Вложенные SQL запросы в Django

Вы знали, что Django ORM умеет делать вложенные SQL запросы? К своему стыду я узнал это не так давно.

Допустим, у нас есть такие модели питомника (Nursery) и питомца (Pet):

class Nursery(models.Model):
    title = models.CharField(max_length=50)

class Pet(models.Model):
    name = models.CharField(max_length=50)
    nursery = models.ForeignKey(Nursery, related_name='pets')

Нам нужно получить всех питомцев (Pet), которые находятся в заданных питомниках (Nursery). Например в питомниках, title который начинается с "Moscow":

nurseries ...

Добавлено 2014-09-09

Бесплатная футболка от New Relic

Бесплатная футболка от New Relic

New Relic - сервис для мониторинга веб приложения. Позволяет в подробных деталях смотреть статистику работы, где программа тратит больше всего времени, как часто обращается к базе данных и много всего прочего. Для описания этого прекрасного сервиса следует уделить отдельный пост. Здесь же хочу рассказать о другом - как я получил бесплатную футболку от New Relic.

На самом деле, для этого нужно лишь зарегистрироваться и настроить New Relic на работающем сайте. Как и сказано в их предложении.

Конечно ...

Добавлено 2014-05-29

Внешний url для localhost сервера

Внеший url для localhost сервера

Есть замечательная тулза под названием ngrok. Она позволяет привязать URL для вашего localhost сервера!

Например, вы запускаете тестовый сервер django у себя на компьютере:

python manage.py runserver

и этот сервер будет доступен через внешний URL.

Для чего?

Как минимум есть такие задачи:

  • продемонстрировать проект заказчику
  • проверить интеграцию вашего сайта с платежной системой, которая отправляет уведомления. Например paypal, где для получения IPN сообщения нужен работающий URL, даже в sandbox

Как

  • Скачиваем ngrok отсюда
  • Распаковываем скаченный ...

Добавлено 2014-05-09

Отправка писем в django проекте с помощью сервиса mandrill

Отправка писем в django проекте с помощью сервиса mandrill

Отправлять email сообщения с сервера можно просто по SMTP протоколу. Но есть другой способ - через специальные сервисы рассылки. Про один такой, mandrill.com, я немного расскажу.

Преимущества относительно SMTP

  • Подробная статистика отправленных писем. Сколько писем отправлено, кому, когда. Сколько писем открыли, какие ссылки нажимали.
  • Шаблоны писем. Их можно редактировать через сервис mandrill, т.о. образом не нужно ничего придумывать в админке django. В шаблоне можно использовать переменные, задавать тему письма, даже адрес отправителя. Из ...

Добавлено 2014-03-18

Что нужно знать об индексах в mongodb

Что нужно знать об индексах в mongodb

Недавно закончил курс "M101P: MongoDB for Developers" (он периодически повторяется, например следующий стартует в апреле). В процессе прохождения натолкнулся на некоторые интересные моменты.

1. Выбор индекса для запроса.

Допустим у нас коллекция с такими данными:

{ "_id" : ..., "a" : 81810, "b" : 97482, "c" : 44288 }
{ "_id" : ..., "a" : 11734, "b" : 27893, "c" : 19485 }
// и т.д.

Всего 99999 объектов. У коллекции есть индексы:

db.foo.ensureIndex({a: 1, b: 1, c: 1})
db.foo.ensureIndex({c: -1})

Вопрос: какой ...

Добавлено 2014-03-07

Асинхронный Bitcoin RPC клиент на python

Для работы с Bitcoin RPC на python'е есть библиотека Python-BitcoinRPC.

Но недавно мне понадобилось обратиться к API из приложения на tornado. Указанная библиотека работает в синхронном, т.е. блокирующем режиме. Для торнадо было бы намного лучше использовать асинхронную версию. Готовой найти не удалось, поэтому написал свой форк - асинхронный, который использует торнадовский AsyncHTTPClient: https://github.com/st4lk/python-bitcoinrpc-tornado.

Пример (выводит текущее количество блоков в сети Bitcoin):

from bitcoinrpc_async.authproxy import AsyncAuthServiceProxy
from tornado import ioloop ...

Добавлено 2014-01-30

Tornado: пример веб приложения

Tornado: пример веб приложения

Tornado - асинхронный веб фреймворк для python'а. Вначале я приведу краткий перечень плюсов и минусов tornado, а потом расскажу о типовом веб проекте с использованием этого инструмента.

Плюсы tornado

В плюсах и минусах я буду приводить свое личное ощущение по сравнению с django.

1. Асинхронность.

Торнадо представляет из себя бесконечный цикл (ioloop), который постоянно проверяет наличие событий. Все это происходит в одном потоке. К примеру кто-то обратился по адресу /home/. Допустим в качестве обработчика этого ...

Добавлено 2013-12-29

Django проект: с нуля до работающего сервера

В этом посте хочу описать свой опыт создания и запуска django проекта на VPS-хостинге.

Разделим задачу на этапы:

  1. Создание django-проекта
  2. Настройка деплоя
  3. Настройка сервера (установка нужных библиотек)
  4. Деплой проекта

Создание django-проекта

Итак. Пусть наш проект называется myproject. Создадим его на локальном компьютере. Будем считать, что python у нас в системе установлен. Для начала нам понадобятся pip и virtualenv (если еще не стоят).

Создаем виртуальное окружение:

virtualenv venv-myproject

Активируем его:

# на *nix системе
source venv-myproject/bin ...

Добавлено 2013-11-13

Настройки логов для django

Рассмотрим дефолтные настройки логов в django и попробуем их сделать максимально удобными.

Вот что есть в settings.py после команды django-admin.py startproject project_name (django 1.5):

# A sample logging configuration. The only tangible logging
# performed by this configuration is to send an email to
# the site admins on every HTTP 500 error when DEBUG=False.
# See http://docs.djangoproject.com/en/dev/topics/logging for
# more details on how to customize your logging ...

Добавлено 2013-09-26

Python logging на каждый день

В процессе написания программы, скрипта, часто бывает нужно вывести какую-либо отладочную информацию или сообщить о каком-то событии. Известно, что для этих целей есть встроенный модуль logging. Однако обычно у меня бывает так: времени в обрез, а все эти настройки логов (handlers, loggers, formatters и пр.) никак не могу запомнить, и на скорую руку вставляю просто print. Потом, если скрипт используется часто или его надо отдать заказчику - хочется чтобы все эти сообщения записывались в файл ...

Добавлено 2013-08-20