🏗️ Cómo publicar tu propia librería de Python: Guía paso a paso

El objetivo de este tutorial es guiarte paso a paso en el proceso de creación y publicación de tu propia librería en Python. Aunque Python ofrece una biblioteca estándar muy completa, aprovechar las contribuciones de la comunidad en PyPI te permite extender sus capacidades y crear soluciones personalizadas que se adapten a tus necesidades.
La motivación detrás de este proyecto es doble: por un lado, adquirir un conocimiento profundo sobre el proceso de preparación, versionado, construcción y despliegue de paquetes; y por el otro, consolidar un repositorio centralizado de herramientas que funcione como una tarjeta de presentación profesional en el mundo del desarrollo.
🧭 Introducción y primeros pasos
El primer paso es comprender el ecosistema de paquetes en Python, especialmente el rol fundamental que juega PyPI (Python Packaging Index). Este es el repositorio oficial de paquetes de Python, y alberga una vasta colección de librerías, desde implementaciones simples hasta complejas soluciones en áreas como ciencia de datos, inteligencia artificial y desarrollo web.
Al entender cómo se organizan y distribuyen los paquetes en PyPI, puedes orientar el desarrollo de tu librería para que cumpla con los estándares que facilitan su instalación y uso por parte de otros desarrolladores. Además, al prepararla para su publicación, te adentras en prácticas modernas como el versionado semántico y la automatización del despliegue.
Nuestro inicio en el mundo de las librerías lo vamos a tener en la próxima sección donde ya iniciaremos el código fuente que usaremos como base para todo el proceso de tener nuestra propia librería en PyPI.
https://pypi.org/project/rafnixg/
🏗️ Crear la base de tu librería en Python
En esta sección crearemos el código base que usaremos para subir a PyPI, tú puedes usar este código como ejemplo o ser libre de usar el código de tu preferencia, y saltar a la siguiente sección.
Si te quedaste acá el paquete que vamos a crear se llama rafnixg y muestra por consola tus datos personales y por otro lado podrá ser usado en tu propio código para descargar post de tu blog de HashNode usando GraphQL. Este es básicamente mi caso de uso de ejemplo, pero tu librería puede tener las funciones que tu consideres necesarias.

