TLDR: Publicando no PyPI

Publicado em

Já se perguntou como publicar seu próprio pacote Python para instalá-lo com o pip? É menos complicado que parece, e qualquer pessoa pode fazer.

Basta acessar o Python Package Index (PyPI) e criar uma conta na qual irá registrar seus pacotes.

Em seguida crie um arquivo python chamado setup.py alterando os valores que forem necessários:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from setuptools import find_packages, setup

setup(
    name='meu-pacote-python',
    packages=find_packages(),
    version='1.0.0',
    description='Descrição curta do meu pacote',
    long_description='Longa descrição do meu pacote',
    author='Meu Nome',
    author_email='meu@email.com',
    url='https://github.com/usuario/meu-pacote-python',
    install_requires=['dependencia1', 'dependencia2'],
    license='MIT',
    keywords=['dev', 'web'],
    classifiers=[
        'Intended Audience :: Developers',
        'License :: OSI Approved :: MIT License',
        'Natural Language :: English',
        'Programming Language :: Python :: 2',
        'Programming Language :: Python :: 3',
    ],
)

O find_packages é uma ferramenta muito boa para encontrar automaticamente os arquivos que fazem parte do seu pacote qualquer dúvida veja sua documentação clicando aqui.

Os classifiers servem para ajudar usuários a encontrar seu pacote na busca e a lista completa deles pode ser vista neste link.

Empacotando

Antes de publicar o pacote é preciso empacotá-lo e a forma mais simples é fazendo o empacotamento do código fonte rodando:

$ python setup.py sdist

Para já empacotar o código montado rode:

$ python setup.py bdist_wheel

Com isso você terá tudo empacotado e pronto para a publicação na pasta dist/.

Publicando

Para publicar é preciso instalar o twine que é uma ferramenta para publicar pacotes no PyPI:

$ pip install twine

Em seguida basta rodar o seguinte comando:

$ twine upload --username usuario-no-pypi dist/meu-pacote-1.0.0.tar.gz dist/meu-pacote-1.0.0-py2-none-any.whl dist/meu-pacote-1.0.0-py3-none-any.whl

O comando vai pedir a senha e em seguida fazer o upload para o PyPI.

Bônus - Versionamento

Uma prática muito comum é versionar o código e adicionar algumas informações no __init__.py desta forma:

__author__ = 'Meu Nome'
__email__ = 'meu@email.com'
__version__ = '1.0.0'

Adicione este código no setup.py para usar os dados do __init__.py no seu pacote:

import os
import re

package = 'meu_pacote'

with open(os.path.join(package, '__init__.py'), 'rb') as f:
    init_py = f.read().decode('utf-8')

version = re.search(
    '^__version__ = [\'\"]([^\'\"]+)[\'\"]', init_py, re.MULTILINE
).group(1)
author = re.search(
    '^__author__ = [\'\"]([^\'\"]+)[\'\"]', init_py, re.MULTILINE
).group(1)
email = re.search(
    '^__email__ = [\'\"]([^\'\"]+)[\'\"]', init_py, re.MULTILINE
).group(1)
...
setup(
    ...
    version=version,
    author=author,
    author_email=email,
    ...
)

Bônus - README.md como long_description

Quem publica código no github costuma escrever um arquivo readme com a descrição do projeto. Você pode usá-lo para não se repetir na long_description:

with open('README.md', 'rb') as f:
    readme = f.read().decode('utf-8')

setup(
    ...
    long_description=readme,
    long_description_content_type="text/markdown",
    ...
)
Licença Creative Commons

Esta obra está licenciada com uma Licença Creative Commons Atribuição-CompartilhaIgual 4.0 Internacional .