Показаны сообщения с ярлыком reusable apps. Показать все сообщения
Показаны сообщения с ярлыком reusable apps. Показать все сообщения

6 сентября 2012 г.

Flask-Script или улучшенный manage.py для Flask приложений

Наверное, ни один из моих Django-проектов не обходился без пары-тройки кастомных команд, благо эта возможность была одним из столбов архитектуры Django-проекта. Да, написание кода для этих кастомных команд иногда заставляло схватываться за голову и вопрошать: "Why so hard?", но сегодня я не про это.

А про расширение Flask-Script, которое добавляет схожий функционал уже в Flask-приложения и проекты. Думаю, про это расширения многие наслышаны, но до недавнего времени использовать его было очень затруднительно из-за того, что автор на какое-то время ушел от дел и форки приложения добавляющие и правящие одну или две неточности появлялись как грибы после дождя. Но, хвала высшим силам, в прошлом месяце Шон Линч решил покончить с беспределом и выпустил версию 0.4.0, которая просто не оставляет нам оправданий на вопрос, почему до сих пор Flask-Script не добавлен в список зависимостей нашего проекта.

Использовать расширение очень просто и понятно, инициализируем инстанс менеджера, добавляем кастомные команды, запускаем менеджер, если был вызван Python-скрипт. Пример использования, app.py:

from flask import Flask
from flask.ext.script import Manager


app = Flask(__name__)
manager = Manager(app)

@manager.command
def hello():
    """
    Hello, world!
    """
    print('Hello, world!')


if __name__ == '__main__':
    manager.run()
(env)$ python app.py
Please provide a command
  hello      Hello, world!
  runserver  Runs the Flask development server i.e. app.run()
  shell      Runs a Python shell inside Flask application context.

И так как в дефолтной поставке сразу доступны две команды, runserver и shell, мы можем запускать девсервер даже не добавляя строчку app.run() в наш app.py, удобно.

Но описанный подход подходит только для демонстрационных или маленьких приложений, в реальной же жизни мы переносим инициализацию и/или запуск менеджера в давно знакомый нам manage.py:

from flask.ext.script import Manager

from app import app


manager = Manager(app)


@manager.command
def hello():
    """
    Hello, world!
    """
    print('Hello, world!')


if __name__ == '__main__':
    manager.run()

Лирическое отступление. Если честно, я еще точно не определился с тем как более православно объявлять инстанс менеджера и где размещать все кастомные команды. Внутри, хочется объявлять менеджер в app.py, а затем все команды описывать в commands.py, но пока весь код для кастомных команд хранится именно в manage.py, а вот инстанс менеджера таки инициализируется в app.py. Однако почему-то не могу я такой подход порекомендовать всем, так что остановлюсь пока на варианте автора расширения.

Для любителей классов предусмотрена возможность наследовать команды от Command базового класса, но мне по душе ближе использовать функции, этого ой как не хватало в стандартной поставке Django.

В остальном у проекта есть отличная документация, так что пользуйтесь, пользуйтесь и еще раз пользуйтесь!

21 мая 2012 г.

Наконец-то, django-discover-runner от Янниса Лейдла

Эта была долгая история полная костылей, но кажется лед тронулся и совсем скоро и Django'вский дефолтный тест раннер будет иметь поддержку автоматического поиска тестов в проекте и мы наконец забудем про from test_* import * как про страшный сон.

Само решение и соответствующий тикет появились довольно давно, а вчера Яннис Лейдл (jezdez, один из Django core-team) оформил решение как отдельный пакет, назвав его django-discover-runner. Шаг в верную сторону, но для меня до сих пор не понятно, почему это очевидное изменение не было сделано сразу после включения unittest2 в проект.

21 апреля 2012 г.

Flask-Dropbox

За что нравится Flask, так это за его концепцию reusable apps. По сравнению с Django на создание по настоящему реюзабельного приложения уходит КУДА меньше времени.

Вот, например, вчера вечером захотелось поиграться с Dropbox API, а сегодня уже готов Flask-Dropbox :) Причем готов с тестовым проектом, который позволит вам загружать файлы в Dropbox, просматривать их и удалять.

Пример использования как всегда прост и неказист: импортируем главный класс и блюпринт, инициализируем их, регистрируем блюпринт с указанием префикса для урлов:

from flask import Flask
from flask.ext.dropbox import Dropbox, DropboxBlueprint

import settings


app = Flask(__name__)
app.config.from_object(settings)

dropbox = Dropbox(app)
dropbox_blueprint = DropboxBlueprint(dropbox)
app.register_blueprint(dropbox_blueprint, url_prefix='/dropbox')

Единственное на чем следует детально остановится - это настройки. Так как мы имеем дело с API, без них никуда :)

