Image for post Poetry y Gestión de Dependencias: Un Enfoque Robusto para Proyectos de IA con Python

Poetry y Gestión de Dependencias: Un Enfoque Robusto para Proyectos de IA con Python


En el dinámico mundo de la Inteligencia Artificial, donde la experimentación y la iteración son constantes, la gestión de las dependencias de tu proyecto puede convertirse rápidamente en un dolor de cabeza. Desde conflictos de versiones hasta entornos de desarrollo inconsistentes, los problemas de dependencias son una fuente común de frustración para los desarrolladores. Aquí es donde herramientas como Poetry entran en juego, ofreciendo una solución elegante y robusta para mantener tus proyectos de IA organizados, reproducibles y listos para la colaboración y el despliegue. [6, 7, 8, 9, 10, 11]

Contexto del Problema: El Laberinto de las Dependencias en IA

Imagina que estás trabajando en un proyecto de Procesamiento de Lenguaje Natural (PLN) que utiliza transformers, pytorch y langchain. Cada una de estas librerías tiene sus propias dependencias y requisitos de versión. Sin una gestión adecuada, podrías encontrarte con:

  • Conflictos de Versiones: Una librería requiere la versión A de una dependencia, mientras que otra requiere la versión B, incompatible con A. [18]
  • Entornos Inconsistentes: Tu código funciona perfectamente en tu máquina, pero falla en la de un compañero o en el servidor de producción debido a diferencias en las versiones de las librerías instaladas. [6, 19]
  • Dificultad de Reproducción: Recrear el entorno exacto de un proyecto antiguo se vuelve una tarea ardua, lo que dificulta el mantenimiento o la continuación del trabajo. [6, 10]
  • Archivos requirements.txt Limitados: Aunque útiles, los requirements.txt a menudo solo especifican dependencias de nivel superior y no sus sub-dependencias, lo que puede llevar a instalaciones inconsistentes. [19]

Estos desafíos son especialmente pronunciados en IA, donde los proyectos suelen integrar múltiples frameworks, modelos y herramientas, cada uno con su propio ecosistema de dependencias. [7, 14, 19]

Conceptos Clave de Poetry

Poetry es una herramienta de gestión de dependencias y empaquetado para Python que busca simplificar todo el ciclo de vida de un proyecto. A diferencia de pip y virtualenv por separado, Poetry integra estas funcionalidades y añade otras mejoras. [8, 9, 10, 17] Sus pilares son:

  • pyproject.toml: El Manifiesto del Proyecto: Este archivo es el corazón de un proyecto Poetry. Define metadatos del proyecto (nombre, versión, autor), dependencias de producción y de desarrollo, y configuraciones de construcción. Es un estándar moderno que reemplaza a setup.py y requirements.txt para la declaración de dependencias. [6, 8, 11, 12, 16, 17, 19]
  • Entornos Virtuales Aislados: Poetry crea y gestiona automáticamente entornos virtuales para cada proyecto, asegurando que las dependencias de un proyecto no interfieran con las de otro. Estos entornos se almacenan de forma centralizada por defecto, pero se activan automáticamente al trabajar dentro del proyecto. [8, 9, 10, 14, 17, 18]
  • poetry.lock: Reproducibilidad Garantizada: Después de resolver las dependencias, Poetry genera un archivo poetry.lock. Este archivo "bloquea" las versiones exactas de todas las dependencias (incluyendo las transitivas) que se instalaron. Esto garantiza que cualquier persona que clone tu proyecto e instale las dependencias con Poetry obtendrá exactamente el mismo entorno, asegurando la reproducibilidad. [6, 8, 9, 10, 19, 21]
  • Resolución de Dependencias Robusta: Poetry utiliza un algoritmo de resolución de dependencias sofisticado que puede manejar conflictos complejos y encontrar un conjunto de versiones compatibles para todas tus librerías. [8, 9, 13, 18]
  • Gestión de Dependencias de Desarrollo: Permite distinguir fácilmente entre dependencias necesarias para la producción y aquellas que solo se usan durante el desarrollo (como herramientas de testing o linters). [12, 13, 17, 24]

Implementación Paso a Paso con Poetry

Paso 1: Instalar Poetry

La forma recomendada de instalar Poetry es a través de su script oficial, que asegura una instalación aislada y sin conflictos con otras instalaciones de Python. [6, 11, 17, 18]

curl -sSL https://install.python-poetry.org | python3 -

