Добро пожаловать в Fabric!
Этот документ - быстрый тур по возможностям Fabric и короткое руководство по его использованию. Дополнительная документация может быть найдена тут.
Что такое Fabric?
Как написано в README:
Fabric — это библиотека для Python (2.5 или выше) и инструмент командной строки для использования SSH при развёртывании приложений или выполнении административных задач.
Более конкретно:
- Инструмент, который позволяет Вам выполнить любую функцию Python при помощи командной строки
- Библиотека подпрограмм (построенная на более низкоуровневой библиотеке), переназначенная для выполнения команд оболочки через SSH легко и по-питонски.
Обычно, большинство пользователей используют обе эти возможности, применяя Fabric для записи и выполнения функций Python или заданий, чтобы автоматизировать работу с удалённым сервером. Давайте на это посмотрим.
Hello, fab
Это не было бы хорошим руководством без стандартного примера:
def hello():
print(«Hello world!»)
Если разместить эту функцию в модуле с именем fabfile.py в вашей рабочей директории, то эту функцию hello можно выполнить при помощи инструмента fab (устанавливаемого как часть Fabric) и будет делать именно то, что Вы ожидаете:
$ fab hello
Hello world!
Done.
Вот и всё. Таким образом Вы можете использовать Fabric как (очень) простой способ сборки даже без импорта какого либо из его API.
Примечание: Инструмент fab просто просто импортирует ваш fabfile и выполняет функцию или функции, которые Вы в нём определили. Тут нет никакой магии — всё, что Вы можете сделать в обычном скрипте Python, можно сделать и в fabfile.
Аргументы задачи
Очень часто полезно передать параметры в процессе выполнения в вашу задачу, как Вы это можете сделать и в обычном скрипте Python. Fabric поддерживает эту возможность при помощи такой нотации: :,=,…. Давайте расширим наш первый пример:
def hello(name=»world»):
print(«Hello %s!» % name)
По умолчанию, если Вы используете команду fab hello — Вы получите тот же результат, что и в раньше; но теперь Вы можете передать и имя, кого приветствовать:
$ fab hello_name=Jeff
Hello Jeff!
Done.
Те, кто уже программируют на Python, могут предположить, что то же самое можно сделать и немного по другому:
$ fab hello:Jeff
Hello Jeff!
Done.
На данный момент, аргумент, который Вы передаёте, в любом случае будет передан как строка, так что Вам могут потребоваться дополнительные манипуляции с полученным значением. В более поздних версиях может быть добавлена система типов, чтобы облегчить этот процесс.
См также: аргументы для задачи
Локальные команды
В примере выше fab всего лишь экономит Вам несколько строк, начинающихся после `if __name__==»__main__»`. Обычно же используется API Fabric, который содержит функции (или операции) для выполнения команд оболочки, передачи файлов и т.д.
Давайте построим гипотетическое Web приложение fabfile. Этот сценарий делает следующее: Web приложение управляется через Git на удалённом хосте vcshost. На localhost у нас есть локальный клон web-приложения.
wxPython in Action. Глава 13. Создание списков (list control) и управление им (Перевод)
В этой главе мы поговорим о:
- создании списков в различных стилях
- работа с элементами в списке
- реакции на выбор пользователем элемента из списка
- редактирование меток и сортировка списка
- создание большого списка (large list)
Django 1.5 и Python 3 (Перевод)
Django 1.5 уже «полностью» поддерживает Python 3, как минимум с технической точки зрения. Поддержка реализована, проверена и работает. Я планирую поместить свой сайт на Django 1.5 / Python 3.3 уже в этом году. Так что в этом смысле всё «готово».
Однако, это не значит, что я рекомендую делать это другим.
У мы даём серьёзные обещания обратной совместимости и мы ещё не на 100% хорошо соответствуем Python 3 API. Есть маленькая (не нулевая) вероятность, что надо будет что-то изменить между 1.5 и 1.6; и мы бы хотели сохранить возможность обратной несовместимости (для Python 3).
Кроме того, есть маленькая (но, опять же, не нулевая) вероятность что есть 1-3 серьёзрых бага в поддержке Python 3 и мы не хотим, чтобы люди с этим столкнулись.
Наконец, значительная часть «хорошести» Django — сторонние приложения, многие из которых не поддерживают ещё Python 3. И это серьёзная проблема для Django / Py3, так как многие сайты используют большое количество сторонних приложений. Так что перед переходом на Python 3 Вы должны решить для себя вопрос: «Готов ли я отказаться от этого приложения или готов портировать его на Python 3 и внести патч?»
В случае моего сайта я к этому готов. Я достаточно хорошо знаю Django, чтобы не бояться потенциальных багов и обратной несовместимости и я могу заняться патчами для Python 3.
Но к большинству пользователей это не относится, так что я надеюсь, что большая часть пользователей Django дождётся 1.6 перед тем, как начать использовать Python 3.
У нас пока нет твёрдых сроков. Я думаю, что 1.6 можно ждать где-то через 6-9 месяцев, но это зависит от слишком многих факторов. Реально срок может быть и год и 3-4 месяца. Увидим 🙂
Автор: Ishayahu Lastov
Исключения в Питоне
Поговорим об исключениях.
Всё нижеизложенное относится к Python 3.3, хотя отчасти справедливо и для более ранних версий.
Для чего они применяются, наверное, все и так прекрасно знают: для передачи сообщений об ошибках внутри программы.
Рассмотрим простейший пример: открытие файла. Если всё нормально — open(filename, 'r') возвращает объект этого самого файла, с которым можно делать всякие полезные вещи: читать из него данные и т.д. Читать
PyBooklet: создание PDF с двумя страницами на листе для печати (Перевод)
Интересная идея.
PyBooklet может быть полезным дополнением к моей утилите PDFBook (части xtopdf), которое может создавать книжки в PDF из набора текстовых файлов, используя при этом меньшее количество бумаги, что хорошо отразится на окружающей среде.
Автор: Ishayahu Lastov
Документация South — Перевод. Часть 3: Дополнительные команды и миграция данных
Последовательная работа с миграцией
Иногда Вы можете обнаружить, что изменения в модели требуют некоторых улучшений. Предположим, Вы определили модель:
class Group(models.Model):
name = models.TextField(verbose_name="Name")
facebook_page__id = models.CharField(max_length=255)
и вы создали и применили миграцию:
./manage.py schemamigration southtut --auto
./manage.py migrate southtut
После чего Вы обнаружили, что: name на самом деле должно быть CharField, а не TextField, а facebook_page__id содержит двойное подчёркивание, а не одинарное, как Вы хотели. Тогда можно исправить эти проблемы и выполнить:
./manage.py schemamigration southtut --auto --update
+ Added model southtut.Group
Migration to be updated, 0026_auto__add_group, is already applied, rolling it back now...
previous_migration: 0025_auto__foo (applied: 2012-05-25 21:20:47)
Running migrations for southtut:
- Migrating backwards to just after 0025_auto__foo.
< partner:0026_auto__add_group
Updated 0026_auto__add_group.py. You can now apply this migration with: ./manage.py migrate southtut
Что произошло? South удалил последнюю миграцию, которая создала модель, но в которой были ошибки, и заменил её новой миграцией, которая уже не содержит этих ошибок.
Стоит так же обратить внимание на то, что та миграция, которая была уже применена, была автоматически откачена назад. Вы можете теперь применить последнюю версию миграции чтобы получить правильный вариант модели:
./manage.py migrate southtut
Можно повторять этот процесс так часто, как требуется, внося необходимые изменения и в итоге получить лишь одну миграцию, где будут учтены все ваши пожелания.
Просмотр текущих миграций
Часто бывает полезно посмотреть, какие миграции были применены на данный момент и какие доступны для использования. Для этой причины есть команда ./manage.py migrate —list. Вот результат выполнения этой команды для нашего проекта:
$ ./manage.py migrate --list
southtut
(*) 0001_initial
(*) 0002_auto__add_field_knight_dances_whenever_able
(*) 0003_auto__add_field_knight_shrubberies
(*) 0004_auto__add_unique_knight_name
Наличие звёздочки (*) говорит о том, что миграция была применена, а отсутствие — что ещё нет. Соответственно, чтобы увидеть только те миграции, которые были применены, воспользуйтесь командой ./manage.py migrate —list | grep -v «*»
Если у Вас есть несколько приложений, работающих при помощи миграций, то можно задать и имя приложения для просмотра миграций только для него.
Перенос данных
До сих пор мы говорили только о «миграции схемы», то есть об изменении колонок и индексов. Но есть и другой тип миграции — «миграция данных».
Миграция данных используется для изменения данных, сохранённых в вашей БД для приведения их в соответствие с новой схемой или предоставления новых возможностей. Например, если Вы сохраняете пароль в виде обычного текста (если это и правда так, то немедленно исправьте это. НЕМЕДЛЕННО!!!) и теперь хотите хранить его в виде солёного хеша, то Вам могут потребоваться эти три шага (причём каждый шаг — это одна миграция):
- Создаём две новые колонки: password_salt и password_hash (миграция схемы)
- Используя содержимое колонки password вычисляем соль и хеш для каждого пользователя (миграция данных)
- Удаляем старую колонку password (миграция схемы)
Как провести первую и последнюю миграцию Вы уже и сами знаете: изменяете models.py и запускаете ./manage.py schemamigration —auto myapp. Главное не удаляйте сразу колонку password, так как нам понадобятся данные из неё для заполнения двух новых колонок (всегда, всегда делайте бакуп вашей БД перед тем, как сделать любое изменение, которое может попортить данные. Потому что однажды именно так и будет).
Давайте возьмём реальный пример. Создадим новое приложение под именем southtut2. Добавим его в INSTALLED_APS и создадим его модель:
from django.db import models
class User(models.Model):
username = models.CharField(max_length=255)
password = models.CharField(max_length=60)
name = models.TextField()
Сде