Во-первых, обязательно нужно будет настроить app.secret_key или просто SECRET_KEY, чтобы иметь возможность использовать flask.session (там будут храниться нужные нам токены).

Во-вторых, нужно будет создать какое-то приложение в Dropbox developers site, если еще нет такого и получить там DROPBOX_KEY, DROPBOX_SECRET и DROPBOX_ACCESS_TYPE. Без указания этих значений - кина не будет и Dropbox(app) отдаст вам ValueError :)

После укзания настроек все просто :)

Аутентификация. dropbox.is_authenticated проверит нет ли валидного access token'а в текущей сессии, dropbox.login_url сгенерирует урл для логина при помощи Dropbox, и наконец dropbox.logout_url отдаст урл, переход по которому вылогинит дропбокс пользователя. После успешного логина получить данные о пользователе можно из словаря dropbox.account_info.

Работа с дропбоксом. После того, как пользователь залогинился вся работа с его дропбоксом будет проходить через проперти dropbox.client, который является прокси к инициализированному инстансу DropboxClient. Полный список доступных методов последнего доступен в документации.

В остальном код доступен на ГитХабе, установить можно с PyPI. Пользуйтесь!

3 апреля 2012 г.

Flask-LazyViews

Мне не нравится использовать декоратор @app.route или метод app.add_url_route для регистрации функций отображения во Flask приложениях и блюпринтах, потому что мне намного больше по душе паттерн ленивой загрузки этих функций :)

Именно так и родился Flask-LazyViews. Пример использования тривиальный, для приложений:

from flask import Flask
from flask.ext.lazyviews import LazyViews


app = Flask(__name__)
views = LazyViews(app)

views.add('/', 'views.home')
views.add('/page/', 'views.page')

Или для блюпринтов:

from flask import Blueprint
from flask.ext.lazyviews import LazyViews


blueprint = Blueprint('test', __name__)
views = LazyViews(blueprint, '.views')

views.add('/', 'test')
views.add('/advanced', 'advanced_test', methods=('GET', 'POST'))

Больше информации доступно как всегда на ГитХабе, установить можно с PyPI.

12 марта 2012 г.

Flask-And-Redis

Понадобилось на днях во Flask проекте докрутить поддержку Redis'а. Плюс, хотелось иметь возможность задавать любые настройки в settings модуле, в итоге появился Flask-And-Redis, так как в Flaks-Redis далеко не все можно настроить и оно не Flask-way инициализируется.

Пример использования есть в репозитории, по быстрому повторю и здесь:

from flask import Flask
from flask.ext.redis import Redis


app = Flask(__name__)
redis = Redis(app)

Вуаля :)

2 декабря 2010 г.

Вставляем виджет карты в Django шаблоны

Только что Mikhail Korobov зарелизил на PyPI незаменимую вещь для любого "корпоративного" сайта или сайта-визитки, разрабатываемого на Django, а именно приложение django-easy-maps позволяющее быстро и безболезненно вставлять виджет карты в Django шаблон.

Кратко о приложении, словами разработчика:

This app makes it easy to display a map for given address in django templates. No API keys, manual geocoding, html/js copy-pasting or django model changes is needed.

И краткий пример использования, взятый из README:

{% load easy_maps_tags %}

<!-- Default map with 300x400 dimensions -->
{% easy_map "Russia, Ekaterinburg, Mira 32" 300 400 %}

<!-- Variable address, custom detail level and custom template -->
{% easy_map address 200 200 5 using 'map.html' %}

Как видим ничего сложного, а формат темплейтного тега без проблем будет понят контент-менеджерами.

18 апреля 2009 г.

Давайте просто поищем!

Как Вы, наверное, знаете поиск и Django - понятия весьма и весьма родные. Каких только приложений не написали для этих целей: и djapian, и и solango, и даже haystack. И это все хорошо, и замечательно, но что делать если нужен простой, совсем простой, поиск по сайту без использования дополнительных поисковых движков? Ответ прост: писать свой очередной велосипед. Что я с удовольствием и сделал!

Итак, знакомтесь: kikola.contrib.basicsearch - приложение для легковесного поиска по любым моделям в вашем проекте.

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

Решение:

  1. Добавляем kikola.contrib.basicsearch в INSTALLED_APPS;
  2. Настраиваем SEARCH_MODELS там же, в settings'ах:
    SEARCH_MODELS = {
       'flatpages.FlatPage': {
           'description': '{{ obj.content|truncatewords_html:20 }}',
           'fields': ('title', 'content'),
           'priority': 0,
           'title': '{{ obj.title }}',
       },
       'sample.SampleModel': {
           'description': '{{ obj.overview|truncatewords_html:20 }}',
           'fields': ('name', 'slug', 'overview'),
           'priority': 100,
           'trigger': lambda obj: obj.is_active,
       },
    }
    
  3. Добавляем kikola.contrib.basicsearch.urls в ROOT_URLCONF-модуль;
  4. ???
  5. Profit!

