EMACS для Python
Введение
Решил наконец написать статью о том, как настроить EMACS для удобной работы с Python'ом. Ниже список рассматриваемых вопросов:
- Разбиение конфигурации на части
- Пакеты
- Ergoemacs
- Anaconda-mode
Разбиение конфигурации на части
Долгое время мой .emacs представлял собой всего один файл. Естественно, править его было не очень удобно. С течением времени он рос и становился толще, наконец, в определённый момент поддерживать его стало совершенно невозможно. К счастью, я подсмотрел на StackOverflow, как можно разбить его на несколько маленьких частей.
Для подгрузки параметров из других файлов нужно в .emacs написать следующее:
;;; package --- Summary
;;; Commentary:
;;; Main EMACS settings file, load settings from parts.
;;; Code:
(load "~/.emacs.d/fonts.el")
(load "~/.emacs.d/packages.el")
(load "~/.emacs.d/ergoemacs.el")
(load "~/.emacs.d/personal.el");
(load "~/.emacs.d/keyboard.el")
(load "~/.emacs.d/variables.el")
(load "~/.emacs.d/flycheck.el")
(load "~/.emacs.d/rust.el")
(load "~/.emacs.d/python.el")
(load "~/.emacs.d/web.el")
;;; .emacs ends here
Здесь load - функция, выполняющая загрузку указанного файла. Сам файл находится в каталоге .emacs.d/ и называется fonts.el. Туда я положил настройки шрифтов. Затем идёт подгрузка файла, отвечающего за список пакетов. При необходимости недостающие пакеты будут установлены из MELPA, MELPA-STABLE или другого из указанных репозиториев, впрочем, об этом я уже писал ранее.
Я не буду давать рекомендаций по поводу того, на сколько частей нужно разбивать конфигурацию, как эти части называть и так далее, каждый решает сам, потому что, например, несколько дней назад я не видел необходимости выносить настройки шрифтов отдельно, а сейчас решил, что так будет лучше. Как видите, за настройки для разработки на Python'е отвечает файл .emacs.d/python.el, в него я поместил все нужные параметры EMACS'а.
Пакеты
Как я уже говорил, автоматическую установку пакетов я описывал в другой статье, ниже перечислю лишь те пакеты, которые понадобятся, а так же дам краткое описание того, для чего они нужны.
anaconda-mode
Данный пакет служит для поддержки функциональности IDE при работе с файлами Python'а, как то быстрый переход к декларациям, вывод документации и т.д.
company
Данный пакет рекомендуется как более современная замена пакету auto-complete. Ничего не имею против последнего, но лично мне использовать указанный приятнее.
company-anaconda
Автодополнение в режиме anaconda-mode, без этого подсказки работать не будут.
ergoemacs-mode
В общем-то, не скажу, что этот пакет жизненно необходим, но он даёт необходимые удобства, например, упрощает работу с командами, заменяя стандартные хоткеи EMACS'а на свои, более близкие к тем, которыми пользуются нормальные люди, например, комбинации Ctrl+C и Ctrl+V, а так же многие другие начинают работать так, как это принято в подавляющем большинстве современных программ, т.е. копируют и вставляют текст. Подробнее можно почитать на сайте проекта.
flycheck, flycheck-pos-tip
Стандарт де-факто для проверки синтаксиса. Какой именно синтаксис и чем будет проверяться - настраивается. По умолчанию для Python'а используются flake8, pylint и pycompile. Естественно, чтобы данные средства работали, они должны присутствовать в системе.
helm
Система подсказок. Допустим, нажали Вы Alt+X, начинаете вводить lis, а он сразу выдаёт отфильтрованные команды, в которых присутствует данная строка. Можно стрелками выбрать нужную строку и нажать Enter. Умеет подсказывать не только команды, но так же имена файлов, виртуальные окружения и многое другое, легко расширяется. Практически незаменимое средство.
neotree
Пакет просто выводит дерево файлов слева. Можно забиндить отображение / скрытие на горячую клавишу, работать станет в разы удобнее.
python-mode
Базовый пакет для поддержки EMACS'ом Python'а.
py-autopep8
Пакет позволяет применить autopep8 - средство для автоформатирования кода по стандартам. Можно настроить на автоформат кода при сохранении файла. Удобно, хотя в старых проектах, где код писан ногами, порождает тонны баттхёрта у тех, кто будет делать ревью вашего кода.
py-isort
Сортирует импортированные файлы. Можно передать разные настройки. Лично я предпочитаю импорт 1-1, т.е. одна строка - один модуль или класс. Рекомендую, т.к. в этом случае с помощью flycheck будет проще удалять неиспользованные модули - выделил строку, нажал Backspace, сохранил.
pyvenv, virtualenvwrapper
Позволяет EMACS'у видеть виртуальные окружения и нормально с ними работать.
pip-requirements
Небольшой пакет для удобного редактирования файла зависимостей. Если кто не в курсе - файл REQUIREMENTS создаётся в корне Python-проекта и позволяет в одну команду установить все нужные для работы зависимости:
pip install -r REQUIREMENTS -U
В чём плюс данного пакета? Он выдаёт подсказки по именам, подгружая список с PyPi - главного всемирного рассадника питонячьих пакетов.
Установка через pip (от имени root)
pip install autopep8 flake8 isort pylint -U
Ergoemacs
Данный пакет довольно активно развивается и предоставляет кучу удобств. Вся его конфигурация у меня вынесена в отдельный файл, и чтобы далеко не ходить, публикую его ниже:
;;; Package --- Summary
;;; Comment:
;;; Settings for ergoemacs-mode
;;; Code:
(require 'ergoemacs-mode)
;;; Ergoemacs
(setq ergoemacs-theme nil)
(setq ergoemacs-keyboard-layout "us")
(setq ergoemacs-ini-mode t)
(setq ergoemacs-use-menus t)
(setq ergoemacs-smart-paste nil)
(setq ergoemacs-ctl-c-or-ctl-x-delay 0.3)
(ergoemacs-mode 1)
;;; ergoemacs.el ends here
Anaconda-mode
Тут речь не только об anaconda-mode, ниже приводится весь файл настроек для Python. Надеюсь, комментарии помогут в понимании данных настроек
;;; Package --- Summary
;;; Commentary:
;;; Settings for Python
;;; Code:
;;; Импорт необходимых модулей
(require 'py-autopep8)
(require 'py-isort)
(require 'pip-requirements-mode)
;;; Псевдоним для команды pyvenv-workon, пользователи virtualenv оценят удобство
(defalias 'workon 'pyvenv-workon)
;;; Автоматически загружать модуль python-mode, писать в статус баре "Python-mode"
(autoload 'python-mode "python-mode" "Python mode." t)
;;; Применять python-mode для файлов с расширением .py
;;; Использовать интерпретатор python для python-mode
(add-to-list 'auto-mode-alist '("\\.py\\'" . python-mode))
(add-to-list 'interpreter-mode-alist '("python" . python-mode))
(add-to-list 'auto-mode-alist '("\\REQUIREMENTS" . pip-requirements-mode))
(add-to-list 'auto-mode-alist '("\\REQUIREMENTS.txt" . pip-requirements-mode))
(add-to-list 'auto-mode-alist '("\\requirements" . pip-requirements-mode))
(add-to-list 'auto-mode-alist '("\\requirements.txt" . pip-requirements-mode))
;;; Подсвечивать строки, которые обычно используются при отладке
(defun annotate-pdb()
(interactive)
(highlight-lines-matching-regexp "import ipdb")
(highlight-lines-matching-regexp "import pdb")
(highlight-lines-matching-regexp "set_trace()")
(highlight-phrase "TODO")
(highlight-regexp "FIXME")
(highlight-regexp "BUG")
)
;;; В Python-mode автоматически включать anaconda-mode, pdb и
;;; автоматически применять autopep8 при сохранении файла
(add-hook 'python-mode-hook 'anaconda-mode)
(add-hook 'python-mode-hook 'annotate-pdb)
(add-hook 'python-mode-hook 'py-autopep8-enable-on-save)
;;; Перед сохранением так же отсортировать импортированные модули.
;;; Правило сортировки: одна строка - один модуль
(add-hook 'before-save-hook 'py-isort-before-save)
(setq py-isort-options '("-sl"))
;;; python.el ends here
Теперь следует перезапустить EMACS, чтобы он подхватил настройки, и начать работать. Ниже приводится вид моего EMACS'а, когда я пишу на Python.
Конфиг на GitHubDjango 1.8, Python 3, WSGI и Gunicorn
Введение
В данной статье рассказывается, как можно запустить приложение на Django и Python 3 под WSGI. Способ не претендует на звание самого лучшего, замечания по настройке и прочим нюансам приветствуются.
Структура каталогов
Следует создать в каталоге /var/www подкаталог для нашего проекта. Пусть сегодня он будет называться talos. В нём нужно будет создать каталоги для размещения статичных файлов, файлов, загружаемых пользователями, и логов.
cd /var/www
mkdir talos
cd talos/
mkdir static media log
Сам проект будет расположен в виртуальном окружении, которое будет создано чуть позже.
Создание файла запуска
Здесь же, в каталоге /var/www/talos, создадим файл run.bash, который будет запускать приложение, передавая ему нужные параметры.
#!/bin/bash
NAME="talos" # Название приложения
DJANGODIR=/var/www/.virtualenvs/talos/talos # Директорая проекта - путь к виртуальному окружению
# плюс папка с проектом
SOCKFILE=/var/www/sockets/talos.sock # Тут будет лежать сокет
USER=www-data # От чьего имени запускается
GROUP=www-data # Группа для запуска
NUM_WORKERS=3 # Кол-во воркеров, обычно число ядер * 2 + 1
DJANGO_SETTINGS_MODULE=talos.settings # Откуда брать настройки
DJANGO_WSGI_MODULE=talos.wsgi # Имя wsgi-файла для запуска
echo "Starting $NAME as `whoami`"
# Активация окружения
cd $DJANGODIR
source ../bin/activate
export DJANGO_SETTINGS_MODULE=$DJANGO_SETTINGS_MODULE
export PYTHONPATH=$DJANGODIR:$PYTHONPATH
# Если папки для сокета нет, её надо создать
RUNDIR=$(dirname $SOCKFILE)
test -d $RUNDIR || mkdir -p $RUNDIR
# Запуск через gunicorn с передачей параметров
exec ../bin/gunicorn ${DJANGO_WSGI_MODULE}:application \
--name $NAME \
--workers $NUM_WORKERS \
--user=$USER --group=$GROUP \
--bind=unix:$SOCKFILE \
--log-level=debug \
--log-file=/var/www/talos/log/talos.log
Создание виртуального окружения
Последние версии Django написаны на Python 3, да и вообще использовать Python 2 в 2015 году - дурной тон. Ставим нужные пакеты, если их ещё нет:
apt-get install python3-dev virtualenvwrapper -y
Первый пакет нужен для сборки пакетов, поставляемых в исходных кодах (lxml, psycopg2, pillow), второй - для удобного управления виртуальными окружениями. Пакеты установлены, пользователь www-data в системе. Пришло время создать окружение и поставить нужные пакеты:
mkvirtualenv talos --python=/usr/bin/python3
workon talos
В результате в каталоге для виртуальных окружений (у каждого пользователя свой, по умолчанию называется .virtualenvs) будет создан подкаталог talos. В нём будут размещены необходимые для работы с окружением скрипты и несколько других каталогов. Разместим наш проект внутри каталога /var/www/.virtualenvs/talos.
Далее следует поставить в окружение все необходимые пакеты, требуемые для запуска проекта, а так же пакет gunicorn. При необходимости стоит так же обновить pip, его последние версии умеют кэшировать скачанные пакеты.
Не забудьте создать статику и при необходимости подкорректировать файл настроек приложения.
Запуск через supervisor
Если supervisor ещё не установлен, пришло время это сделать:
apt-get install supervisor -y
Настройки хранятся в каталоге /etc/supervisor. Главный файл называется supervisor.conf, файлы для запуска приложений следует расположить в каталоге /etc/supervisor/conf.d/, указав расширение .conf. В нашем случае файл будет лежать по пути /etc/supervisor/conf.d/talos.conf
[program:talos]
command=/var/www/talos/run.bash
user=www-data
group=www-data
autostart=true
autorestart=true
redirect_stderr=true
stdout_logfile=/var/www/talos/log/supervisor.log
Когда файл будет создан, следует обновить данные Supervisor'а:
supervisorctl update
При необходимости перезапустить то или иное приложение следует вызывать не перезапуск системной службы supervisor, а давать команды supervisorctl:
supervisorctl update # Перечитать файлы конфигации приложений
supervisorctl start talos # Запустить приложение talos
supervosorctl stop talos # Остановить приложение talos
supervisorctl restart talos # Перезапуск приложения talos
supervisorctl status # Посмотреть статус всех приложений
supervisorctl ДЕЙСТВИЕ all # Выполнить ДЕЙСТВИЕ со всеми приложениями, например, перезапуск
Если всё сделано правильно, приложение будет запущено, а в каталоге /var/www/sockets/ появится файл сокета talos.sock (как было настроено в файле run.bash).
Подключение к nginx
Всё, что нужно теперь сделать - указать nginx путь к сокету и откуда брать статику для проекта. В общем-то, всё довольно просто. Nginx лучше ставить из официального репозитория проекта, а не из Debian'овского, там пакет не обновляется годами.
apt-get install nginx -y
Все настройки в каталоге /etc/nginx, главный файл - nginx.conf, настройки для сайтов в .conf-файлах, лежащих в каталоге /etc/nginx/conf.d/.
Создадим файл настроек, общих для всех сайтов: /etc/nginx/proxy_params.conf:
proxy_redirect off;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Url-Scheme $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
client_max_body_size 20m;
client_body_buffer_size 1m;
proxy_buffering off;
proxy_send_timeout 180;
proxy_read_timeout 180;
proxy_connect_timeout 180;
proxy_buffer_size 4k;
proxy_buffers 32 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 1m;
add_header X-Frame-Options "SAMEORIGIN";Возможно, данные настройки придётся доработать исходя из реальной конфигурации сервера. Здесь я на этом останавливаться не буду. Переходим к созданию файла конфигурации для нашего проекта:
upstream talos {
server unix:/var/www/sockets/talos.sock fail_timeout=0;
keepalive 30;
}
server {
listen 80;
server_name talos.lo;
keepalive_timeout 3;
access_log off;
error_log /var/www/talos/log/nginx_error.log crit;
location / {
proxy_pass http://talos/;
include /etc/nginx/proxy_params.conf;
}
location /static/ {
alias /var/www/talos/static/;
expires 3d;
}
location /media/ {
alias /var/www/talos/media/;
expires 3d;
}
location ~* \.(7z|jpg|jpeg|gif|png|ico|css|bmp|swf|js|html|txt|doc|docx|pdf|rar|xls|xlsx|zip)$ {
root /var/www/talos/;
expires 3d;
add_header Cache-Control: public;
access_log off;
error_log /var/www/talos/log/nginx_static_error.log;
}
}
Перезапустите nginx, тобы он подхватил новый конфигурационный файл. На этом всё.