Después de la instalación, asegúrate de que Poetry esté en tu PATH. El script de instalación suele añadir las instrucciones al final. Puedes verificar la instalación: [8, 9]

poetry --version

Paso 2: Inicializar un Nuevo Proyecto de IA

Navega al directorio donde quieres crear tu proyecto y usa poetry new. Esto creará una estructura de directorio básica y un archivo pyproject.toml. [6, 7, 10, 14]

mkdir mi_proyecto_ia
cd mi_proyecto_ia
poetry new . --src # El --src es opcional, crea un subdirectorio src para tu código.

Tu pyproject.toml inicial se verá algo así: [16]

[tool.poetry]
name = "mi-proyecto-ia"
version = "0.1.0"
description = ""
authors = ["Tu Nombre <tu.email@example.com>"]
readme = "README.md"

[tool.poetry.dependencies]
python = "^3.10" # O la versión de Python que estés usando

[tool.poetry.group.dev.dependencies]
pytest = "^7.1.0" # Ejemplo de dependencia de desarrollo

[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

Paso 3: Añadir Dependencias de IA

Ahora, añade las librerías que necesitas para tu proyecto de IA. Poetry las instalará en el entorno virtual del proyecto y las añadirá a pyproject.toml y poetry.lock. [6, 8, 10, 14, 21]

poetry add fastapi uvicorn
poetry add langchain openai python-dotenv

Si necesitas una versión específica, puedes indicarla: [12]

poetry add transformers@^4.30.0

Para dependencias de desarrollo (por ejemplo, para testing o linting): [12, 17, 24]

poetry add --group dev black ruff

Después de añadir dependencias, tu pyproject.toml se actualizará y se creará o actualizará el archivo poetry.lock. [8, 19]

Paso 4: Instalar Dependencias (para colaboradores o despliegue)

Si clonas un proyecto con pyproject.toml y poetry.lock, simplemente ejecuta: [6, 19, 21]

poetry install

Esto instalará todas las dependencias listadas en poetry.lock, garantizando la reproducibilidad. [6, 9, 19]

Paso 5: Ejecutar Comandos y Scripts

Para ejecutar comandos dentro del entorno virtual de Poetry, usa poetry run: [14, 21]

poetry run python tu_script.py
poetry run uvicorn main:app --reload

También puedes entrar al shell del entorno virtual: [10, 14]

poetry shell

Y luego ejecutar comandos directamente:

python tu_script.py

Para salir del shell, simplemente escribe exit.

Mini Proyecto: API de IA Sencilla con FastAPI y LangChain gestionada por Poetry

Crearemos una pequeña API con FastAPI que usa LangChain para una interacción básica con un LLM. Gestionaremos todo con Poetry. [20, 22, 23, 25]

Estructura del Proyecto

mi_proyecto_ia/
├── pyproject.toml
├── poetry.lock
├── .env # Para variables de entorno
└── src/
    ├── __init__.py
    └── main.py

Contenido de pyproject.toml (después de añadir dependencias)

[tool.poetry]
name = "mi-proyecto-ia"
version = "0.1.0"
description = "API de IA sencilla con FastAPI y LangChain"
authors = ["Tu Nombre <tu.email@example.com>"]
readme = "README.md"

[tool.poetry.dependencies]
python = "^3.10"
fastapi = "^0.111.0"
uvicorn = {extras = ["standard"], version = "^0.29.0"}
langchain = "^0.2.5"
openai = "^1.35.0"
python-dotenv = "^1.0.0"

[tool.poetry.group.dev.dependencies]
pytest = "^8.2.2"
black = "^24.4.2"
ruff = "^0.4.9"

[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

Contenido de .env

Crea un archivo .env en la raíz de tu proyecto (mi_proyecto_ia/) y añade tu clave de API de OpenAI. Recuerda nunca subir este archivo a control de versiones (Git).

OPENAI_API_KEY="sk-tu_clave_secreta_aqui"

Contenido de src/main.py

import os
from dotenv import load_dotenv
from fastapi import FastAPI
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
from typing import Dict

# Cargar variables de entorno al inicio
load_dotenv()

# Inicializar FastAPI
app = FastAPI(
    title="API de IA con LangChain y Poetry",
    description="Una API sencilla para interactuar con un LLM, gestionada con Poetry.",
    version="0.1.0",
)

# Configurar LangChain
try:
    openai_api_key = os.getenv("OPENAI_API_KEY")
    if not openai_api_key:
        raise ValueError("La variable de entorno OPENAI_API_KEY no está configurada.")
    
    llm = ChatOpenAI(api_key=openai_api_key, model="gpt-4o-mini", temperature=0.7)
    
    prompt = ChatPromptTemplate.from_messages([
        ("system", "Eres un asistente de IA útil. Responde de forma concisa y clara."),
        ("user", "{question}")
    ])
    
    output_parser = StrOutputParser()
    
    chain = prompt | llm | output_parser

except ValueError as e:
    print(f"Error de configuración de OpenAI: {e}")
    llm = None
    chain = None
    # Podrías añadir un endpoint de salud que indique este error si la API no puede funcionar

@app.get("/")
async def read_root():
    return {"message": "Bienvenido a la API de IA. Usa /ask para hacer preguntas."}

@app.post("/ask")
async def ask_llm(request: Dict[str, str]):
    question = request.get("question")
    if not question:
        return {"error": "Por favor, proporciona una pregunta en el cuerpo de la solicitud."}
    
    if not chain:
        return {"error": "El servicio de IA no está configurado correctamente. Revisa las variables de entorno."}

    try:
        response = chain.invoke({"question": question})
        return {"question": question, "answer": response}
    except Exception as e:
        return {"error": f"Ocurrió un error al procesar la solicitud: {str(e)}"}

# Ejemplo de endpoint de salud para verificar la configuración
@app.get("/health")
async def health_check():
    if llm and chain:
        return {"status": "ok", "message": "Servicio de IA operativo."}
    else:
        return {"status": "error", "message": "Servicio de IA no configurado o con errores."}

Ejecutar la Aplicación

Asegúrate de estar en el directorio raíz de tu proyecto (mi_proyecto_ia/).

poetry run uvicorn src.main:app --reload

Ahora puedes acceder a la API en http://127.0.0.1:8000 y probar el endpoint /ask con una herramienta como Postman o cURL:

curl -X POST "http://127.0.0.1:8000/ask" \
     -H "Content-Type: application/json" \
     -d '{"question": "¿Cuál es la capital de Francia?"}'

Deberías recibir una respuesta similar a:

{
  "question": "¿Cuál es la capital de Francia?",
  "answer": "La capital de Francia es París."
}

Errores Comunes y Depuración

  • "Command not found: poetry": Asegúrate de que Poetry esté en tu PATH. Revisa las instrucciones de instalación o añade manualmente la ruta al directorio bin de Poetry a tu variable de entorno PATH.
  • Conflictos de Dependencias durante poetry add o poetry install: Poetry intentará resolverlos. Si no puede, te dará un mensaje de error detallado. A menudo, esto significa que dos de tus dependencias requieren versiones incompatibles de una sub-dependencia. Puedes intentar especificar versiones más flexibles (^ para "compatible con") o buscar alternativas. [18]
  • "ModuleNotFoundError" al ejecutar un script: Asegúrate de usar poetry run python tu_script.py o de haber entrado al shell con poetry shell antes de ejecutar el script. Esto garantiza que el intérprete de Python del entorno virtual de Poetry sea el que se use. [21]
  • Variables de Entorno no cargadas: Verifica que tu archivo .env esté en la raíz del proyecto y que load_dotenv() se llame al inicio de tu script. Asegúrate de que el nombre de la variable (ej. OPENAI_API_KEY) sea correcto.
  • Problemas con la clave de API de OpenAI: Si recibes errores de autenticación o de "invalid API key", verifica que tu clave en el archivo .env sea correcta y que no tenga espacios extra.

Aprendizaje Futuro

Poetry es una herramienta poderosa con muchas más funcionalidades. Aquí hay algunas áreas para explorar: [9]

  • Publicar Paquetes: Si desarrollas una librería de IA que quieres compartir, Poetry simplifica enormemente el proceso de construir y publicar paquetes en PyPI. [6, 7, 9]
  • Grupos de Dependencias Avanzados: Puedes definir grupos de dependencias más específicos (ej. test, docs, gpu) para diferentes escenarios. [13, 14]
  • Integración con CI/CD: Incorporar Poetry en tus pipelines de integración continua/despliegue continuo para automatizar la instalación de dependencias y las pruebas.
  • Configuración de Repositorios Privados: Si trabajas con dependencias internas, Poetry puede configurarse para usar repositorios de paquetes privados.

Dominar la gestión de dependencias con Poetry te permitirá construir proyectos de IA más robustos, mantenibles y colaborativos, liberándote para concentrarte en lo que realmente importa: la innovación en inteligencia artificial. [7, 8, 9]