Para lograr obtener este diseño de card vamos a hacer uso de la librería rich que nos ayuda a crear diseños de tablas para la terminal de forma fácil, los invito a revisar el potencial de rich, puede agregar iconos, gestionar paleta de colores, Markdown.
🧪Preparación del entorno de desarrollo
Para este caso hare uso de VSCode pero puedes usar el editor que prefieras, acá lo importante es crear un entorno virtual de Python para aislar las dependencias y no tener problemas en el futuro.
$ python -m venv env
$ source env/bin/activate # Para Linux
$ env\Scripts\activate # Para Windows
(env) $ pip install rich
Lo segundo será crear un archivo .gitignore que nos ayudará a indicar que no queremos que se suba a nuestro repositorio, podemos hacer uso de la siguiente web para generar uno con la configuración para Python.
Create Useful .gitignore Files For Your Project
# Created by https://www.toptal.com/developers/gitignore/api/python
# Edit at https://www.toptal.com/developers/gitignore?templates=python
### Python ###
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
env
.env
/venv
venv
# End of https://www.toptal.com/developers/gitignore/api/python
Debemos recordar que es importante evitar subir archivos con contenido sensibles como API Keys, Claves o algún tipo de información que permita acceso no autorizado.
Luego de esto inicializamos nuestro repositorio de git y creamos nuestra estructura de archivos.
(env) $ git init
📁 Estructura del proyecto
Toda librería de Python inicia dentro de una carpeta, así que para esto cree el directorio rafnixg-lib y dentro creo la siguiente estructura de archivos:
rafnixg-lib/
│
├── src/
│ └── rafnixg/
│ ├── __init__.py
│ ├── __main__.py
│ └── rafnixg.py
│
├── LICENSE
├── README.md
└── pyproject.toml
Todo el código fuente se encuentra de src/ esto no es obligatorio, pero es una buena práctica. Si estas usando tu propio código, dentro de src/ es donde debería ir para mantener la mejor estructura.
En esta sección nos enfocaremos en los archivos de Python y en las siguientes secciones veremos estos archivos especiales LICENSE, README.md, pyproject.toml.
🧾 Crear el archivo principal src/rafnixg/rafnixg.py
"""src/rafnixg/rafnixg.py
RafnixG - Personal Card
"""
from rich.console import Console
from rich.table import Table
class RafnixG:
"""RafnixG - Personal Card"""
def __init__(self):
self.username = "rafnixg"
self.name = "Rafnix Guzmán"
self.position = "Python Software Developer"
self.links = "https://links.rafnixg.dev"
self.web = "https://rafnixg.dev"
self.blog = "https://blog.rafnixg.dev"
self.cv = "https://resume.rafnixg.dev"
self.github = "https://github.com/rafnixg"
self.twitter = "@rafnixg"
self.about = "Experienced software developer with 10+ years of expertise in designing, developing and implementing web systems across various sectors. Backend specialist skilled in Python, Linux, and Git. Passionate about continuous learning and open-source technology."
def __str__(self):
return f"{self.name} (@{self.username}) - {self.position}"
def display(self):
"""Display personal card"""
# Crea un objeto Console para imprimir en la consola
console = Console()
table = Table(
show_header=False, # No mostrar encabezados
title=str(self), # Título de la tabla
highlight=True, # Resaltar la tabla
title_style="bold magenta", # Estilo del título
)
# Agrega columnas a la tabla
table.add_column("Attribute", style="bold", width=16)
table.add_column("Value")
# Agrega filas a la tabla con los atributos y valores de la clase
# Itera sobre los atributos de la clase y los agrega a la tabla
for key, value in self.__dict__.items():
if isinstance(value, dict):
for sub_key, sub_value in value.items():
table.add_row(sub_key, ", ".join(sub_value))
elif isinstance(value, list):
table.add_row(key, ", ".join(value))
else:
table.add_row(key, value)
# Imprime la tabla en la consola
console.print(table)
🧩 Inicializar el paquete con src/rafnixg/__init__.py
"""src/rafnixg/__init__.py
RafnixG - Personal Card
"""
from rafnixg.rafnixg import RafnixG
__version__ = "1.0.0"
🧩 Ejecutar como modulo con src/rafnixg/__main__.py
"""src/rafnixg/__main__.py
RafnixG - Personal Card
"""
from rafnixg import RafnixG
def main():
"""Main function."""
me = RafnixG()
me.display()
if __name__ == '__main__':
main()
🖥️ Ejecutar y probar tu código localmente
Para probar nuestro código debemos movernos a la carpeta src/ y luego correr el paquete como un módulo de Python:
(env) $ cd src
(env) $ ls
rafnixg/
(env) $ python -m rafnixg
Recuerda que si estas usando tu código aquí debes colocar el nombre la carpeta que contiene tu código fuente.
📦 Preparar la librería para ser publicada
📘Documentando nuestra librería
Un README es esencial para cualquier proyecto ya que aquí es donde otros desarrolladores y usuarios obtendrán información sobre tu librería, en este archivo no solo se explica que es y lo que hace tu proyecto, sino que también contiene información de como instalarlo, utilizarlo y contribuir. En una próxima publicación profundizaremos más sobre el README y que debería contener, por los momentos creamos el archivo README.md con el siguiente contenido:
# Rafnix Guzmán - Personal Card (README.md)
## Hi there 👋
This is my personal card [rafnixg.dev](https://rafnixg.dev)

## How to use it? 🤔
Install using pip:
```bash
pip install rafnixg
```
Then run it:
```bash
rafnixg
```
🛠️Configurar el sistema de construcción (build system)
Para preparar nuestra librería para ser publicada en PyPI necesitamos configurar algunas secciones en el archivo pyproject.toml primero debemos indicar el build system que es la parte responsable de crear los archivos que se suben a PyPI, usualmente se usa el formato wheel o sdist.
Nosotros usaremos el setuptools como build system.
# pyproject.toml
[build-system]
requires = ["setuptools>=61.0.0", "wheel"]
build-backend = "setuptools.build_meta"
🗂️ Organizar el archivo pyproject.toml
Ahora agregaremos una sección para configurar información del proyecto, acá es donde indicaremos el nombre de nuestro paquete, recordemos que debemos verificar que el nombre no este usado por ningún otro paquete dentro del ecosistema PyPI.
# pyproject.toml
...
[project]
name = "rafnixg"
version = "1.0.0"
description = "Rafnix Guzman Personal Card"
readme = "README.md"
authors = [{ name = "Rafnix Guzman", email = "rafnixg@gmail.com" }]
license = { file = "LICENSE" }
classifiers = [
"License :: OSI Approved :: MIT License",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
]
keywords = ["personal card", "console"]
dependencies = [
"rich",
]
requires-python = ">=3.9"
[project.optional-dependencies]
dev = ["black", "bumpver", "isort", "pip-tools", "pytest"]
[project.urls]
Homepage = "https://github.com/rafnixg/rafnixg-lib"
[project.scripts]
rafnixg = "rafnixg.__main__:main"
No toda esta información es obligatoria, pero es importante dar la mayor cantidad de información posible sobre nuestra librería, la información mínima que podemos ingresar es
nameyversion.
Las siguientes secciones son importantes por la información que le proporcionan a PyPI:
classifiers: Lista de classifiers de PyPI que ayudan a la búsqueda.keywords: Lista de etiquetas que seran usadas para identicar y categorizar la libreria.dependencies: Lista de dependencias que tu librería necesita, en nuestro caso rich.project.optional-dependencies: Lista de las dependencias de desarrollo.project.urls: Links que relacione a tu proyecto en github o alguna página web.project.scripts: Punto de entrada para tu librería. en este caso el comando serárafnixgy el punto de entrada serárafnixg.__main__:main
Toda esta información hace que en PyPI tu librería se vea mucho mejor y cuando se haga una búsqueda también sea más fácil de encontrar. acá un ejemplo de la información que se muestra en PyPI:

Vemos como también usa el archivo README.md para mostrar del lado derecho la documentación de la librería en PyPI, y los datos del archivo pyproject.toml también se muestran a la izquierda.
Para saber más sobre este archivo de configuración acá esta la documentación.
🔢 Usar versionamiento semántico
Toda librería debe tener un versionamiento para poder tener un control de lo que se publica, existen diferentes esquemas de versionamiento, en nuestro caso usaremos Semantic Versioning que es una forma simple de gestionar el versionamiento formado por 3 grupo de números, ejemplo: MAJOR.MINOR.PATCH las recomendaciones para cambiar estos números son:
MAJOR: Cuando tus cambios son tan grandes que rompen tu API anterior.
MINOR: Cuando agregas nuevas funciones y todo se mantiene compatible, Vuelve a 0 cuando MAJOR cambia.
PATCH: Cuando agregas bug fixes, vuelve a 0 cuando MINOR cambia.
Para gestionar esto en Python haremos uso de una librería llamada bumpver esto modifica directamente los archivos y así mantiene sincronizado en todos lados la versión.
(venv) $ python -m pip install bumpver
(venv) $ bumpver init
WARNING - Couldn't parse pyproject.toml: Missing version_pattern
Updated pyproject.toml
Este comando inicializa en pyproject.toml la gestión de las versiones, si vemos agrego una nueva sección:
[tool.bumpver]
current_version = "1.0.0"
version_pattern = "MAJOR.MINOR.PATCH"
commit_message = "bump version {old_version} -> {new_version}"
commit = true
tag = true
push = false
[tool.bumpver.file_patterns]
"pyproject.toml" = [
'current_version = "{version}"',
'version = "{version}"'
]
"src/rafnixg/__init__.py" = ["{version}"]
Si no se parece a esta ajustar el version_pattern para que sean iguales, después de configurar esto, tú puedes cambiar la versión usando los comandos de bumpver:
(venv) $ bumpver update --minor
INFO - Old Version: 1.0.0
INFO - New Version: 1.1.0
INFO - git commit --message 'bump version 1.0.0 -> 1.1.0'
INFO - git tag --annotate 1.1.0 --message '1.1.0'
📜 Elegir una licencia adecuada
Cuando creamos una librería debemos elegir que permisos queremos que los demás tengan sobre nuestro código, así se podrá saber qué es lo que quiere que se haga o no con tu librería. Una licencia muy usada para compartir código es la Licencia MIT con esta licencia simple y bastante permisiva.
Lo que debemos hacer es crear un archivo de texto llamado LICENSE que contenga el texto de nuestra licencia, si no sabes que licencia escoger existe esta web que permite ver cuál es la más conveniente según tus necesidades: Choose an open source license
📥 Instalar tu librería localmente
Para este punto ya tenemos nuestra librería lista para ser publicada, ahora lo que vamos a necesitar hacer es probar nuestra librería instalándola directamente en nuestro entorno virtual, para esto haremos uso de los siguientes comandos:
(env) $ python -m pip install -e .
Con el flag -e se instala tu librería en modo editable y con . indicamos donde se encuentra el archivo pyproject.toml esto ya deja disponible nuestro comando rafnixg que está definido en la sección project.scripts indicando el punto de entrada.
(env) $ rafnixg
Rafnix Guzmán Garcia (@rafnixg) - Python Software Developer
┌──────────────────┬───────────────────────────────────────────────────────────────────────────────────────────────┐
│ username │ rafnixg │
│ name │ Rafnix Guzmán Garcia │
│ position │ Python Software Developer │
│ links │ https://links.rafnixg.dev │
│ web │ https://rafnixg.dev │
│ blog │ https://blog.rafnixg.dev │
│ cv │ https://resume.rafnixg.dev │
│ github │ https://github.com/rafnixg │
│ twitter │ @rafnixg │
│ about │ Experienced software developer with 10+ years of expertise in designing, developing and │
│ │ implementing web systems across various sectors. Backend specialist skilled in Python, Linux, │
│ │ and Git. Passionate about continuous learning and open-source technology. │
└──────────────────┴───────────────────────────────────────────────────────────────────────────────────────────────┘
🚀 Publica tu librería a PyPI
Ya nuestra librería se encuentra lista y a la espera de conocer el mundo, en esta sección haremos el empaquetado y despliegue a PyPI.
🧑💻 Crear cuentas en PyPI y TestPyPI
Lo primero que debemos tener es una cuenta en PyPI, así que si no la tienes este es tu momento de registrarte: https://pypi.org/account/register/
También deberíamos crear una cuenta en el ambiente de pruebas de PyPI, así siempre podemos verificar que todo va bien antes de lanzar algo a producción: https://test.pypi.org/account/register/
Recuerden crear sus API Key porque en el proceso de publicación mas adelante serán necesarias.
🔐 Generar una API Key
Para esto ingresamos a Configuracion de la cuenta bajamos y buscamos la opción Fichas de API, hacemos clic en el botón Añadir ficha de API

Luego le ponen algún nombre descriptivo a esta Key, seleccionamos el Alcance y por último clic al botón Create Token

Con esto nos mostrara nuestra API Key que siempre empieza por pypy- como se muestra en la imagen de abajo:

Hacemos clic en Copiar Ficha y guardamos nuestra API Key en algún lugar seguro**.** Siempre van a tener la posibilidad de borrar la key y generar otra si es necesario la pierden.
Luego de todo esto debemos instalar 2 librerías que nos ayudaran a construir y publicar nuestro paquete:
(env) $ python -m pip install build twine
🛠️ Construir el paquete con build
Ahora que tenemos nuestra librería lista, ya podemos hacer la distribución del código a PyPI, para esto primero debemos empaquetar nuestra librería en formato wheels, un formato que consiste en empaquetar en un archivo tar todo el código fuente de la librería. Para crear este archivo haremos uso de la librería build:
(env) $ python -m build
[...]
Successfully built rafnixg-1.0.0.tar.gz and rafnixg-1.0.0-py3-none-any.whl
Esto nos crea una nueva carpeta llamada dist/ que contiene el archivo .tar.gz con el código de nuestra librería y el archivo .whl que es nuestro archivo wheels, esto es todo lo que necesitamos para subir a PyPI.
✅ Verificar el paquete con twine check
Para validar que todo fue empaquetado correctamente podemos usar twine:
(env) $ twine check dist/*
Checking dist/rafnixg-1.0.0-py3-none-any.whl: PASSED
Checking dist/rafnixg-1.0.0.tar.gz: PASSED
☁️ Subir el paquete a PyPI
Ahora que tenemos todo listo y verificado, podemos subir a TestPyPI para ver que todo va con normalidad y no tenemos ningún error en nuestra librería:
(env) $ twine upload -r testpypi dist/*
Nos pedirá nuestra API Key. Ya con esto podemos probar nuestra librería usando el siguiente comando:
(env) $ pip install -i https://test.pypi.org/simple/ rafnixg
Si todo salió con normalidad, podemos subir a él repositorio principal de PyPI:
(env) $ twine upload dist/*
Con esto tendríamos nuestro proyecto ya disponible para usar con pip, podemos a PyPI y buscar nuestra librería.

📥 Instalar tu paquete desde PyPI
Ya con nuestra librería publicada en PyPI podemos usarla con el siguiente comando:
(env) $ python -m pip install rafnixg
(env) $ rafnixg
🧠 Conclusiones
Crear y publicar tu propio paquete en Python es una experiencia enriquecedora que va más allá de compartir código: es una oportunidad para aprender sobre la estructuración de proyectos, el versionado semántico y las buenas prácticas de la comunidad. A lo largo de este tutorial, hemos recorrido desde la configuración del entorno de desarrollo hasta la publicación en PyPI, enfatizando la importancia de una documentación clara y una estructura ordenada. Con estos conocimientos, no solo mejoras tus habilidades técnicas, sino que también das un paso significativo hacia la consolidación de tu perfil profesional en el mundo del desarrollo. ¡Atrévete a experimentar, optimizar tu paquete y contribuir al ecosistema open source!





