Como publicar un paquete python al repositorio pypi
Tutorial para publicar paquetes en el repositorio python pypi
En este post veremos como publicar un paquete de software al repositorio pypi.python.org (Python Package Index), así estará disponible públicamente y para que cualquiera lo instale sólo hará falta usar pip install nombre_del_paquete
.
Si tienes un módulo o paquete python que te ha servido mucho, lo hayas escrito tu o con amigos, puedes compartirlo en el repositorio https://pypi.python.org y así le servirá a cualquiera que lo necesite. En este post veremos el proceso paso a paso, empecemos.
¿ Qué es pypi.python.org ?¶
Pypi.python.org es un repositorio público que alberga software escrito en el lenguaje de programación python. A esta fecha hay más de 129000 paquetes disponibles.
Este repositorio facilita enormente en el desarrollo de software, por que para incluir uno o varios módulos, sólo hace falta utilizar pip en un entorno de sistema o virtual para un programa que estemos escribiendo.
Por ejemplo para este sitio web, utilizo el micro-framework Flask y otros paquetes python, de no ser por pip para instalarlo tendría que posiblemente descargarme el código fuente y hacer una serie de pasos manuales para que esta página web pueda utilizar sus funcionalidades. Pero gracias a pip y el repositorio pypi.python.org para instalar flask se puede hacer comdamente en un entorno virtual:
mkdir nombre_proyecto cd nombre_proyecto virtualenv venv source venv/bin/activate # con la siguiente línea se descargará e instalará todo el framework Flask # en el entorno virtual de nuestra computadora (la carpeta venv) # y estará listo para usarse. pip install flask
Escribiendo el paquete o módulo python¶
Este el paso más largo e importante, una vez tengamos el módulo python funcional es cuando debemos pensar en si lo vamos a compartir con el resto del mundo. Para este ejemplo he escrito un pequeño paquete en python llamado simplemotds.
Rápidamente sobre simplemotds¶
El paquete simplemotds ayuda a obtener un mensage del día y que cambie automáticamente, de ahí el nombre simple motds (motd = Message Of The Day).
Básicamente lo que hace es leer un directorio con archivos donde cada uno tiene un mensaje o consejo del día, al llamar al método getMotdContent()
, este devuelve el contenido del archivo seleccionado para el día de hoy. Al día siguiente este mensaje cambiará automáticamente.
Adicionalmente a este módulo se le puede configurar fácilmente para que el mensaje cambie por ejemplo al cabo de un mes, una semana, una hora o hasta un minuto. La selección del mensaje tambíen puede cambiarse.
Para más detalles puedes ver el código fuente de python-simplemotds y una demostración de cómo funciona se la ve en esta misma página que muestra los consejos para cada día utilizando simplemotds.
La estructura necesaria para subir el paquete python¶
Hay un buen tutorial para empaquetar software python [1] , para el ejemplo de simplemotds, tenemos la siguiente estrucutra:
├── LICENSE.txt
├── MANIFEST.in
├── README.md
├── setup.cfg
├── setup.py
└── simplemotds # esta es la carpeta con el software en si
├── config.json
├── __init__.py
├── messages
│ ├── m1.html
│ ├── m2.html
│ └── m3.html
└── simplemotds.py
Independientemente del módulo python que desarrollemos, son obligatorios los archivos: LICENSE.txt
, MANIFEST.in
, README
y setup.py
. Estos son la meta-data que pypi.python.org usará para identificar nuestro paquete y deben estar un directorio arriba de nuestro módulo. Algo que difiere es que el archivo README debería estar en formato rst según la documentación oficial de python [2] .
El paquete simplemotds es tan simple que sólo tiene un archivo de código fuente simplemotds.py
aunque también tiene otros archivos como config.json
y un directorio messages
donde hay unos mensajes de prueba, por supuesto para que python interprete el directorio como un módulo está el archivo __init__.py
.
setup.py¶
Este archivo es muy importante y se utiliza para configurar la instalación del paquete, para nuestro caso su contenido es:
from setuptools import setup, find_packages setup( name = 'simplemotds', packages = ['simplemotds'], include_package_data=True, # muy importante para que se incluyan archivos sin extension .py version = '0.23', description = 'Configurable package that returns the message of the day (motd)', author='Rodrigo Garcia', author_email="strysg@riseup.net", license="GPLv3", url="https://github.com/strymsg/python-simplemotds", classifiers = ["Programming Language :: Python :: 3",\ "License :: OSI Approved :: GNU General Public License v3 (GPLv3)",\ "Development Status :: 4 - Beta", "Intended Audience :: Developers", \ "Operating System :: OS Independent"], )
Para empaquetar este proyecto usaremos la biblioteca setuptools y es mejor tenerla instalada en el sistema en su versión más reciente, si usamos una distribución de GNU linux basada en debian podríamos instalarlo con sudo apt install python-setuptools
, pero puede que el paquete debian no sea actualizado, en todo caso podríamos utilizar pip.
pip install -U pip setuptools # que instalará setuptools en el sistema
name
: Es el nombre del paquete.packages
: Es la lista de paquetes que contiene nuestro módulo, para el caso de simplemotds sólo existe un paquete que se llama simplemotds.include_package_data
: Por defecto setuptools sólo empaqueta archivos con estensión .py, en este cas se utiliza un archivo de configuraciónconfig.json
y varos archivos de prueba.html
, esta variable debe serTrue
para que sean incluidos.version
: La versión del paquete (debemos cambiarla cada que necesitemos actualizar.description
: Una descripción cortaauthor
yauthor_email
license
: Obligatorio especificar una licencia de software libre o al menos código abierto, puedes revisar esta guía si no sabes cuál escoger.url
: Sitio web donde se puede revisar el proyecto.calssifiers
: Sirven para clasificar apropiadamente tu paquete en pypi.python.org [1] .
MANIFEST.in¶
Este archivo es para especificar archivos adicionales [1] , para este caso queremos incluir el archivo config.json
y los mensajes de prueba dentro el directorio messages/
.
recursive-include simplemotds config.json recursive-include simplemotds/messages *.html
Con esta configuración básica tenemos lo necesario para empaquetar el software python y luego subirlo.
Empaquetando¶
Para empaquetar ejecutamos en el directorio raíz del proyecto:
python setup.py sdist
Lo que ocurrirá será que se interpreta setup.py
se aplican las configuraciones y se leerá el archivo MANIFEST.in
para incluir archivos adicionales. Una vez se termina, todo el módulo python quedará dentro un archivo .tar.gz
dentro el directorio dist
/ que setup creará.
En el caso de simplemotds se ha empaquetado en simplemotds-0.23.tar.gz
, deberíamos revisar en el archivo comprimido si esta todo lo que se requiere.
Subiendo el archivo empaquetado¶
Primero es necesario que tengamos una cuenta de usuario en pypi.python.org, afortunadamente el registro es libre.
.pypirc (opcional)¶
Una vez hayamos creado la cuenta para facilitar el proceso de autenticación con pypi.python.org, podemos incluir las credenciales de la cuenta que tengamos en pypi.python.org en un archivo. Usualmente el archivo debería estar en el directorio HOME del usuario actual es decir $HOME/.pypirc
, luego en ese archivo poner las credenciales de la siguiente manera:
[pypi] username = <usuario> password = <password>
Para que el archvivo este más seguro:
chmod 600 $HOME/.pypirc
Una nota sobre passwords [4] .
Instalando twine para facilitar la subida del paquete¶
Para subir el paquete he utilizado la herramienta twine que ayuda a interactuar con PyPI enviando las credenciales, y subiendo el paquete que preparamos antes al repositorio PyPI.
Twine no viene por defecto con python y por eso hay que instalarlo en el sistema, usualmente se debería poder con sudo apt install twine
, pero en el caso de mi distribución la versión de twine estaba muy desactualizada y al tratar de usarlo retornaba error 401 [5] .
Para solucionarlo he tenido que desinstalar twine del sistema e instalar la última versión estable con pip:
pip install -U pip setuptools twine
Luego confirmar la versión de twine con twine --version
que debería devolver 1.9.1 o superior
Nota: En mi sistema (basado en ubuntu 16) hubo el problema que al desinstalar twine con sudo apt-get purge twine
e instalarlo con pip, la referencia a la nueva versión de twine no se resolvía correctamente, entonces uso whereis twine
que me dice que el binario de twine está en /usr/local/bin/twine
. Para llamar al twine correcto uso /usr/local/bin/twine
seguido de las opciones.
Subiendo el paquete¶
Ahora usamos:
twine upload dist/*
Que subirá a pypi.python.org lo que tengamos en el directorio dist/ que es donde quedó empaquetado nuestro paquete python.
Una vez se haga esto correctamente deberíamos comprobar ingresando a https://pypi.python.org y buscando por el nombre del paquete que hemos subido recién.
Habilitando para que esté disponible usando pip¶
En pypi.python.org es necesario indicar explícitamente que versión de nuestro paquete estará disponible públicamente. Par eso debemos ingresar con nuestra cuenta de usuario al sitio y revisar la página relacionada a nuestro paquete, luego liberarla manualmente. Para el caso de simplemotds, la imagen siguiente muestra como hacerlo.
Como se ve, se listan las versiones que he subido de simplemotds, finalmente para liberar la última versión solo se hace click en Update Releases.
Bien, ahora si desde cualquier proyecto utilizamos
pip search simplemotds
Nos devuelve:
simplemotds (0.23) - Configurable package that returns the message of the day (motd)
Esto indica que el paquete simplemotds se ha subido correctamente al índice de paquetes python https://pypi.python.org y por eso para cualquier proyecto lo podemos instalar con:
pip install simplemotds
Conclusión¶
Puede que subir un paquete la primera vez sea algo tedioso, sin embargo como vimos existen las herramientas necesarias para hacerlo bien y facilitar el proceso.
Si tienes un pedazo de código tuyo escrito en python que funcione bien como módulo, piensa en compartirlo con todo el mundo o también si te gusta un módulo de python en especial haz tu aporte para mejorarlo y que otr@s se beneficien ;)