Иными словами, сейчас запустив тестовый сервер проекта и зайдя на 127.0.0.1:8000/search/ перед нами будет страничка с поисковой формой в которой мы сможем поискать и по всем FlatPage, и по только активным SampleModel.

зы. Код SampleModel:

from django.db import models
from django.db.models import permalink
from django.utils.translation import ugettext_lazy as _


class SampleModel(models.Model):

   name = models.CharField(_('name'), max_length=64)
   slug = models.CharField(_('slug'), max_length=64)
   overview = models.TextField(_('overview'), blank=True)
   is_active = models.BooleanField(_('actived'), blank=True, default=True)

   def __unicode__(self):
       return self.name

   def get_absolute_url(self):
       return ('sample_urlname', [self.slug])
   get_absolute_url = permalink(get_absolute_url)

27 февраля 2009 г.

django-mediafiles 0.2

Сегодня оффициально вышел первый публичный релиз моего проекта, под названием django-mediafiles.

О чем этот проект уже практически понятно из его названия, а чтобы рассеять последние ваши сомнения, посвечу скриншотами того, что он умеет:

Главная страница

Создание новой директории или файла, загрузка файла на сервер

Удаление директории

Предпросмотр рисунков, кода или редактирование текстовых файлов

Надеюсь, что кому-то этот проект пригодится. Enjoy!

30 мая 2008 г.

Django Forum - это реально

Конечно, я знаю, что для Django есть десятки прототипов решений форума, начиная от Cicero и заканчивая Snapboard и Mighty Board. Но не с одним из этих прототипов мне не удалось подружиться быстро и безболезненно. Всегда надо было предпринимать какие-то лишние телодвижения, связанные с пониманием идеологии того или иного форума.

И вот вчера, когда я еще раз просматривал списки доступных решений я наткнулся на статью ForumAppsComparsion в Django Code Wiki. Присмотрелся я к табличке и понял, что не имел дело всего лишь с django-threadedcomments и Django Forum. Благо и одно и второе приложение содержало демо-версии и я решил остановится на них подробней.

django-threadedcomments я сразу отбросил из-за названия и области применения (и даже прикольная демка не спасла его :)).

А вот Django Forum оказался практически сразу же именно тем, что мне и надо было. Простой и не загруженный разными ненужными фишками форум, который быстро настраивается и запускается. Единственным же минусом стало то, что автор решил не утомлять себя интернационализацией движка и именно ей я сейчас и занимаюсь.

И даже то, что этот форум хранится в Darcs репозиторие - это не помешало мне уже практически полюбить его, как когда-то давно я полюбил с первого взгляда маленький и удаленький UseBB форум.

Ну а напоследок, как всегда пачка скриншотов, в этот раз для тех кому лень идти на демонстрцию :)

  • Главная страница моего форума (уже частично локализированного)
  • Список тем в форуме
  • Отображение темы
  • Добавить новое сообщение в тему
  • Отображение профиля

зы. Позволю себе еще одно замечание. Если вы хотите использовать этот форум в STANDALONE режиме - не забудьте папки css, img и js в media/ перенести в media/forum/. А то после django-manage.py runserver Вы вполне можете не увидеть ни стилей, ни рисунков, ни смайлов. А только текст, один текст.

29 мая 2008 г.

Расширение функционала django-admin.py и django-manage.py с помощью django-command-extensions

Вообще, утилиты командной строки django-admin.py и django-manage.py обладают кучей полезных и крайне юзабельных функций (dbshell, runserver, shell и тп), но иногда и их бывает недостаточно.

И именно тогда на помощь приходит django-command-extensions! Это приложение расширяет стандартные возможности утилит Django и теперь вы можете:

  • Создавать скелет приложения по своему шаблону (create_app)
  • Создавать скелет для своей комманды (create_command)
  • Быстро добавлять суперпользователя в базу данных (create_superuser)
  • Быстро создать форму для необходимой модели (describe_form)
  • Создать базу контактов пользователей вашего проекта (export_email)
  • Сгенерировать SECRET_KEY для настроек проекта (generate_secret_key)
  • Создать граф, показывающий связь между моделями (graphviz)
  • Сбросить пользовательский пароль (passwd)
  • Использовать python shell с автоматически загруженными классами всех моделей проекта (shell_plus)
  • Просмотреть все существующие в проекте urlpatterns (show_urls)
  • Показать разницу между определением модели и тем, что присутствует в базе данных (sqldiff)
  • Создать и запустить определенное задание (create_job, run_job, run_jobs)

Остается только поблагадорить разработчиков приложения и перейти к его скачиванию/установке/использованию.

Ссылки: