Разработка, HowTo

Разработка на Python с использованием virtualenv

Virtual Environment — полезный инструмент, который позволет держать различные конфигурации зависимостей проектов в разных директориях. Например он решает проблему когда одному приложению требуется версия 1.0 пакета X, а другому — 2.0.

vitrualenv

Главным инструментов будет virtualenv.

$ sudo yum install python-virtualenv

Использование

Создадим окружение

$ cd project_dir
$ virtualenv proj_env

Этими командами мы создадим папку proj_env, которая будет содержать наше новое окружение. В этой папке будет набор скриптов и копия интерпретатора python, который будет использоваться в окружении (окружение использует свой интерпретатор, а не общесистемный).

При создании окружения можно указать, какая версия python нам нужна.

Возможно, что в системе параллельно стоит как python2, так и python3. Выбирать версию при создании окружения мы можем ключем -p. Если ключ не указан, то будет выбрана версия /usr/bin/python.

$ virtualenv -p /usr/bin/python3.4 proj_env

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

$ source proj_env/bin/activate

Теперь мы внутри окружения.

Определеить это можно по изменившемуся приглашению:

(proj_env)тут_старое_приглашение_из_$PS1

Все. Мы внутри окружения. Можно ставить зависимости для нашего приложения.

$ pip install flask flask-bootsrap rq rq-scheduler pymysql

Выйти из окружения можно при помощи

$ deactivate

Теперь мы попали обратно в систему с дефолтными интерпретаторами.

Сохранение информации о зависимостях

Опция —no-site-packages отключает использование глобально-установленных пакетов, что может быть полезно (сейчас это дефолтное поведение virtualenv).

Хорошей идей будет сохранить информацию об установленных в окружении пакетов.

{code lang=»shell»]$ pip freeze > requirements.txt[/code]

После развертывание окружения в новой системе можно поднять все пакеты сразу.

$ pip install -r requirements.txt

Не забываем добавить папку окружения в .gitignore.

virtualenverapper

Еще один полезный инструмент (скорее для разработчиков, а не для деплоя), который позволяет обращаться со со множеством окружений и переключаться между ними.

$ sudo yum install python-virtualenvwrapper

Применение

Добавляем в .bashrc

export WORKON_HOME=~/.envs
source /usr/bin/virtualenvwrapper.sh

Теперь можно создавать окружения.

$ mkvirtualenv proj_env

Активировать окружения.

$ workon proj_env

Выходить из окружения можно так же как это делалось в кготом virtualenv.

$ deactivate

Удалять окружения.

$ rmvirtualenv proj_env

При этом все папки окружений будет расположены в одном месте: папке, которая задана через $WORKON_HOME.

Дополнительные команды

Есть несколько дополнительных команд

  • lsvirtualenv — покажет список созданных окружений
  • cdvirtualenv — перейдет непосрественно в папку окружения
  • cdsitepackages — переведет в site-packages выбранного окруженияч
  • lssitepackages — сделает ls для папки site-packages

Посмотреть полный список команд.

autoenv

Утилита позволяет активировать окружение при входе в папку, и деактивировать при выходе.

$ git clone git://github.com/kennethreitz/autoenv.git ~/.autoenv
$ echo 'source ~/.autoenv/activate.sh' >> ~/.bashrc
Реклама
Обработка текста, Разработка

Python 3+ и окончания строк в файлах

Столкнулся одного теста, который был перенесен с python 2+ на python 3+.

Тест делал следующее:

скачивал файл через python.requests и сравнивал его с эталонным содержимым на диске (посимвольно).

Выглядело приблизительно так

import requests
import sys
response = requests.get(sys.argv[1])
if response.code == 200:
  with open(sys.argv[2]) as f:
    from_storage = f.read()
    from_web = response.text
    assert from_web == from_storage

Да. Все верно. Этот тест не проходил.

И тут была замечена одна странность: файл на диске содержал последовательность crlf, а в coдержимом from_storage этой последовательности не оказало.

А дело все в том, что в python 3+ было введено соглашение на обработку символов перевода строки. И управление работой осуществляется манипулированием параметром newline.

  • On input, if newline is None, universal newlines mode is enabled. Lines in the input can end in ‘\n’, ‘\r’, or ‘\r\n’, and these are translated into ‘\n’ before being returned to the caller. If it is '', universal newline mode is enabled, but line endings are returned to the caller untranslated. If it has any of the other legal values, input lines are only terminated by the given string, and the line ending is returned to the caller untranslated.
  • On output, if newline is None, any ‘\n’ characters written are translated to the system default line separator, os.linesep. If newline is '', no translation takes place. If newline is any of the other legal values, any ‘\n’ characters written are translated to the given string.

В итоге достаточно было указать newline='' как CRLF появились.

Разработка

Python3: feedparser unicode error

Есть расширение universal feed parser и есть у него одна очень неприятная бага: если установлено расширение chardet, то парсинг лент в юникоде ломается.

$ ./rss.py                                                                                                                                                                     Traceback (most recent call last):
File "./rss.py", line 11, in <module>
feed = feedparser.parse(rss_response.text)
File "/usr/lib/python3.3/site-packages/feedparser.py", line 3966, in parse
data, result['encoding'], error = convert_to_utf8(http_headers, data)
File "/usr/lib/python3.3/site-packages/feedparser.py", line 3768, in convert_to_utf8
chardet_encoding = str(chardet.detect(data)['encoding'] or '', 'ascii', 'ignore')
TypeError: decoding str is not supported

Неприятно. Можно удалить chardet, но тогда другие расширения, которые от него зависят будут удалены. В том числе и requests.

Значит надо чинить. Но поскольку баг пофикшен только в транке, а текущая стейбл 5.1.3, то надо обновляться из транка.

$ sudo python3-pip install git+https://code.google.com/p/feedparser/ --upgrade

Или накатить патч руками.

Разработка

Мониторинг обмена данными с serial-портом

Иногда надо сниффать serial-порт на предмет того, что туда пишется/читается софтиной.
Есть сниффер jpnevulator.

jpnevulator --timing-print --tty /dev/ttyACM0

Но он не совсем удобен. Так как он не сниффер на смом деле, а простой ридер-писатель для порта.
Поэтому если запустить его совместно с другой софтиной, то она данных на порту не увидит.

А нам нужен именно сниффер.

Можно создать виртуальный порт с помощью pyserial. И читать/писать данный и реального в виртуальный порт и наоборот (MITM), но стоит ли? 🙂

Воспользуемся strace!

$ strace -e trace=read,write python terminal.py
# тут я вырезал кусок, который относится к питону
write(3, "P", 1)                        = 1
write(3, "P", 1)                        = 1
read(3, "P", 1)                         = 1
read(3, ";\26\225\320\0k,\r\0", 9)      = 9
write(1, "3B 16 95 D0 0 6B 2C D 0\n", 243B 16 95 D0 0 6B 2C D 0
) = 24
write(3, "S\3\377\0\377", 5)            = 5
read(3, "\377\0\377", 3)                = 3
write(1, "FF 0 FF\n", 8FF 0 FF
)                = 8
write(3, "S\5\240\244\0\0\2", 7)        = 7
read(3, "\244", 1)                      = 1
write(3, "S\2?\0", 4)                   = 4
read(3, "\237#", 2)                     = 2
write(1, "9F 23\n", 69F 23
)                  = 6
write(3, "S\5\240\300\0\0#", 7)         = 7
read(3, "\300\0\0Z\0?\0\1\0\0\0\0\0\26\263\3\7\4\0\203\212\203\212\0\3\0\0Z\0\0\0Z"..., 38) = 38
write(1, "C0 0 0 5A 0 3F 0 1 0 0 0 0 0 16 "..., 89C0 0 0 5A 0 3F 0 1 0 0 0 0 0 16 B3 3 7 4 0 83 8A 83 8A 0 3 0 0 5A 0 0 0 5A 0 2F 6 2 90 0
) = 89
write(3, "H", 1)                        = 1
+++ exited with 0 +++

И вот уже вожделенный протокол обмена на экране. 🙂

HowTo

Делаем подсветку синтаксиса для less

Подсветка синтаксиса в lessДефолтный вывод less  в консоли чрезвычайно скучный. И рассматривать километры одинаковых черно-белых листингов утомляет (или зеленых если у вас Ъ-хакерский терминал :)).

Так привнесем же цветность в наши черно-белые терминал.

 $ sudo yum install python-pygments

А затем прописываем в .bashrc

export LESS="-R"
export LESSOPEN="|pygmentize -g -O encoding=utf8 %s"

Кодировку ставим на выбор. Но если чаще всего работаем в юникоде, то и оставляем юникод.

При этом будет подсвечиваться только вывод less, который вызван в дефолтной форме

 $ less filename

Вывод же less, который работает с перенаправленным вводом подсвечиваться на будет. 🙂

Проект pygments.

Найдено в сети

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

Алгоритмы

Python

PHP

  • Парсинг PHP в Go — основа для построения статических анализаторов и других удобных инструментов

JavaScript

Linux

Git

Софт

Arduino/Raspberry Pi и другое железо

Всякое