Этот материал рассчитан на тех, кто уже написал свой модуль для Django и хочет, чтобы его труд оценили.
Я бы хотел пояснить, зачем нужно готовить пакет для python. Как написано на сайте redsolutioncms.org,
мы столкнулись с тем, что какая-нибудь наша библиотека уходит
за ненадобностью, потому что OpenSource сообщество сделално
подобную вещь хоть позже нас, но лучше
Итак, для чего вам нужно опубликовать свой модуль:
Насчёт организации кода сказано много слов. При публикации каждый сам решает, на что обратить больше внимания, на что меньше, а что вообще обойти. Я опишу технологию выпуска модулей в нашей компании, которая, судя по практике, имеет право считаться удобной :)
Все зависимости от других должны быть прописаны в setup.py, зависимость от самой Django мы не прописываем, чтобы при установке её не скачивал easy_install.
В модуле не должно содержаться ни строчки по-русски. В идеале не должно быть комментариев и текстов коммита не на английском. Мы стараемся в общем придерживаться этого идеала. Ко всем модулям создается русская локаль, так что сразу заметно, если что-то не переведено.
Наше слабое место. Тем не менее я категорически настаиваю на наличии тестов у сколь бы то ни было сложных модулей. Существует множество удобных фреймворков для тестов (от Selenium до webtest), пользуйетсь ими на здоровье!
Каждый наш модуль содержит, как минимум, описание в README. Если модуль требует бОльшей документации, то её необходимо предоставить пользователю.
Мы долго размышляли о том, как публиковать версии того или иного модуля. Мы использ��ем трехзначную систему именования версий:
[0].[мажорный релиз].[минорный релиз]
Вместо нуля первой цифрой станет 1, когда мы посчитаем модуль стабильным и неизменным. В гите мы делаем так: для мажорных версий созданы ветки, а для минорных - тэги. Это сделано для того, чтобы при использовании одной и той же мажорной версии модуля можно было получить багфиксы в минорных версиях.
Чем мажорные от минорных отличаются спрашиваете? Между двумя мажорными версиями сохраняется API и структура БД. Минорные версии могут добавлять новые возможности и исправлять ошибки.
Мы стараемся оформлять модули по одному алгоритму:
В корень проекта добавляются в обязательном порядке файлы:
Помимо этого, в __init__.py файле модуля должна быть переменная __version__, которая содержит номер текущей версии модуля. Например
__version__ = '0.1.0'
Текст README проверяйте на валидность , иначе на Python Package Index форматирование не будет отображаться, документация будет в текстовом формате.
Файл MANIFEST.in нужен для того, чтобы в egg-пакет вошли медиа-файлы (шаблоны, стили, js-скрипты)
recursive-include chunks *
include README README.rst DESCRIPTION INSTALL.txt
exclude *.orig *.pyc
setup.py по сути, самый главный файл при публикации модуля. Он определяет всю мета-информацию о пакете, разработчике, лицензии, файлах и т.п. в модуле
# -*- coding: utf-8 -*-
import os
from setuptools import setup, find_packages
# Utility function to read the README file.
# Used for the long_description. It's nice, because now 1) we have a top level
# README file and 2) it's easier to type in the README file than to put a raw
# string in below ...
def read(fname):
try:
return open(os.path.join(os.path.dirname(__file__), fname)).read()
except IOError:
return ''
setup(
name="redsolutioncms.django-myapp",
version=__import__('myapp').__version__,
description=read('DESCRIPTION'),
license="GPL",
keywords="django tag1 tag2",
author="John Doe",
author_email="[email protected]",
maintainer='John Doe',
maintainer_email='[email protected]',
url="http://github.com/redsolution/myapp",
classifiers=[
'Development Status :: 3 - Alpha',
'Intended Audience :: Developers',
'License :: GPL',
'Framework :: Django',
'Environment :: Web Environment',
'Natural Language :: Russian',
'Natural Language :: English',
'Operating System :: OS Independent',
'Programming Language :: Python',
'Topic :: Internet :: WWW/HTTP :: Dynamic Content',
],
packages=find_packages(exclude=['example', 'example.*']),
install_requires=[],
include_package_data=True,
zip_safe=False,
long_description=read('README'),
entry_points={
'redsolutioncms': ['myapp = myapp.redsolution_setup', ],
}
)
Следует привести комментарии к некоторым строкам. Во-первых, данный setup.py подразумевает, что файлы README и DESCRIPTION существуют. Если это не так - опсание будет пустое. Более того, версия будет пустая, если в __init__.py не будет переменной __version__.
Строка packages=find_packages(exclude=['example', 'example.*']), говорит о том, что если в модуле есть папка example, и она является питоновским модулем, то её нужно исключить из пакета - представьте, если дюжина модулей будет импортировать один и тот же модуль example.
Параметр entry_points нужен для интеграции с Redsolution CMS, об этом в статье про интеграцию.
Полная спецификация по параметрам приведена на сайте разработчика setuptools. На самом деле, я наблюдаю тенденцию отчуждения от модуля setuptools в пользу того же , однако мы остановили выбор на стабильной и проверенной библиотеке.
Опубликовать модуль на PYPI очень легко. В первую очередь, вам нужен будет аккаунт на PYPI. Затем, зайдите в папку проекта и наберите
python setup.py register
Для вас создастся страничка проекта. Для загрузки пишите
python setup.py sdist upload
Готово! Ваш модуль на PYPI, можете проверять главную страницу :)