Menu iconMenu icon
OpenAI API Biblia Volumen 2

Capítulo 4: Construyendo un Chatbot Simple con Memoria

4.1 Implementaciones de Flask y Streamlit

En este capítulo exhaustivo, aprenderás a construir un chatbot sofisticado pero accesible para principiantes que demuestra capacidades avanzadas de memoria. A diferencia de los chatbots simples que solo responden al último mensaje, esta implementación mantendrá el contexto durante conversaciones completas, permitiendo interacciones más naturales y contextualmente conscientes. Trabajarás con dos potentes frameworks de Python para aplicaciones web: Flask, un micro-framework flexible que te da control total sobre tu aplicación, y Streamlit, un framework moderno diseñado para el desarrollo rápido de aplicaciones.

El capítulo proporciona una guía detallada paso a paso para ambos frameworks, permitiéndote elegir el enfoque que mejor se adapte a tus necesidades. Ya sea que elijas el control granular de Flask o el proceso de desarrollo simplificado de Streamlit, aprenderás a integrar tu chatbot con el modelo GPT-4o de OpenAI, aprovechando sus capacidades avanzadas de procesamiento del lenguaje natural para conversaciones inteligentes.

Al completar este capítulo, habrás creado un chatbot completamente funcional con estas características esenciales:

  • Se ejecuta en una aplicación web local - Tu chatbot operará a través de una interfaz web que podrás acceder desde cualquier navegador en tu máquina local
  • Maneja la entrada del usuario en tiempo real - La aplicación procesará y responderá a los mensajes del usuario inmediatamente, creando un flujo de conversación fluido
  • Mantiene memoria de conversación multiturnos - Tu chatbot recordará los intercambios previos y usará este contexto para proporcionar respuestas más relevantes y coherentes
  • Utiliza la API de Chat Completions de OpenAI para elaborar respuestas - Aprenderás a integrar la potente API de OpenAI para generar respuestas similares a las humanas basadas en el contexto de la conversación

Comenzaremos con 11.1 Implementaciones de Flask y Streamlit, proporcionando una exploración profunda de ambos frameworks y guiándote a través del proceso de configuración para cada enfoque. Aprenderás las ventajas específicas y consideraciones para ambas implementaciones, permitiéndote tomar una decisión informada para tu proyecto.

Profundicemos en estas poderosas herramientas de desarrollo web para entender sus arquitecturas, capacidades y casos de uso. Cada framework ofrece ventajas únicas para construir aplicaciones web, y entender sus características te ayudará a tomar una decisión informada para tu implementación de chatbot:

Flask es un micro framework web ligero y versátil para Python. Se le llama "micro" porque proporciona solo los componentes esenciales que necesitas para construir una aplicación web, dándote control completo sobre la arquitectura de tu proyecto. Las características principales incluyen:

  • Sistema de enrutamiento para manejar peticiones HTTP
  • Motor de plantillas para generación dinámica de HTML
  • Servidor de desarrollo incorporado
  • Documentación extensa y gran soporte de la comunidad
  • Fácil integración con varias extensiones

Streamlit es un framework moderno basado en Python diseñado específicamente para crear aplicaciones de datos con mínimo esfuerzo. Transforma scripts de Python en aplicaciones web compartibles a través de llamadas API simples. Las características notables incluyen:

  • Widgets incorporados para visualización interactiva de datos
  • Recarga automática durante el desarrollo
  • Soporte nativo para frameworks de aprendizaje automático
  • Proceso de implementación simple
  • Manejo de interacción del usuario en tiempo real

Ambos frameworks sobresalen en diferentes escenarios — Flask ofrece control granular y flexibilidad para aplicaciones web personalizadas, mientras que Streamlit se especializa en prototipado rápido y aplicaciones enfocadas en datos. Te invitamos a explorar uno o ambos enfoques mientras procedemos con la implementación. Veamos una implementación detallada de cada uno para ayudarte a entender sus fortalezas únicas.

Eligiendo Entre Flask y Streamlit

Considera probar ambos frameworks para ganar experiencia valiosa. Flask te dará perspectivas más profundas sobre conceptos de desarrollo web como enrutamiento, plantillas y solicitudes HTTP. Mientras tanto, Streamlit sobresale en prototipado rápido y es perfecto cuando necesitas demostrar funcionalidad rápidamente sin gastar tiempo en desarrollo frontend.

4.1.1 Eligiendo entre Flask y Streamlit: Una Comparación Detallada

Comencemos con una exploración exhaustiva de las consideraciones clave al elegir entre Flask y Streamlit para tu proyecto de chatbot. Ambos frameworks ofrecen ventajas distintivas y posibles compensaciones que pueden impactar significativamente tu experiencia de desarrollo y la aplicación final. Comprender estas diferencias te ayudará a tomar una decisión informada que se alinee con los objetivos de tu proyecto, requisitos técnicos y cronograma de desarrollo.

Flask y Streamlit representan dos enfoques filosóficos diferentes para el desarrollo de aplicaciones web. Flask encarna el concepto de microframework, proporcionando a los desarrolladores control y flexibilidad completos, mientras que Streamlit enfatiza el desarrollo rápido y resultados inmediatos a través de su enfoque optimizado y estructurado. La elección entre ellos a menudo depende de factores como la complejidad del proyecto, la personalización requerida, los requisitos de implementación y la experiencia técnica de tu equipo.

Al decidir entre Flask y Streamlit para tu proyecto de chatbot, exploremos estos factores clave en detalle:

  • Flask requiere más configuración inicial pero ofrece mayor control:
    • Necesitarás crear y configurar rutas para manejar diferentes puntos finales URL
    • La configuración de plantillas HTML requiere comprensión del desarrollo frontend
    • El manejo manual de solicitudes HTTP te da control minucioso sobre el flujo de datos
    • La gestión de sesiones y autenticación de usuarios necesitan implementación personalizada
    • Este nivel de control es poderoso pero requiere experiencia más profunda en desarrollo web y más tiempo de desarrollo
  • Streamlit permite prototipado rápido con configuración mínima:
    • Las funciones simples de Python pueden crear elementos web interactivos instantáneamente
    • La gestión de estado incorporada maneja la persistencia de datos automáticamente
    • No es necesario entender HTML, CSS o JavaScript
    • Los widgets interactivos están disponibles de forma inmediata
    • Perfecto para prototipos rápidos y aplicaciones enfocadas en datos donde la velocidad de desarrollo es crucial
  • Requisitos de la Aplicación
    • Elige Flask para aplicaciones web complejas y personalizadas:
      • Perfecto para proyectos que requieren personalización detallada de la interfaz de usuario y lógica backend
      • Ideal cuando necesitas control granular sobre sistemas de autenticación y gestión de usuarios
      • Excelente para aplicaciones con requisitos complejos de enrutamiento y múltiples endpoints
      • Mejor opción cuando tu aplicación necesita integrarse con varios servicios externos y APIs
      • Adecuado para proyectos que pueden necesitar escalar significativamente en el futuro
      • Recomendado cuando tienes desarrolladores experimentados que entienden los principios de desarrollo web
    • Elige Streamlit para aplicaciones centradas en datos que necesitan implementación rápida:
      • Excelente para proyectos de visualización de datos y paneles analíticos
      • Perfecto para prototipado rápido de interfaces de modelos de aprendizaje automático
      • Ideal para proyectos donde los científicos de datos necesitan demostrar resultados rápidamente
      • Genial para aplicaciones que se centran principalmente en la presentación e interacción con datos
      • Adecuado para equipos que quieren minimizar la sobrecarga del desarrollo frontend
      • Mejor cuando necesitas iterar rápidamente en características basadas en retroalimentación del usuario
  • Flask proporciona libertad completa de personalización frontend:
    • Diseña interfaces completamente personalizadas usando HTML, CSS y JavaScript
    • Crea diseños pixel-perfect y diseños específicos de marca
    • Implementa interacciones y animaciones complejas
    • Construye diseños responsivos que funcionan en todos los dispositivos
    • Añade bibliotecas y frameworks JavaScript personalizados según sea necesario
    • Crea experiencias de usuario únicas sin limitaciones
  • Streamlit ofrece componentes preconfigurados ideales para visualización de datos:
    • Conjunto rico de widgets listos para usar (gráficos, tablas, diagramas)
    • Elementos interactivos como deslizadores, botones y campos de entrada
    • Actualizaciones de datos y visualizaciones en tiempo real
    • Soporte nativo para bibliotecas populares de visualización de datos
    • API simple para crear interfaces complejas sin experiencia frontend
    • Capacidades de prototipado rápido para aplicaciones basadas en datos
  • Escalabilidad a Largo Plazo y Arquitectura del Sistema
    • La flexibilidad de Flask permite una escalabilidad robusta:
      • La arquitectura modular permite añadir nuevas características sin interrumpir el código existente
      • Soporta escalado horizontal a través de múltiples servidores para aumentar la capacidad
      • Fácil integración con balanceadores de carga y microservicios
      • Compatible con varios sistemas de bases de datos (SQL, NoSQL, bases de datos distribuidas)
      • Permite implementación de estrategias complejas de caché
      • Soporta middleware personalizado para optimización de rendimiento
      • Permite sistemas sofisticados de autenticación y autorización
    • La arquitectura de Streamlit tiene limitaciones específicas:
      • Construido principalmente para aplicaciones de una sola página y paneles de datos
      • Puede enfrentar desafíos de rendimiento con grandes bases de usuarios concurrentes
      • Opciones limitadas para enrutamiento complejo y gestión de URLs
      • Capacidad restringida para implementar gestión compleja de estado
      • Puede volverse más difícil de mantener a medida que crece la lógica de negocio
      • Menos adecuado para arquitectura de microservicios
      • Puede requerir reescritura completa al escalar más allá de cierta complejidad

4.1.2 Flask

Flask es un micro framework web potente y versátil para Python que ha revolucionado el desarrollo web con su elegante simplicidad y notable flexibilidad. Cuando lo llamamos framework "micro", esto no significa que tenga capacidades limitadas - más bien, sigue una filosofía minimalista donde los desarrolladores comienzan con un núcleo liviano y construyen exactamente lo que necesitan. Este enfoque reflexivo elimina la complejidad innecesaria mientras otorga a los desarrolladores un control sin precedentes sobre la arquitectura de su aplicación. Flask permite a los desarrolladores crear desde APIs simples hasta aplicaciones web complejas, manteniendo siempre un código limpio y mantenible.

Profundicemos en las características clave de Flask y entendamos por qué lo convierten en una opción tan poderosa:

  • Sistema de enrutamiento para manejar solicitudes HTTP - El sofisticado mecanismo de enrutamiento de Flask va más allá del simple mapeo de URLs. Proporciona una sintaxis basada en decoradores que hace intuitiva la creación de APIs RESTful, admite patrones de URL dinámicos con reglas variables y permite jerarquías de URL complejas. Esta flexibilidad permite a los desarrolladores estructurar sus aplicaciones de manera lógica mientras mantienen esquemas de URL limpios.
  • Motor de plantillas para generación dinámica de HTML - La integración con Jinja2, uno de los motores de plantillas más potentes de Python, ofrece mucho más que la generación básica de HTML. Proporciona herencia de plantillas para código DRY (No Te Repitas), filtros personalizados para manipulación de datos, procesadores de contexto para variables globales y soporte de macros para componentes HTML reutilizables. Estas características hacen posible crear código frontend sofisticado y mantenible sin sacrificar flexibilidad.
  • Servidor de desarrollo incorporado - El servidor de desarrollo de Flask es una herramienta sofisticada que va más allá del servicio HTTP básico. Incluye características como recarga automática cuando el código cambia, páginas de depuración detalladas con trazas de pila interactivas y la capacidad de manejar múltiples solicitudes concurrentes. Si bien es perfecto para desarrollo, Flask realiza una transición sin problemas a servidores de nivel de producción como Gunicorn o uWSGI cuando estás listo para implementar.
  • Documentación extensa y gran soporte de la comunidad - La documentación de Flask no es solo exhaustiva - es una clase magistral en desarrollo web con Python. Cada característica está explicada a fondo con ejemplos prácticos, mejores prácticas y consideraciones de seguridad. La vibrante comunidad contribuye con innumerables extensiones, tutoriales y soluciones a problemas comunes, haciendo de Flask uno de los frameworks mejor respaldados en el ecosistema Python.
  • Fácil integración con varias extensiones - El sistema de extensiones de Flask es un testimonio de su excelente diseño. A través de una API consistente, las extensiones pueden agregar características sofisticadas como soporte ORM para bases de datos (SQLAlchemy), validación de formularios (WTForms), autenticación de usuarios (Flask-Login), documentación de API (Swagger/OpenAPI) y mucho más. Estas extensiones mantienen la naturaleza liviana de Flask mientras proporcionan funcionalidad de nivel empresarial cuando se necesita.

4.1.3 Implementación del Chatbot con Flask

Este ejemplo implementa un chatbot simple usando Flask y la API de OpenAI. El chatbot recibe la entrada del usuario a través de un formulario web, la envía al modelo GPT-4o de OpenAI y muestra la respuesta del modelo en el navegador. También mantiene un historial básico de conversación.

Paso 1: Instalar Dependencias

pip install flask openai python-dotenv
  • flask: Un framework web para construir la aplicación del chatbot.
  • openai: La biblioteca de Python de OpenAI para interactuar con el modelo GPT-4o.
  • python-dotenv: Una biblioteca para cargar variables de entorno desde un archivo .env.

Paso 2: Crear la Aplicación Flask (app.py)

from flask import Flask, request, render_template, session
import openai
import os
from dotenv import load_dotenv

load_dotenv()
openai.api_key = os.getenv("OPENAI_API_KEY")

app = Flask(__name__)
app.secret_key = os.urandom(24)  # Required for session

@app.route("/", methods=["GET", "POST"])
def chat():
    # Use session to store conversation history
    if "conversation_history" not in session:
        session["conversation_history"] = []

    conversation_history = session["conversation_history"]

    if request.method == "POST":
        user_input = request.form["user_input"]
        conversation_history.append({"role": "user", "content": user_input})

        try:
            response = openai.ChatCompletion.create(
                model="gpt-4o",
                messages=[
                    {"role": "system", "content": "You are a helpful assistant."}
                ] + conversation_history
            )
            assistant_reply = response.choices[0].message.content
            conversation_history.append({"role": "assistant", "content": assistant_reply})
            session["conversation_history"] = conversation_history #save the updated history

        except openai.error.OpenAIError as e:
            assistant_reply = f"Error: {e}"
            conversation_history.append({"role": "assistant", "content": assistant_reply})
            session["conversation_history"] = conversation_history

        return render_template("chat.html", reply=assistant_reply)

    else:
        # Reset the history.  Important for starting a new chat.
        session["conversation_history"] = []
        assistant_reply = "" # Initialize
        return render_template("chat.html", reply=assistant_reply)

if __name__ == "__main__":
    app.run(debug=True)

Desglose del código

  • from flask import ...: Importa los módulos necesarios de Flask.
    • Flask: La clase Flask para crear la aplicación web.
    • request: Para acceder a los datos de solicitudes entrantes (datos de formularios).
    • render_template: Para renderizar plantillas HTML.
    • session: Para gestionar sesiones de usuario. El historial de conversación ahora se almacena en la sesión.
  • import openai: Importa la biblioteca OpenAI.
  • import os: Importa el módulo os para variables de entorno.
  • from dotenv import load_dotenv: Importa load_dotenv para cargar variables desde un archivo .env.
  • load_dotenv(): Carga las variables de entorno desde un archivo .env.
  • openai.api_key = os.getenv("OPENAI_API_KEY"): Obtiene la clave API de OpenAI desde la variable de entorno OPENAI_API_KEY y la configura para la biblioteca OpenAI.
  • app = Flask(__name__): Crea una instancia de la aplicación Flask.
  • app.secret_key = os.urandom(24)Importante: Establece una clave secreta para la aplicación Flask. Esto es necesario para usar sesiones. os.urandom(24) genera una clave aleatoria criptográficamente segura.
  • @app.route("/", methods=["GET", "POST"]): Este decorador define una ruta para la URL raíz ("/"). La función chat() manejará tanto solicitudes GET como POST a esta URL.
  • def chat():: La función que maneja las solicitudes a la URL raíz.
  • if "conversation_history" not in session: session["conversation_history"] = []: Esto es crucial para persistir el historial de conversación entre solicitudes. El historial de conversación se almacena como una lista de diccionarios en la sesión del usuario. Si conversation_history no está en la sesión, se inicializa como una lista vacía.
  • conversation_history = session["conversation_history"]: Obtiene el historial de conversación de la sesión.
  • if request.method == "POST":: Maneja las solicitudes POST, que ocurren cuando el usuario envía el formulario.
    • user_input = request.form["user_input"]: Obtiene la entrada del usuario desde los datos del formulario. El campo de entrada en la plantilla HTML se llama "user_input".
    • conversation_history.append({"role": "user", "content": user_input}): Añade la entrada del usuario al historial de conversación.
    • try...except openai.error.OpenAIError as e: Incluye manejo de errores para errores de la API de OpenAI.
    • response = openai.ChatCompletion.create(...): Llama a la API de OpenAI para obtener una respuesta del modelo GPT-4o.
      • model: Especifica el modelo de lenguaje a usar ("gpt-4o").
      • messages: Una lista de diccionarios de mensajes que representa el historial de conversación. El mensaje del sistema se incluye al principio, seguido por el historial de conversación.
    • assistant_reply = response.choices[0].message.content: Extrae la respuesta del asistente de la respuesta de la API.
    • conversation_history.append({"role": "assistant", "content": assistant_reply}): Añade la respuesta del asistente al historial de conversación.
    • session["conversation_history"] = conversation_historyCrucial: Actualiza el conversation_history en la sesión, para que se conserve para el siguiente turno de la conversación.
    • return render_template("chat.html", reply=assistant_reply): Renderiza la plantilla "chat.html" y pasa la respuesta del asistente a la plantilla.
  • else:: Maneja las solicitudes GET, que ocurren cuando el usuario carga inicialmente la página.
    • session["conversation_history"] = []: Reinicia el historial cuando el usuario carga la página.
    • assistant_reply = "": Inicializa assistant_reply como una cadena vacía.
    • return render_template("chat.html", reply=assistant_reply): Renderiza la plantilla "chat.html" con una respuesta vacía.
  • if __name__ == "__main__":: Esto asegura que el servidor de desarrollo Flask se inicie solo cuando el script se ejecuta directamente (no cuando se importa como módulo).
  • app.run(debug=True): Inicia el servidor de desarrollo Flask en modo debug. El modo debug proporciona mensajes de error útiles y recarga automática cuando se realizan cambios en el código.

Paso 3: Crear una Plantilla HTML Simple (templates/chat.html)

<!DOCTYPE html>
<html>
<head><title>Flask Chatbot</title></head>
<body>
  <h2>GPT-4o Chatbot</h2>
  <form method="post">
    <textarea name="user_input" rows="4" cols="50"></textarea><br>
    <input type="submit" value="Send">
  </form>
  <hr>
  <p><strong>Assistant:</strong> {{ reply }}</p>
</body>
</html>

Desglose del código:

  • &lt;!DOCTYPE html&gt;: Declara el tipo de documento como HTML5.
  • &lt;html&gt;: El elemento raíz del documento HTML.
  • &lt;head&gt;: Contiene metadatos sobre el documento HTML.
    • &lt;title&gt;: Especifica el título de la página HTML, que se muestra en la barra de título o pestaña del navegador.
  • &lt;body&gt;: Contiene el contenido visible de la página HTML.
    • &lt;h2&gt;: Define un encabezado de nivel 2.
    • &lt;form method="post"&gt;: Define un formulario HTML que envía datos usando el método POST.
      • &lt;textarea&gt;: Un campo de entrada de texto multilínea donde el usuario puede ingresar su consulta. El atributo name está configurado como "user_input", que se usa para acceder a la entrada en el código Flask.
      • &lt;input type="submit" value="Send"&gt;: Un botón de envío que manda los datos del formulario al servidor.
    • &lt;hr&gt;: Una línea horizontal, usada para separar contenido.
    • &lt;p&gt;: Un elemento de párrafo para mostrar la respuesta del asistente.
      • &lt;strong&gt;: Define texto enfatizado (generalmente mostrado en negrita).
      • {{ reply }}: Una variable de plantilla Jinja que será reemplazada con el valor de la variable reply pasada desde el código Flask.
  • templates: Flask, por defecto, busca las plantillas HTML en una carpeta llamada "templates" en el mismo directorio que tu archivo app.py. Por lo tanto, este archivo debe guardarse como templates/chat.html.

Este ejemplo crea una aplicación de chatbot robusta y funcional. Para implementarla, crea una carpeta templates en el mismo directorio que tu archivo app.py, guarda la plantilla HTML como chat.html dentro de esa carpeta, y configura la variable de entorno OPENAI_API_KEY.

4.1.4 Streamlit

Streamlit representa un avance revolucionario en el desarrollo de aplicaciones de datos. Este framework basado en Python ha transformado fundamentalmente cómo los desarrolladores abordan la creación de aplicaciones web. En su esencia, Streamlit encarna una filosofía de simplicidad y eficiencia, permitiendo a los desarrolladores convertir scripts de Python estándar en aplicaciones web sofisticadas con mínima sobrecarga de código.

Lo que lo distingue de los frameworks web convencionales es su enfoque innovador - mientras que los frameworks tradicionales exigen amplia experiencia en HTML, CSS y JavaScript, Streamlit introduce un cambio de paradigma al proporcionar una capa de abstracción a través de sus llamadas API intuitivas. Esta decisión de diseño lo ha convertido en una herramienta invaluable, particularmente para científicos de datos e ingenieros de aprendizaje automático que ahora pueden concentrarse en sus competencias principales mientras crean demostraciones interactivas de nivel profesional.

Exploremos en detalle su conjunto completo de características:

  • Widgets incorporados para visualización de datos interactiva - La extensa biblioteca de componentes de Streamlit incluye gráficos sofisticados, gráficos interactivos, controles deslizantes personalizables y campos de entrada versátiles. Estos componentes preconfigurados eliminan la necesidad de experiencia en desarrollo frontend, permitiendo a los creadores concentrarse en la presentación de datos en lugar de las complejidades del desarrollo web. El framework maneja toda la renderización compleja y la gestión de estado tras bambalinas.
  • Recarga automática durante el desarrollo - El entorno de desarrollo de Streamlit cuenta con un sistema inteligente de monitoreo de archivos que supervisa los cambios en tu código fuente. Cuando se detectan modificaciones, actualiza automáticamente la aplicación web, creando una experiencia de desarrollo fluida. Esta característica reduce significativamente el tiempo de desarrollo al eliminar el ciclo tradicional de guardar-actualizar común en el desarrollo web.
  • Soporte nativo para frameworks de aprendizaje automático - La profunda integración del framework con bibliotecas populares de aprendizaje automático como TensorFlow, PyTorch y scikit-learn va más allá de la simple compatibilidad. Proporciona componentes especializados y optimizaciones para flujos de trabajo de ML, convirtiéndolo en una plataforma ideal para crear demostraciones interactivas de modelos, interfaces de predicción en tiempo real y herramientas educativas para conceptos de aprendizaje automático.
  • Proceso de implementación simple - La infraestructura de implementación de Streamlit ha sido cuidadosamente diseñada para minimizar la complejidad operativa. Ya sea usando la plataforma en la nube de Streamlit o servicios de alojamiento alternativos, el proceso de implementación se ha simplificado para requerir una configuración mínima. Este enfoque asegura que los desarrolladores puedan compartir rápidamente sus aplicaciones con las partes interesadas sin quedar atrapados en tecnicismos de implementación.
  • Manejo de interacción del usuario en tiempo real - El framework incorpora mecanismos sofisticados de gestión de estado y caché que operan perfectamente en segundo plano. Estos sistemas aseguran un rendimiento óptimo durante interacciones complejas del usuario, gestionando el flujo de datos y las actualizaciones de componentes de manera eficiente sin requerir que los desarrolladores implementen lógica backend personalizada. Esto resulta en aplicaciones receptivas que pueden manejar tareas computacionales complejas mientras mantienen experiencias de usuario fluidas.

4.1.5 Implementación de Chatbot con Streamlit

Este ejemplo crea un chatbot usando Streamlit y la API de OpenAI. Es una aplicación simple que permite a los usuarios interactuar con el modelo GPT-4o a través de una interfaz de chat. La aplicación mantiene el historial de chat usando el estado de sesión de Streamlit. Esta versión mejorada incluye manejo de errores, un prompt de sistema y una barra lateral para configuraciones adicionales.

Paso 1: Instalar Dependencias

pip install streamlit openai python-dotenv

Desglose del código:

  • streamlit: Una biblioteca de Python para crear aplicaciones web interactivas, en este caso, la interfaz del chatbot.
  • openai: La biblioteca de Python de OpenAI para interactuar con el modelo GPT-4o.
  • python-dotenv: Una biblioteca para cargar variables de entorno desde un archivo .env.

Paso 2: Crear la Aplicación Streamlit (chatbot.py)

import streamlit as st
import openai
import os
from dotenv import load_dotenv
import time  # For handling potential API errors


load_dotenv()
openai.api_key = os.getenv("OPENAI_API_KEY")


# --- Configuration ---
SYSTEM_PROMPT = "You are a helpful, friendly, and knowledgeable assistant.  Answer all questions clearly and concisely."
DEFAULT_MODEL = "gpt-4o"
MAX_CONTEXT_MESSAGES = 10  # Limit conversation history


# --- Helper Functions ---
def get_openai_response(messages, model=DEFAULT_MODEL):
    """
    Sends a message to OpenAI's Chat API and handles potential errors.
    Args:
        messages: A list of message dictionaries.
        model: The OpenAI model to use.  Defaults to gpt-4o
    Returns:
        The assistant's reply, or an error message.
    """
    try:
        response = openai.ChatCompletion.create(
            model=model,
            messages=messages,
            timeout=60,  # Add a timeout to prevent hanging
        )
        return response.choices[0].message.content
    except openai.error.OpenAIError as e:
        st.error(f"OpenAI API Error: {e}")
        return f"Sorry, I encountered an error: {e}"
    except Exception as e:
        st.error(f"An unexpected error occurred: {e}")
        return "Sorry, I encountered an unexpected error."



def initialize_session_state():
    """Initializes session state variables."""
    if "messages" not in st.session_state:
        st.session_state.messages = [{"role": "system", "content": SYSTEM_PROMPT}]
    if "display_messages" not in st.session_state:
        st.session_state.display_messages = [{"role": "system", "content": SYSTEM_PROMPT}] # Separate list for displayed messages
    if "model" not in st.session_state:
        st.session_state.model = DEFAULT_MODEL


# --- Main App ---
def main():
    initialize_session_state()

    # --- Sidebar ---
    st.sidebar.header("Settings")
    model = st.sidebar.selectbox("Model", ["gpt-4o", "gpt-3.5-turbo"], index=0)  # Add model selection
    st.session_state.model = model #update the model
    clear_history = st.sidebar.button("Clear Chat History")
    if clear_history:
        st.session_state.messages = [{"role": "system", "content": SYSTEM_PROMPT}]
        st.session_state.display_messages = [{"role": "system", "content": SYSTEM_PROMPT}]  # Clear displayed messages too
        st.rerun()  # Force a rerun to update the display

    st.title("🧠 GPT-4o Chatbot with Memory") #moved title

    # Display previous messages
    for message in st.session_state.display_messages:
        if message["role"] != "system":  # Don't display the system prompt
            with st.chat_message(message["role"]):
                st.markdown(message["content"])

    # User input
    user_input = st.chat_input("You:", key="user_input")  # Use key for chat_input


    if user_input:
        st.session_state.messages.append({"role": "user", "content": user_input})
        st.session_state.display_messages.append({"role": "user", "content": user_input}) # Also add to display list

        # Get assistant reply
        reply = get_openai_response(st.session_state.messages, model=st.session_state.model)
        st.session_state.messages.append({"role": "assistant", "content": reply})
        st.session_state.display_messages.append({"role": "assistant", "content": reply}) # Also add to display list

        with st.chat_message("assistant"):
            st.markdown(reply)

        # Keep only the last MAX_CONTEXT_MESSAGES messages (including system prompt)
        st.session_state.messages = st.session_state.messages[:1] + st.session_state.messages[-MAX_CONTEXT_MESSAGES + 1:]
        st.rerun() # Force a rerun to update the display



if __name__ == "__main__":
    main()

Analicemos este código de chatbot en Streamlit:

1. Importaciones y Configuración

  • Importa las bibliotecas esenciales (streamlit, openai, os, dotenv) para la funcionalidad del chat
  • Carga las variables de entorno y configura la clave API de OpenAI

2. Configuración

  • Define el prompt del sistema para la personalidad del chatbot
  • Establece el modelo predeterminado (gpt-4o) y el máximo de mensajes de contexto (10)

3. Funciones Auxiliares

  • get_openai_response(): Gestiona la comunicación API con OpenAI
    • Incluye manejo de errores para problemas de API
    • Establece un tiempo límite de 60 segundos
    • Devuelve la respuesta o mensaje de error
  • initialize_session_state(): Configura el estado de sesión de Streamlit
    • Crea historial de mensajes para llamadas API
    • Mantiene mensajes de visualización separados
    • Inicializa la selección del modelo

4. Aplicación Principal

  • Barra lateral con ajustes:
    • Menú desplegable de selección de modelo
    • Botón para borrar historial de chat
  • Interfaz de chat:
    • Muestra historial de mensajes
    • Maneja entrada del usuario
    • Muestra respuestas del bot
    • Mantiene contexto de conversación dentro del límite de mensajes

5. Características Principales

  • Gestión de memoria mediante estado de sesión
  • Manejo de errores para llamadas API
  • Limitación del historial de mensajes para rendimiento
  • Actualizaciones de chat en tiempo real usando componentes de chat de Streamlit

Este ejemplo proporciona un chatbot fácil de usar con mejor manejo de errores, un prompt de sistema y un límite en el historial de conversación. También permite al usuario seleccionar el modelo.

4.1 Implementaciones de Flask y Streamlit

En este capítulo exhaustivo, aprenderás a construir un chatbot sofisticado pero accesible para principiantes que demuestra capacidades avanzadas de memoria. A diferencia de los chatbots simples que solo responden al último mensaje, esta implementación mantendrá el contexto durante conversaciones completas, permitiendo interacciones más naturales y contextualmente conscientes. Trabajarás con dos potentes frameworks de Python para aplicaciones web: Flask, un micro-framework flexible que te da control total sobre tu aplicación, y Streamlit, un framework moderno diseñado para el desarrollo rápido de aplicaciones.

El capítulo proporciona una guía detallada paso a paso para ambos frameworks, permitiéndote elegir el enfoque que mejor se adapte a tus necesidades. Ya sea que elijas el control granular de Flask o el proceso de desarrollo simplificado de Streamlit, aprenderás a integrar tu chatbot con el modelo GPT-4o de OpenAI, aprovechando sus capacidades avanzadas de procesamiento del lenguaje natural para conversaciones inteligentes.

Al completar este capítulo, habrás creado un chatbot completamente funcional con estas características esenciales:

  • Se ejecuta en una aplicación web local - Tu chatbot operará a través de una interfaz web que podrás acceder desde cualquier navegador en tu máquina local
  • Maneja la entrada del usuario en tiempo real - La aplicación procesará y responderá a los mensajes del usuario inmediatamente, creando un flujo de conversación fluido
  • Mantiene memoria de conversación multiturnos - Tu chatbot recordará los intercambios previos y usará este contexto para proporcionar respuestas más relevantes y coherentes
  • Utiliza la API de Chat Completions de OpenAI para elaborar respuestas - Aprenderás a integrar la potente API de OpenAI para generar respuestas similares a las humanas basadas en el contexto de la conversación

Comenzaremos con 11.1 Implementaciones de Flask y Streamlit, proporcionando una exploración profunda de ambos frameworks y guiándote a través del proceso de configuración para cada enfoque. Aprenderás las ventajas específicas y consideraciones para ambas implementaciones, permitiéndote tomar una decisión informada para tu proyecto.

Profundicemos en estas poderosas herramientas de desarrollo web para entender sus arquitecturas, capacidades y casos de uso. Cada framework ofrece ventajas únicas para construir aplicaciones web, y entender sus características te ayudará a tomar una decisión informada para tu implementación de chatbot:

Flask es un micro framework web ligero y versátil para Python. Se le llama "micro" porque proporciona solo los componentes esenciales que necesitas para construir una aplicación web, dándote control completo sobre la arquitectura de tu proyecto. Las características principales incluyen:

  • Sistema de enrutamiento para manejar peticiones HTTP
  • Motor de plantillas para generación dinámica de HTML
  • Servidor de desarrollo incorporado
  • Documentación extensa y gran soporte de la comunidad
  • Fácil integración con varias extensiones

Streamlit es un framework moderno basado en Python diseñado específicamente para crear aplicaciones de datos con mínimo esfuerzo. Transforma scripts de Python en aplicaciones web compartibles a través de llamadas API simples. Las características notables incluyen:

  • Widgets incorporados para visualización interactiva de datos
  • Recarga automática durante el desarrollo
  • Soporte nativo para frameworks de aprendizaje automático
  • Proceso de implementación simple
  • Manejo de interacción del usuario en tiempo real

Ambos frameworks sobresalen en diferentes escenarios — Flask ofrece control granular y flexibilidad para aplicaciones web personalizadas, mientras que Streamlit se especializa en prototipado rápido y aplicaciones enfocadas en datos. Te invitamos a explorar uno o ambos enfoques mientras procedemos con la implementación. Veamos una implementación detallada de cada uno para ayudarte a entender sus fortalezas únicas.

Eligiendo Entre Flask y Streamlit

Considera probar ambos frameworks para ganar experiencia valiosa. Flask te dará perspectivas más profundas sobre conceptos de desarrollo web como enrutamiento, plantillas y solicitudes HTTP. Mientras tanto, Streamlit sobresale en prototipado rápido y es perfecto cuando necesitas demostrar funcionalidad rápidamente sin gastar tiempo en desarrollo frontend.

4.1.1 Eligiendo entre Flask y Streamlit: Una Comparación Detallada

Comencemos con una exploración exhaustiva de las consideraciones clave al elegir entre Flask y Streamlit para tu proyecto de chatbot. Ambos frameworks ofrecen ventajas distintivas y posibles compensaciones que pueden impactar significativamente tu experiencia de desarrollo y la aplicación final. Comprender estas diferencias te ayudará a tomar una decisión informada que se alinee con los objetivos de tu proyecto, requisitos técnicos y cronograma de desarrollo.

Flask y Streamlit representan dos enfoques filosóficos diferentes para el desarrollo de aplicaciones web. Flask encarna el concepto de microframework, proporcionando a los desarrolladores control y flexibilidad completos, mientras que Streamlit enfatiza el desarrollo rápido y resultados inmediatos a través de su enfoque optimizado y estructurado. La elección entre ellos a menudo depende de factores como la complejidad del proyecto, la personalización requerida, los requisitos de implementación y la experiencia técnica de tu equipo.

Al decidir entre Flask y Streamlit para tu proyecto de chatbot, exploremos estos factores clave en detalle:

  • Flask requiere más configuración inicial pero ofrece mayor control:
    • Necesitarás crear y configurar rutas para manejar diferentes puntos finales URL
    • La configuración de plantillas HTML requiere comprensión del desarrollo frontend
    • El manejo manual de solicitudes HTTP te da control minucioso sobre el flujo de datos
    • La gestión de sesiones y autenticación de usuarios necesitan implementación personalizada
    • Este nivel de control es poderoso pero requiere experiencia más profunda en desarrollo web y más tiempo de desarrollo
  • Streamlit permite prototipado rápido con configuración mínima:
    • Las funciones simples de Python pueden crear elementos web interactivos instantáneamente
    • La gestión de estado incorporada maneja la persistencia de datos automáticamente
    • No es necesario entender HTML, CSS o JavaScript
    • Los widgets interactivos están disponibles de forma inmediata
    • Perfecto para prototipos rápidos y aplicaciones enfocadas en datos donde la velocidad de desarrollo es crucial
  • Requisitos de la Aplicación
    • Elige Flask para aplicaciones web complejas y personalizadas:
      • Perfecto para proyectos que requieren personalización detallada de la interfaz de usuario y lógica backend
      • Ideal cuando necesitas control granular sobre sistemas de autenticación y gestión de usuarios
      • Excelente para aplicaciones con requisitos complejos de enrutamiento y múltiples endpoints
      • Mejor opción cuando tu aplicación necesita integrarse con varios servicios externos y APIs
      • Adecuado para proyectos que pueden necesitar escalar significativamente en el futuro
      • Recomendado cuando tienes desarrolladores experimentados que entienden los principios de desarrollo web
    • Elige Streamlit para aplicaciones centradas en datos que necesitan implementación rápida:
      • Excelente para proyectos de visualización de datos y paneles analíticos
      • Perfecto para prototipado rápido de interfaces de modelos de aprendizaje automático
      • Ideal para proyectos donde los científicos de datos necesitan demostrar resultados rápidamente
      • Genial para aplicaciones que se centran principalmente en la presentación e interacción con datos
      • Adecuado para equipos que quieren minimizar la sobrecarga del desarrollo frontend
      • Mejor cuando necesitas iterar rápidamente en características basadas en retroalimentación del usuario
  • Flask proporciona libertad completa de personalización frontend:
    • Diseña interfaces completamente personalizadas usando HTML, CSS y JavaScript
    • Crea diseños pixel-perfect y diseños específicos de marca
    • Implementa interacciones y animaciones complejas
    • Construye diseños responsivos que funcionan en todos los dispositivos
    • Añade bibliotecas y frameworks JavaScript personalizados según sea necesario
    • Crea experiencias de usuario únicas sin limitaciones
  • Streamlit ofrece componentes preconfigurados ideales para visualización de datos:
    • Conjunto rico de widgets listos para usar (gráficos, tablas, diagramas)
    • Elementos interactivos como deslizadores, botones y campos de entrada
    • Actualizaciones de datos y visualizaciones en tiempo real
    • Soporte nativo para bibliotecas populares de visualización de datos
    • API simple para crear interfaces complejas sin experiencia frontend
    • Capacidades de prototipado rápido para aplicaciones basadas en datos
  • Escalabilidad a Largo Plazo y Arquitectura del Sistema
    • La flexibilidad de Flask permite una escalabilidad robusta:
      • La arquitectura modular permite añadir nuevas características sin interrumpir el código existente
      • Soporta escalado horizontal a través de múltiples servidores para aumentar la capacidad
      • Fácil integración con balanceadores de carga y microservicios
      • Compatible con varios sistemas de bases de datos (SQL, NoSQL, bases de datos distribuidas)
      • Permite implementación de estrategias complejas de caché
      • Soporta middleware personalizado para optimización de rendimiento
      • Permite sistemas sofisticados de autenticación y autorización
    • La arquitectura de Streamlit tiene limitaciones específicas:
      • Construido principalmente para aplicaciones de una sola página y paneles de datos
      • Puede enfrentar desafíos de rendimiento con grandes bases de usuarios concurrentes
      • Opciones limitadas para enrutamiento complejo y gestión de URLs
      • Capacidad restringida para implementar gestión compleja de estado
      • Puede volverse más difícil de mantener a medida que crece la lógica de negocio
      • Menos adecuado para arquitectura de microservicios
      • Puede requerir reescritura completa al escalar más allá de cierta complejidad

4.1.2 Flask

Flask es un micro framework web potente y versátil para Python que ha revolucionado el desarrollo web con su elegante simplicidad y notable flexibilidad. Cuando lo llamamos framework "micro", esto no significa que tenga capacidades limitadas - más bien, sigue una filosofía minimalista donde los desarrolladores comienzan con un núcleo liviano y construyen exactamente lo que necesitan. Este enfoque reflexivo elimina la complejidad innecesaria mientras otorga a los desarrolladores un control sin precedentes sobre la arquitectura de su aplicación. Flask permite a los desarrolladores crear desde APIs simples hasta aplicaciones web complejas, manteniendo siempre un código limpio y mantenible.

Profundicemos en las características clave de Flask y entendamos por qué lo convierten en una opción tan poderosa:

  • Sistema de enrutamiento para manejar solicitudes HTTP - El sofisticado mecanismo de enrutamiento de Flask va más allá del simple mapeo de URLs. Proporciona una sintaxis basada en decoradores que hace intuitiva la creación de APIs RESTful, admite patrones de URL dinámicos con reglas variables y permite jerarquías de URL complejas. Esta flexibilidad permite a los desarrolladores estructurar sus aplicaciones de manera lógica mientras mantienen esquemas de URL limpios.
  • Motor de plantillas para generación dinámica de HTML - La integración con Jinja2, uno de los motores de plantillas más potentes de Python, ofrece mucho más que la generación básica de HTML. Proporciona herencia de plantillas para código DRY (No Te Repitas), filtros personalizados para manipulación de datos, procesadores de contexto para variables globales y soporte de macros para componentes HTML reutilizables. Estas características hacen posible crear código frontend sofisticado y mantenible sin sacrificar flexibilidad.
  • Servidor de desarrollo incorporado - El servidor de desarrollo de Flask es una herramienta sofisticada que va más allá del servicio HTTP básico. Incluye características como recarga automática cuando el código cambia, páginas de depuración detalladas con trazas de pila interactivas y la capacidad de manejar múltiples solicitudes concurrentes. Si bien es perfecto para desarrollo, Flask realiza una transición sin problemas a servidores de nivel de producción como Gunicorn o uWSGI cuando estás listo para implementar.
  • Documentación extensa y gran soporte de la comunidad - La documentación de Flask no es solo exhaustiva - es una clase magistral en desarrollo web con Python. Cada característica está explicada a fondo con ejemplos prácticos, mejores prácticas y consideraciones de seguridad. La vibrante comunidad contribuye con innumerables extensiones, tutoriales y soluciones a problemas comunes, haciendo de Flask uno de los frameworks mejor respaldados en el ecosistema Python.
  • Fácil integración con varias extensiones - El sistema de extensiones de Flask es un testimonio de su excelente diseño. A través de una API consistente, las extensiones pueden agregar características sofisticadas como soporte ORM para bases de datos (SQLAlchemy), validación de formularios (WTForms), autenticación de usuarios (Flask-Login), documentación de API (Swagger/OpenAPI) y mucho más. Estas extensiones mantienen la naturaleza liviana de Flask mientras proporcionan funcionalidad de nivel empresarial cuando se necesita.

4.1.3 Implementación del Chatbot con Flask

Este ejemplo implementa un chatbot simple usando Flask y la API de OpenAI. El chatbot recibe la entrada del usuario a través de un formulario web, la envía al modelo GPT-4o de OpenAI y muestra la respuesta del modelo en el navegador. También mantiene un historial básico de conversación.

Paso 1: Instalar Dependencias

pip install flask openai python-dotenv
  • flask: Un framework web para construir la aplicación del chatbot.
  • openai: La biblioteca de Python de OpenAI para interactuar con el modelo GPT-4o.
  • python-dotenv: Una biblioteca para cargar variables de entorno desde un archivo .env.

Paso 2: Crear la Aplicación Flask (app.py)

from flask import Flask, request, render_template, session
import openai
import os
from dotenv import load_dotenv

load_dotenv()
openai.api_key = os.getenv("OPENAI_API_KEY")

app = Flask(__name__)
app.secret_key = os.urandom(24)  # Required for session

@app.route("/", methods=["GET", "POST"])
def chat():
    # Use session to store conversation history
    if "conversation_history" not in session:
        session["conversation_history"] = []

    conversation_history = session["conversation_history"]

    if request.method == "POST":
        user_input = request.form["user_input"]
        conversation_history.append({"role": "user", "content": user_input})

        try:
            response = openai.ChatCompletion.create(
                model="gpt-4o",
                messages=[
                    {"role": "system", "content": "You are a helpful assistant."}
                ] + conversation_history
            )
            assistant_reply = response.choices[0].message.content
            conversation_history.append({"role": "assistant", "content": assistant_reply})
            session["conversation_history"] = conversation_history #save the updated history

        except openai.error.OpenAIError as e:
            assistant_reply = f"Error: {e}"
            conversation_history.append({"role": "assistant", "content": assistant_reply})
            session["conversation_history"] = conversation_history

        return render_template("chat.html", reply=assistant_reply)

    else:
        # Reset the history.  Important for starting a new chat.
        session["conversation_history"] = []
        assistant_reply = "" # Initialize
        return render_template("chat.html", reply=assistant_reply)

if __name__ == "__main__":
    app.run(debug=True)

Desglose del código

  • from flask import ...: Importa los módulos necesarios de Flask.
    • Flask: La clase Flask para crear la aplicación web.
    • request: Para acceder a los datos de solicitudes entrantes (datos de formularios).
    • render_template: Para renderizar plantillas HTML.
    • session: Para gestionar sesiones de usuario. El historial de conversación ahora se almacena en la sesión.
  • import openai: Importa la biblioteca OpenAI.
  • import os: Importa el módulo os para variables de entorno.
  • from dotenv import load_dotenv: Importa load_dotenv para cargar variables desde un archivo .env.
  • load_dotenv(): Carga las variables de entorno desde un archivo .env.
  • openai.api_key = os.getenv("OPENAI_API_KEY"): Obtiene la clave API de OpenAI desde la variable de entorno OPENAI_API_KEY y la configura para la biblioteca OpenAI.
  • app = Flask(__name__): Crea una instancia de la aplicación Flask.
  • app.secret_key = os.urandom(24)Importante: Establece una clave secreta para la aplicación Flask. Esto es necesario para usar sesiones. os.urandom(24) genera una clave aleatoria criptográficamente segura.
  • @app.route("/", methods=["GET", "POST"]): Este decorador define una ruta para la URL raíz ("/"). La función chat() manejará tanto solicitudes GET como POST a esta URL.
  • def chat():: La función que maneja las solicitudes a la URL raíz.
  • if "conversation_history" not in session: session["conversation_history"] = []: Esto es crucial para persistir el historial de conversación entre solicitudes. El historial de conversación se almacena como una lista de diccionarios en la sesión del usuario. Si conversation_history no está en la sesión, se inicializa como una lista vacía.
  • conversation_history = session["conversation_history"]: Obtiene el historial de conversación de la sesión.
  • if request.method == "POST":: Maneja las solicitudes POST, que ocurren cuando el usuario envía el formulario.
    • user_input = request.form["user_input"]: Obtiene la entrada del usuario desde los datos del formulario. El campo de entrada en la plantilla HTML se llama "user_input".
    • conversation_history.append({"role": "user", "content": user_input}): Añade la entrada del usuario al historial de conversación.
    • try...except openai.error.OpenAIError as e: Incluye manejo de errores para errores de la API de OpenAI.
    • response = openai.ChatCompletion.create(...): Llama a la API de OpenAI para obtener una respuesta del modelo GPT-4o.
      • model: Especifica el modelo de lenguaje a usar ("gpt-4o").
      • messages: Una lista de diccionarios de mensajes que representa el historial de conversación. El mensaje del sistema se incluye al principio, seguido por el historial de conversación.
    • assistant_reply = response.choices[0].message.content: Extrae la respuesta del asistente de la respuesta de la API.
    • conversation_history.append({"role": "assistant", "content": assistant_reply}): Añade la respuesta del asistente al historial de conversación.
    • session["conversation_history"] = conversation_historyCrucial: Actualiza el conversation_history en la sesión, para que se conserve para el siguiente turno de la conversación.
    • return render_template("chat.html", reply=assistant_reply): Renderiza la plantilla "chat.html" y pasa la respuesta del asistente a la plantilla.
  • else:: Maneja las solicitudes GET, que ocurren cuando el usuario carga inicialmente la página.
    • session["conversation_history"] = []: Reinicia el historial cuando el usuario carga la página.
    • assistant_reply = "": Inicializa assistant_reply como una cadena vacía.
    • return render_template("chat.html", reply=assistant_reply): Renderiza la plantilla "chat.html" con una respuesta vacía.
  • if __name__ == "__main__":: Esto asegura que el servidor de desarrollo Flask se inicie solo cuando el script se ejecuta directamente (no cuando se importa como módulo).
  • app.run(debug=True): Inicia el servidor de desarrollo Flask en modo debug. El modo debug proporciona mensajes de error útiles y recarga automática cuando se realizan cambios en el código.

Paso 3: Crear una Plantilla HTML Simple (templates/chat.html)

<!DOCTYPE html>
<html>
<head><title>Flask Chatbot</title></head>
<body>
  <h2>GPT-4o Chatbot</h2>
  <form method="post">
    <textarea name="user_input" rows="4" cols="50"></textarea><br>
    <input type="submit" value="Send">
  </form>
  <hr>
  <p><strong>Assistant:</strong> {{ reply }}</p>
</body>
</html>

Desglose del código:

  • &lt;!DOCTYPE html&gt;: Declara el tipo de documento como HTML5.
  • &lt;html&gt;: El elemento raíz del documento HTML.
  • &lt;head&gt;: Contiene metadatos sobre el documento HTML.
    • &lt;title&gt;: Especifica el título de la página HTML, que se muestra en la barra de título o pestaña del navegador.
  • &lt;body&gt;: Contiene el contenido visible de la página HTML.
    • &lt;h2&gt;: Define un encabezado de nivel 2.
    • &lt;form method="post"&gt;: Define un formulario HTML que envía datos usando el método POST.
      • &lt;textarea&gt;: Un campo de entrada de texto multilínea donde el usuario puede ingresar su consulta. El atributo name está configurado como "user_input", que se usa para acceder a la entrada en el código Flask.
      • &lt;input type="submit" value="Send"&gt;: Un botón de envío que manda los datos del formulario al servidor.
    • &lt;hr&gt;: Una línea horizontal, usada para separar contenido.
    • &lt;p&gt;: Un elemento de párrafo para mostrar la respuesta del asistente.
      • &lt;strong&gt;: Define texto enfatizado (generalmente mostrado en negrita).
      • {{ reply }}: Una variable de plantilla Jinja que será reemplazada con el valor de la variable reply pasada desde el código Flask.
  • templates: Flask, por defecto, busca las plantillas HTML en una carpeta llamada "templates" en el mismo directorio que tu archivo app.py. Por lo tanto, este archivo debe guardarse como templates/chat.html.

Este ejemplo crea una aplicación de chatbot robusta y funcional. Para implementarla, crea una carpeta templates en el mismo directorio que tu archivo app.py, guarda la plantilla HTML como chat.html dentro de esa carpeta, y configura la variable de entorno OPENAI_API_KEY.

4.1.4 Streamlit

Streamlit representa un avance revolucionario en el desarrollo de aplicaciones de datos. Este framework basado en Python ha transformado fundamentalmente cómo los desarrolladores abordan la creación de aplicaciones web. En su esencia, Streamlit encarna una filosofía de simplicidad y eficiencia, permitiendo a los desarrolladores convertir scripts de Python estándar en aplicaciones web sofisticadas con mínima sobrecarga de código.

Lo que lo distingue de los frameworks web convencionales es su enfoque innovador - mientras que los frameworks tradicionales exigen amplia experiencia en HTML, CSS y JavaScript, Streamlit introduce un cambio de paradigma al proporcionar una capa de abstracción a través de sus llamadas API intuitivas. Esta decisión de diseño lo ha convertido en una herramienta invaluable, particularmente para científicos de datos e ingenieros de aprendizaje automático que ahora pueden concentrarse en sus competencias principales mientras crean demostraciones interactivas de nivel profesional.

Exploremos en detalle su conjunto completo de características:

  • Widgets incorporados para visualización de datos interactiva - La extensa biblioteca de componentes de Streamlit incluye gráficos sofisticados, gráficos interactivos, controles deslizantes personalizables y campos de entrada versátiles. Estos componentes preconfigurados eliminan la necesidad de experiencia en desarrollo frontend, permitiendo a los creadores concentrarse en la presentación de datos en lugar de las complejidades del desarrollo web. El framework maneja toda la renderización compleja y la gestión de estado tras bambalinas.
  • Recarga automática durante el desarrollo - El entorno de desarrollo de Streamlit cuenta con un sistema inteligente de monitoreo de archivos que supervisa los cambios en tu código fuente. Cuando se detectan modificaciones, actualiza automáticamente la aplicación web, creando una experiencia de desarrollo fluida. Esta característica reduce significativamente el tiempo de desarrollo al eliminar el ciclo tradicional de guardar-actualizar común en el desarrollo web.
  • Soporte nativo para frameworks de aprendizaje automático - La profunda integración del framework con bibliotecas populares de aprendizaje automático como TensorFlow, PyTorch y scikit-learn va más allá de la simple compatibilidad. Proporciona componentes especializados y optimizaciones para flujos de trabajo de ML, convirtiéndolo en una plataforma ideal para crear demostraciones interactivas de modelos, interfaces de predicción en tiempo real y herramientas educativas para conceptos de aprendizaje automático.
  • Proceso de implementación simple - La infraestructura de implementación de Streamlit ha sido cuidadosamente diseñada para minimizar la complejidad operativa. Ya sea usando la plataforma en la nube de Streamlit o servicios de alojamiento alternativos, el proceso de implementación se ha simplificado para requerir una configuración mínima. Este enfoque asegura que los desarrolladores puedan compartir rápidamente sus aplicaciones con las partes interesadas sin quedar atrapados en tecnicismos de implementación.
  • Manejo de interacción del usuario en tiempo real - El framework incorpora mecanismos sofisticados de gestión de estado y caché que operan perfectamente en segundo plano. Estos sistemas aseguran un rendimiento óptimo durante interacciones complejas del usuario, gestionando el flujo de datos y las actualizaciones de componentes de manera eficiente sin requerir que los desarrolladores implementen lógica backend personalizada. Esto resulta en aplicaciones receptivas que pueden manejar tareas computacionales complejas mientras mantienen experiencias de usuario fluidas.

4.1.5 Implementación de Chatbot con Streamlit

Este ejemplo crea un chatbot usando Streamlit y la API de OpenAI. Es una aplicación simple que permite a los usuarios interactuar con el modelo GPT-4o a través de una interfaz de chat. La aplicación mantiene el historial de chat usando el estado de sesión de Streamlit. Esta versión mejorada incluye manejo de errores, un prompt de sistema y una barra lateral para configuraciones adicionales.

Paso 1: Instalar Dependencias

pip install streamlit openai python-dotenv

Desglose del código:

  • streamlit: Una biblioteca de Python para crear aplicaciones web interactivas, en este caso, la interfaz del chatbot.
  • openai: La biblioteca de Python de OpenAI para interactuar con el modelo GPT-4o.
  • python-dotenv: Una biblioteca para cargar variables de entorno desde un archivo .env.

Paso 2: Crear la Aplicación Streamlit (chatbot.py)

import streamlit as st
import openai
import os
from dotenv import load_dotenv
import time  # For handling potential API errors


load_dotenv()
openai.api_key = os.getenv("OPENAI_API_KEY")


# --- Configuration ---
SYSTEM_PROMPT = "You are a helpful, friendly, and knowledgeable assistant.  Answer all questions clearly and concisely."
DEFAULT_MODEL = "gpt-4o"
MAX_CONTEXT_MESSAGES = 10  # Limit conversation history


# --- Helper Functions ---
def get_openai_response(messages, model=DEFAULT_MODEL):
    """
    Sends a message to OpenAI's Chat API and handles potential errors.
    Args:
        messages: A list of message dictionaries.
        model: The OpenAI model to use.  Defaults to gpt-4o
    Returns:
        The assistant's reply, or an error message.
    """
    try:
        response = openai.ChatCompletion.create(
            model=model,
            messages=messages,
            timeout=60,  # Add a timeout to prevent hanging
        )
        return response.choices[0].message.content
    except openai.error.OpenAIError as e:
        st.error(f"OpenAI API Error: {e}")
        return f"Sorry, I encountered an error: {e}"
    except Exception as e:
        st.error(f"An unexpected error occurred: {e}")
        return "Sorry, I encountered an unexpected error."



def initialize_session_state():
    """Initializes session state variables."""
    if "messages" not in st.session_state:
        st.session_state.messages = [{"role": "system", "content": SYSTEM_PROMPT}]
    if "display_messages" not in st.session_state:
        st.session_state.display_messages = [{"role": "system", "content": SYSTEM_PROMPT}] # Separate list for displayed messages
    if "model" not in st.session_state:
        st.session_state.model = DEFAULT_MODEL


# --- Main App ---
def main():
    initialize_session_state()

    # --- Sidebar ---
    st.sidebar.header("Settings")
    model = st.sidebar.selectbox("Model", ["gpt-4o", "gpt-3.5-turbo"], index=0)  # Add model selection
    st.session_state.model = model #update the model
    clear_history = st.sidebar.button("Clear Chat History")
    if clear_history:
        st.session_state.messages = [{"role": "system", "content": SYSTEM_PROMPT}]
        st.session_state.display_messages = [{"role": "system", "content": SYSTEM_PROMPT}]  # Clear displayed messages too
        st.rerun()  # Force a rerun to update the display

    st.title("🧠 GPT-4o Chatbot with Memory") #moved title

    # Display previous messages
    for message in st.session_state.display_messages:
        if message["role"] != "system":  # Don't display the system prompt
            with st.chat_message(message["role"]):
                st.markdown(message["content"])

    # User input
    user_input = st.chat_input("You:", key="user_input")  # Use key for chat_input


    if user_input:
        st.session_state.messages.append({"role": "user", "content": user_input})
        st.session_state.display_messages.append({"role": "user", "content": user_input}) # Also add to display list

        # Get assistant reply
        reply = get_openai_response(st.session_state.messages, model=st.session_state.model)
        st.session_state.messages.append({"role": "assistant", "content": reply})
        st.session_state.display_messages.append({"role": "assistant", "content": reply}) # Also add to display list

        with st.chat_message("assistant"):
            st.markdown(reply)

        # Keep only the last MAX_CONTEXT_MESSAGES messages (including system prompt)
        st.session_state.messages = st.session_state.messages[:1] + st.session_state.messages[-MAX_CONTEXT_MESSAGES + 1:]
        st.rerun() # Force a rerun to update the display



if __name__ == "__main__":
    main()

Analicemos este código de chatbot en Streamlit:

1. Importaciones y Configuración

  • Importa las bibliotecas esenciales (streamlit, openai, os, dotenv) para la funcionalidad del chat
  • Carga las variables de entorno y configura la clave API de OpenAI

2. Configuración

  • Define el prompt del sistema para la personalidad del chatbot
  • Establece el modelo predeterminado (gpt-4o) y el máximo de mensajes de contexto (10)

3. Funciones Auxiliares

  • get_openai_response(): Gestiona la comunicación API con OpenAI
    • Incluye manejo de errores para problemas de API
    • Establece un tiempo límite de 60 segundos
    • Devuelve la respuesta o mensaje de error
  • initialize_session_state(): Configura el estado de sesión de Streamlit
    • Crea historial de mensajes para llamadas API
    • Mantiene mensajes de visualización separados
    • Inicializa la selección del modelo

4. Aplicación Principal

  • Barra lateral con ajustes:
    • Menú desplegable de selección de modelo
    • Botón para borrar historial de chat
  • Interfaz de chat:
    • Muestra historial de mensajes
    • Maneja entrada del usuario
    • Muestra respuestas del bot
    • Mantiene contexto de conversación dentro del límite de mensajes

5. Características Principales

  • Gestión de memoria mediante estado de sesión
  • Manejo de errores para llamadas API
  • Limitación del historial de mensajes para rendimiento
  • Actualizaciones de chat en tiempo real usando componentes de chat de Streamlit

Este ejemplo proporciona un chatbot fácil de usar con mejor manejo de errores, un prompt de sistema y un límite en el historial de conversación. También permite al usuario seleccionar el modelo.

4.1 Implementaciones de Flask y Streamlit

En este capítulo exhaustivo, aprenderás a construir un chatbot sofisticado pero accesible para principiantes que demuestra capacidades avanzadas de memoria. A diferencia de los chatbots simples que solo responden al último mensaje, esta implementación mantendrá el contexto durante conversaciones completas, permitiendo interacciones más naturales y contextualmente conscientes. Trabajarás con dos potentes frameworks de Python para aplicaciones web: Flask, un micro-framework flexible que te da control total sobre tu aplicación, y Streamlit, un framework moderno diseñado para el desarrollo rápido de aplicaciones.

El capítulo proporciona una guía detallada paso a paso para ambos frameworks, permitiéndote elegir el enfoque que mejor se adapte a tus necesidades. Ya sea que elijas el control granular de Flask o el proceso de desarrollo simplificado de Streamlit, aprenderás a integrar tu chatbot con el modelo GPT-4o de OpenAI, aprovechando sus capacidades avanzadas de procesamiento del lenguaje natural para conversaciones inteligentes.

Al completar este capítulo, habrás creado un chatbot completamente funcional con estas características esenciales:

  • Se ejecuta en una aplicación web local - Tu chatbot operará a través de una interfaz web que podrás acceder desde cualquier navegador en tu máquina local
  • Maneja la entrada del usuario en tiempo real - La aplicación procesará y responderá a los mensajes del usuario inmediatamente, creando un flujo de conversación fluido
  • Mantiene memoria de conversación multiturnos - Tu chatbot recordará los intercambios previos y usará este contexto para proporcionar respuestas más relevantes y coherentes
  • Utiliza la API de Chat Completions de OpenAI para elaborar respuestas - Aprenderás a integrar la potente API de OpenAI para generar respuestas similares a las humanas basadas en el contexto de la conversación

Comenzaremos con 11.1 Implementaciones de Flask y Streamlit, proporcionando una exploración profunda de ambos frameworks y guiándote a través del proceso de configuración para cada enfoque. Aprenderás las ventajas específicas y consideraciones para ambas implementaciones, permitiéndote tomar una decisión informada para tu proyecto.

Profundicemos en estas poderosas herramientas de desarrollo web para entender sus arquitecturas, capacidades y casos de uso. Cada framework ofrece ventajas únicas para construir aplicaciones web, y entender sus características te ayudará a tomar una decisión informada para tu implementación de chatbot:

Flask es un micro framework web ligero y versátil para Python. Se le llama "micro" porque proporciona solo los componentes esenciales que necesitas para construir una aplicación web, dándote control completo sobre la arquitectura de tu proyecto. Las características principales incluyen:

  • Sistema de enrutamiento para manejar peticiones HTTP
  • Motor de plantillas para generación dinámica de HTML
  • Servidor de desarrollo incorporado
  • Documentación extensa y gran soporte de la comunidad
  • Fácil integración con varias extensiones

Streamlit es un framework moderno basado en Python diseñado específicamente para crear aplicaciones de datos con mínimo esfuerzo. Transforma scripts de Python en aplicaciones web compartibles a través de llamadas API simples. Las características notables incluyen:

  • Widgets incorporados para visualización interactiva de datos
  • Recarga automática durante el desarrollo
  • Soporte nativo para frameworks de aprendizaje automático
  • Proceso de implementación simple
  • Manejo de interacción del usuario en tiempo real

Ambos frameworks sobresalen en diferentes escenarios — Flask ofrece control granular y flexibilidad para aplicaciones web personalizadas, mientras que Streamlit se especializa en prototipado rápido y aplicaciones enfocadas en datos. Te invitamos a explorar uno o ambos enfoques mientras procedemos con la implementación. Veamos una implementación detallada de cada uno para ayudarte a entender sus fortalezas únicas.

Eligiendo Entre Flask y Streamlit

Considera probar ambos frameworks para ganar experiencia valiosa. Flask te dará perspectivas más profundas sobre conceptos de desarrollo web como enrutamiento, plantillas y solicitudes HTTP. Mientras tanto, Streamlit sobresale en prototipado rápido y es perfecto cuando necesitas demostrar funcionalidad rápidamente sin gastar tiempo en desarrollo frontend.

4.1.1 Eligiendo entre Flask y Streamlit: Una Comparación Detallada

Comencemos con una exploración exhaustiva de las consideraciones clave al elegir entre Flask y Streamlit para tu proyecto de chatbot. Ambos frameworks ofrecen ventajas distintivas y posibles compensaciones que pueden impactar significativamente tu experiencia de desarrollo y la aplicación final. Comprender estas diferencias te ayudará a tomar una decisión informada que se alinee con los objetivos de tu proyecto, requisitos técnicos y cronograma de desarrollo.

Flask y Streamlit representan dos enfoques filosóficos diferentes para el desarrollo de aplicaciones web. Flask encarna el concepto de microframework, proporcionando a los desarrolladores control y flexibilidad completos, mientras que Streamlit enfatiza el desarrollo rápido y resultados inmediatos a través de su enfoque optimizado y estructurado. La elección entre ellos a menudo depende de factores como la complejidad del proyecto, la personalización requerida, los requisitos de implementación y la experiencia técnica de tu equipo.

Al decidir entre Flask y Streamlit para tu proyecto de chatbot, exploremos estos factores clave en detalle:

  • Flask requiere más configuración inicial pero ofrece mayor control:
    • Necesitarás crear y configurar rutas para manejar diferentes puntos finales URL
    • La configuración de plantillas HTML requiere comprensión del desarrollo frontend
    • El manejo manual de solicitudes HTTP te da control minucioso sobre el flujo de datos
    • La gestión de sesiones y autenticación de usuarios necesitan implementación personalizada
    • Este nivel de control es poderoso pero requiere experiencia más profunda en desarrollo web y más tiempo de desarrollo
  • Streamlit permite prototipado rápido con configuración mínima:
    • Las funciones simples de Python pueden crear elementos web interactivos instantáneamente
    • La gestión de estado incorporada maneja la persistencia de datos automáticamente
    • No es necesario entender HTML, CSS o JavaScript
    • Los widgets interactivos están disponibles de forma inmediata
    • Perfecto para prototipos rápidos y aplicaciones enfocadas en datos donde la velocidad de desarrollo es crucial
  • Requisitos de la Aplicación
    • Elige Flask para aplicaciones web complejas y personalizadas:
      • Perfecto para proyectos que requieren personalización detallada de la interfaz de usuario y lógica backend
      • Ideal cuando necesitas control granular sobre sistemas de autenticación y gestión de usuarios
      • Excelente para aplicaciones con requisitos complejos de enrutamiento y múltiples endpoints
      • Mejor opción cuando tu aplicación necesita integrarse con varios servicios externos y APIs
      • Adecuado para proyectos que pueden necesitar escalar significativamente en el futuro
      • Recomendado cuando tienes desarrolladores experimentados que entienden los principios de desarrollo web
    • Elige Streamlit para aplicaciones centradas en datos que necesitan implementación rápida:
      • Excelente para proyectos de visualización de datos y paneles analíticos
      • Perfecto para prototipado rápido de interfaces de modelos de aprendizaje automático
      • Ideal para proyectos donde los científicos de datos necesitan demostrar resultados rápidamente
      • Genial para aplicaciones que se centran principalmente en la presentación e interacción con datos
      • Adecuado para equipos que quieren minimizar la sobrecarga del desarrollo frontend
      • Mejor cuando necesitas iterar rápidamente en características basadas en retroalimentación del usuario
  • Flask proporciona libertad completa de personalización frontend:
    • Diseña interfaces completamente personalizadas usando HTML, CSS y JavaScript
    • Crea diseños pixel-perfect y diseños específicos de marca
    • Implementa interacciones y animaciones complejas
    • Construye diseños responsivos que funcionan en todos los dispositivos
    • Añade bibliotecas y frameworks JavaScript personalizados según sea necesario
    • Crea experiencias de usuario únicas sin limitaciones
  • Streamlit ofrece componentes preconfigurados ideales para visualización de datos:
    • Conjunto rico de widgets listos para usar (gráficos, tablas, diagramas)
    • Elementos interactivos como deslizadores, botones y campos de entrada
    • Actualizaciones de datos y visualizaciones en tiempo real
    • Soporte nativo para bibliotecas populares de visualización de datos
    • API simple para crear interfaces complejas sin experiencia frontend
    • Capacidades de prototipado rápido para aplicaciones basadas en datos
  • Escalabilidad a Largo Plazo y Arquitectura del Sistema
    • La flexibilidad de Flask permite una escalabilidad robusta:
      • La arquitectura modular permite añadir nuevas características sin interrumpir el código existente
      • Soporta escalado horizontal a través de múltiples servidores para aumentar la capacidad
      • Fácil integración con balanceadores de carga y microservicios
      • Compatible con varios sistemas de bases de datos (SQL, NoSQL, bases de datos distribuidas)
      • Permite implementación de estrategias complejas de caché
      • Soporta middleware personalizado para optimización de rendimiento
      • Permite sistemas sofisticados de autenticación y autorización
    • La arquitectura de Streamlit tiene limitaciones específicas:
      • Construido principalmente para aplicaciones de una sola página y paneles de datos
      • Puede enfrentar desafíos de rendimiento con grandes bases de usuarios concurrentes
      • Opciones limitadas para enrutamiento complejo y gestión de URLs
      • Capacidad restringida para implementar gestión compleja de estado
      • Puede volverse más difícil de mantener a medida que crece la lógica de negocio
      • Menos adecuado para arquitectura de microservicios
      • Puede requerir reescritura completa al escalar más allá de cierta complejidad

4.1.2 Flask

Flask es un micro framework web potente y versátil para Python que ha revolucionado el desarrollo web con su elegante simplicidad y notable flexibilidad. Cuando lo llamamos framework "micro", esto no significa que tenga capacidades limitadas - más bien, sigue una filosofía minimalista donde los desarrolladores comienzan con un núcleo liviano y construyen exactamente lo que necesitan. Este enfoque reflexivo elimina la complejidad innecesaria mientras otorga a los desarrolladores un control sin precedentes sobre la arquitectura de su aplicación. Flask permite a los desarrolladores crear desde APIs simples hasta aplicaciones web complejas, manteniendo siempre un código limpio y mantenible.

Profundicemos en las características clave de Flask y entendamos por qué lo convierten en una opción tan poderosa:

  • Sistema de enrutamiento para manejar solicitudes HTTP - El sofisticado mecanismo de enrutamiento de Flask va más allá del simple mapeo de URLs. Proporciona una sintaxis basada en decoradores que hace intuitiva la creación de APIs RESTful, admite patrones de URL dinámicos con reglas variables y permite jerarquías de URL complejas. Esta flexibilidad permite a los desarrolladores estructurar sus aplicaciones de manera lógica mientras mantienen esquemas de URL limpios.
  • Motor de plantillas para generación dinámica de HTML - La integración con Jinja2, uno de los motores de plantillas más potentes de Python, ofrece mucho más que la generación básica de HTML. Proporciona herencia de plantillas para código DRY (No Te Repitas), filtros personalizados para manipulación de datos, procesadores de contexto para variables globales y soporte de macros para componentes HTML reutilizables. Estas características hacen posible crear código frontend sofisticado y mantenible sin sacrificar flexibilidad.
  • Servidor de desarrollo incorporado - El servidor de desarrollo de Flask es una herramienta sofisticada que va más allá del servicio HTTP básico. Incluye características como recarga automática cuando el código cambia, páginas de depuración detalladas con trazas de pila interactivas y la capacidad de manejar múltiples solicitudes concurrentes. Si bien es perfecto para desarrollo, Flask realiza una transición sin problemas a servidores de nivel de producción como Gunicorn o uWSGI cuando estás listo para implementar.
  • Documentación extensa y gran soporte de la comunidad - La documentación de Flask no es solo exhaustiva - es una clase magistral en desarrollo web con Python. Cada característica está explicada a fondo con ejemplos prácticos, mejores prácticas y consideraciones de seguridad. La vibrante comunidad contribuye con innumerables extensiones, tutoriales y soluciones a problemas comunes, haciendo de Flask uno de los frameworks mejor respaldados en el ecosistema Python.
  • Fácil integración con varias extensiones - El sistema de extensiones de Flask es un testimonio de su excelente diseño. A través de una API consistente, las extensiones pueden agregar características sofisticadas como soporte ORM para bases de datos (SQLAlchemy), validación de formularios (WTForms), autenticación de usuarios (Flask-Login), documentación de API (Swagger/OpenAPI) y mucho más. Estas extensiones mantienen la naturaleza liviana de Flask mientras proporcionan funcionalidad de nivel empresarial cuando se necesita.

4.1.3 Implementación del Chatbot con Flask

Este ejemplo implementa un chatbot simple usando Flask y la API de OpenAI. El chatbot recibe la entrada del usuario a través de un formulario web, la envía al modelo GPT-4o de OpenAI y muestra la respuesta del modelo en el navegador. También mantiene un historial básico de conversación.

Paso 1: Instalar Dependencias

pip install flask openai python-dotenv
  • flask: Un framework web para construir la aplicación del chatbot.
  • openai: La biblioteca de Python de OpenAI para interactuar con el modelo GPT-4o.
  • python-dotenv: Una biblioteca para cargar variables de entorno desde un archivo .env.

Paso 2: Crear la Aplicación Flask (app.py)

from flask import Flask, request, render_template, session
import openai
import os
from dotenv import load_dotenv

load_dotenv()
openai.api_key = os.getenv("OPENAI_API_KEY")

app = Flask(__name__)
app.secret_key = os.urandom(24)  # Required for session

@app.route("/", methods=["GET", "POST"])
def chat():
    # Use session to store conversation history
    if "conversation_history" not in session:
        session["conversation_history"] = []

    conversation_history = session["conversation_history"]

    if request.method == "POST":
        user_input = request.form["user_input"]
        conversation_history.append({"role": "user", "content": user_input})

        try:
            response = openai.ChatCompletion.create(
                model="gpt-4o",
                messages=[
                    {"role": "system", "content": "You are a helpful assistant."}
                ] + conversation_history
            )
            assistant_reply = response.choices[0].message.content
            conversation_history.append({"role": "assistant", "content": assistant_reply})
            session["conversation_history"] = conversation_history #save the updated history

        except openai.error.OpenAIError as e:
            assistant_reply = f"Error: {e}"
            conversation_history.append({"role": "assistant", "content": assistant_reply})
            session["conversation_history"] = conversation_history

        return render_template("chat.html", reply=assistant_reply)

    else:
        # Reset the history.  Important for starting a new chat.
        session["conversation_history"] = []
        assistant_reply = "" # Initialize
        return render_template("chat.html", reply=assistant_reply)

if __name__ == "__main__":
    app.run(debug=True)

Desglose del código

  • from flask import ...: Importa los módulos necesarios de Flask.
    • Flask: La clase Flask para crear la aplicación web.
    • request: Para acceder a los datos de solicitudes entrantes (datos de formularios).
    • render_template: Para renderizar plantillas HTML.
    • session: Para gestionar sesiones de usuario. El historial de conversación ahora se almacena en la sesión.
  • import openai: Importa la biblioteca OpenAI.
  • import os: Importa el módulo os para variables de entorno.
  • from dotenv import load_dotenv: Importa load_dotenv para cargar variables desde un archivo .env.
  • load_dotenv(): Carga las variables de entorno desde un archivo .env.
  • openai.api_key = os.getenv("OPENAI_API_KEY"): Obtiene la clave API de OpenAI desde la variable de entorno OPENAI_API_KEY y la configura para la biblioteca OpenAI.
  • app = Flask(__name__): Crea una instancia de la aplicación Flask.
  • app.secret_key = os.urandom(24)Importante: Establece una clave secreta para la aplicación Flask. Esto es necesario para usar sesiones. os.urandom(24) genera una clave aleatoria criptográficamente segura.
  • @app.route("/", methods=["GET", "POST"]): Este decorador define una ruta para la URL raíz ("/"). La función chat() manejará tanto solicitudes GET como POST a esta URL.
  • def chat():: La función que maneja las solicitudes a la URL raíz.
  • if "conversation_history" not in session: session["conversation_history"] = []: Esto es crucial para persistir el historial de conversación entre solicitudes. El historial de conversación se almacena como una lista de diccionarios en la sesión del usuario. Si conversation_history no está en la sesión, se inicializa como una lista vacía.
  • conversation_history = session["conversation_history"]: Obtiene el historial de conversación de la sesión.
  • if request.method == "POST":: Maneja las solicitudes POST, que ocurren cuando el usuario envía el formulario.
    • user_input = request.form["user_input"]: Obtiene la entrada del usuario desde los datos del formulario. El campo de entrada en la plantilla HTML se llama "user_input".
    • conversation_history.append({"role": "user", "content": user_input}): Añade la entrada del usuario al historial de conversación.
    • try...except openai.error.OpenAIError as e: Incluye manejo de errores para errores de la API de OpenAI.
    • response = openai.ChatCompletion.create(...): Llama a la API de OpenAI para obtener una respuesta del modelo GPT-4o.
      • model: Especifica el modelo de lenguaje a usar ("gpt-4o").
      • messages: Una lista de diccionarios de mensajes que representa el historial de conversación. El mensaje del sistema se incluye al principio, seguido por el historial de conversación.
    • assistant_reply = response.choices[0].message.content: Extrae la respuesta del asistente de la respuesta de la API.
    • conversation_history.append({"role": "assistant", "content": assistant_reply}): Añade la respuesta del asistente al historial de conversación.
    • session["conversation_history"] = conversation_historyCrucial: Actualiza el conversation_history en la sesión, para que se conserve para el siguiente turno de la conversación.
    • return render_template("chat.html", reply=assistant_reply): Renderiza la plantilla "chat.html" y pasa la respuesta del asistente a la plantilla.
  • else:: Maneja las solicitudes GET, que ocurren cuando el usuario carga inicialmente la página.
    • session["conversation_history"] = []: Reinicia el historial cuando el usuario carga la página.
    • assistant_reply = "": Inicializa assistant_reply como una cadena vacía.
    • return render_template("chat.html", reply=assistant_reply): Renderiza la plantilla "chat.html" con una respuesta vacía.
  • if __name__ == "__main__":: Esto asegura que el servidor de desarrollo Flask se inicie solo cuando el script se ejecuta directamente (no cuando se importa como módulo).
  • app.run(debug=True): Inicia el servidor de desarrollo Flask en modo debug. El modo debug proporciona mensajes de error útiles y recarga automática cuando se realizan cambios en el código.

Paso 3: Crear una Plantilla HTML Simple (templates/chat.html)

<!DOCTYPE html>
<html>
<head><title>Flask Chatbot</title></head>
<body>
  <h2>GPT-4o Chatbot</h2>
  <form method="post">
    <textarea name="user_input" rows="4" cols="50"></textarea><br>
    <input type="submit" value="Send">
  </form>
  <hr>
  <p><strong>Assistant:</strong> {{ reply }}</p>
</body>
</html>

Desglose del código:

  • &lt;!DOCTYPE html&gt;: Declara el tipo de documento como HTML5.
  • &lt;html&gt;: El elemento raíz del documento HTML.
  • &lt;head&gt;: Contiene metadatos sobre el documento HTML.
    • &lt;title&gt;: Especifica el título de la página HTML, que se muestra en la barra de título o pestaña del navegador.
  • &lt;body&gt;: Contiene el contenido visible de la página HTML.
    • &lt;h2&gt;: Define un encabezado de nivel 2.
    • &lt;form method="post"&gt;: Define un formulario HTML que envía datos usando el método POST.
      • &lt;textarea&gt;: Un campo de entrada de texto multilínea donde el usuario puede ingresar su consulta. El atributo name está configurado como "user_input", que se usa para acceder a la entrada en el código Flask.
      • &lt;input type="submit" value="Send"&gt;: Un botón de envío que manda los datos del formulario al servidor.
    • &lt;hr&gt;: Una línea horizontal, usada para separar contenido.
    • &lt;p&gt;: Un elemento de párrafo para mostrar la respuesta del asistente.
      • &lt;strong&gt;: Define texto enfatizado (generalmente mostrado en negrita).
      • {{ reply }}: Una variable de plantilla Jinja que será reemplazada con el valor de la variable reply pasada desde el código Flask.
  • templates: Flask, por defecto, busca las plantillas HTML en una carpeta llamada "templates" en el mismo directorio que tu archivo app.py. Por lo tanto, este archivo debe guardarse como templates/chat.html.

Este ejemplo crea una aplicación de chatbot robusta y funcional. Para implementarla, crea una carpeta templates en el mismo directorio que tu archivo app.py, guarda la plantilla HTML como chat.html dentro de esa carpeta, y configura la variable de entorno OPENAI_API_KEY.

4.1.4 Streamlit

Streamlit representa un avance revolucionario en el desarrollo de aplicaciones de datos. Este framework basado en Python ha transformado fundamentalmente cómo los desarrolladores abordan la creación de aplicaciones web. En su esencia, Streamlit encarna una filosofía de simplicidad y eficiencia, permitiendo a los desarrolladores convertir scripts de Python estándar en aplicaciones web sofisticadas con mínima sobrecarga de código.

Lo que lo distingue de los frameworks web convencionales es su enfoque innovador - mientras que los frameworks tradicionales exigen amplia experiencia en HTML, CSS y JavaScript, Streamlit introduce un cambio de paradigma al proporcionar una capa de abstracción a través de sus llamadas API intuitivas. Esta decisión de diseño lo ha convertido en una herramienta invaluable, particularmente para científicos de datos e ingenieros de aprendizaje automático que ahora pueden concentrarse en sus competencias principales mientras crean demostraciones interactivas de nivel profesional.

Exploremos en detalle su conjunto completo de características:

  • Widgets incorporados para visualización de datos interactiva - La extensa biblioteca de componentes de Streamlit incluye gráficos sofisticados, gráficos interactivos, controles deslizantes personalizables y campos de entrada versátiles. Estos componentes preconfigurados eliminan la necesidad de experiencia en desarrollo frontend, permitiendo a los creadores concentrarse en la presentación de datos en lugar de las complejidades del desarrollo web. El framework maneja toda la renderización compleja y la gestión de estado tras bambalinas.
  • Recarga automática durante el desarrollo - El entorno de desarrollo de Streamlit cuenta con un sistema inteligente de monitoreo de archivos que supervisa los cambios en tu código fuente. Cuando se detectan modificaciones, actualiza automáticamente la aplicación web, creando una experiencia de desarrollo fluida. Esta característica reduce significativamente el tiempo de desarrollo al eliminar el ciclo tradicional de guardar-actualizar común en el desarrollo web.
  • Soporte nativo para frameworks de aprendizaje automático - La profunda integración del framework con bibliotecas populares de aprendizaje automático como TensorFlow, PyTorch y scikit-learn va más allá de la simple compatibilidad. Proporciona componentes especializados y optimizaciones para flujos de trabajo de ML, convirtiéndolo en una plataforma ideal para crear demostraciones interactivas de modelos, interfaces de predicción en tiempo real y herramientas educativas para conceptos de aprendizaje automático.
  • Proceso de implementación simple - La infraestructura de implementación de Streamlit ha sido cuidadosamente diseñada para minimizar la complejidad operativa. Ya sea usando la plataforma en la nube de Streamlit o servicios de alojamiento alternativos, el proceso de implementación se ha simplificado para requerir una configuración mínima. Este enfoque asegura que los desarrolladores puedan compartir rápidamente sus aplicaciones con las partes interesadas sin quedar atrapados en tecnicismos de implementación.
  • Manejo de interacción del usuario en tiempo real - El framework incorpora mecanismos sofisticados de gestión de estado y caché que operan perfectamente en segundo plano. Estos sistemas aseguran un rendimiento óptimo durante interacciones complejas del usuario, gestionando el flujo de datos y las actualizaciones de componentes de manera eficiente sin requerir que los desarrolladores implementen lógica backend personalizada. Esto resulta en aplicaciones receptivas que pueden manejar tareas computacionales complejas mientras mantienen experiencias de usuario fluidas.

4.1.5 Implementación de Chatbot con Streamlit

Este ejemplo crea un chatbot usando Streamlit y la API de OpenAI. Es una aplicación simple que permite a los usuarios interactuar con el modelo GPT-4o a través de una interfaz de chat. La aplicación mantiene el historial de chat usando el estado de sesión de Streamlit. Esta versión mejorada incluye manejo de errores, un prompt de sistema y una barra lateral para configuraciones adicionales.

Paso 1: Instalar Dependencias

pip install streamlit openai python-dotenv

Desglose del código:

  • streamlit: Una biblioteca de Python para crear aplicaciones web interactivas, en este caso, la interfaz del chatbot.
  • openai: La biblioteca de Python de OpenAI para interactuar con el modelo GPT-4o.
  • python-dotenv: Una biblioteca para cargar variables de entorno desde un archivo .env.

Paso 2: Crear la Aplicación Streamlit (chatbot.py)

import streamlit as st
import openai
import os
from dotenv import load_dotenv
import time  # For handling potential API errors


load_dotenv()
openai.api_key = os.getenv("OPENAI_API_KEY")


# --- Configuration ---
SYSTEM_PROMPT = "You are a helpful, friendly, and knowledgeable assistant.  Answer all questions clearly and concisely."
DEFAULT_MODEL = "gpt-4o"
MAX_CONTEXT_MESSAGES = 10  # Limit conversation history


# --- Helper Functions ---
def get_openai_response(messages, model=DEFAULT_MODEL):
    """
    Sends a message to OpenAI's Chat API and handles potential errors.
    Args:
        messages: A list of message dictionaries.
        model: The OpenAI model to use.  Defaults to gpt-4o
    Returns:
        The assistant's reply, or an error message.
    """
    try:
        response = openai.ChatCompletion.create(
            model=model,
            messages=messages,
            timeout=60,  # Add a timeout to prevent hanging
        )
        return response.choices[0].message.content
    except openai.error.OpenAIError as e:
        st.error(f"OpenAI API Error: {e}")
        return f"Sorry, I encountered an error: {e}"
    except Exception as e:
        st.error(f"An unexpected error occurred: {e}")
        return "Sorry, I encountered an unexpected error."



def initialize_session_state():
    """Initializes session state variables."""
    if "messages" not in st.session_state:
        st.session_state.messages = [{"role": "system", "content": SYSTEM_PROMPT}]
    if "display_messages" not in st.session_state:
        st.session_state.display_messages = [{"role": "system", "content": SYSTEM_PROMPT}] # Separate list for displayed messages
    if "model" not in st.session_state:
        st.session_state.model = DEFAULT_MODEL


# --- Main App ---
def main():
    initialize_session_state()

    # --- Sidebar ---
    st.sidebar.header("Settings")
    model = st.sidebar.selectbox("Model", ["gpt-4o", "gpt-3.5-turbo"], index=0)  # Add model selection
    st.session_state.model = model #update the model
    clear_history = st.sidebar.button("Clear Chat History")
    if clear_history:
        st.session_state.messages = [{"role": "system", "content": SYSTEM_PROMPT}]
        st.session_state.display_messages = [{"role": "system", "content": SYSTEM_PROMPT}]  # Clear displayed messages too
        st.rerun()  # Force a rerun to update the display

    st.title("🧠 GPT-4o Chatbot with Memory") #moved title

    # Display previous messages
    for message in st.session_state.display_messages:
        if message["role"] != "system":  # Don't display the system prompt
            with st.chat_message(message["role"]):
                st.markdown(message["content"])

    # User input
    user_input = st.chat_input("You:", key="user_input")  # Use key for chat_input


    if user_input:
        st.session_state.messages.append({"role": "user", "content": user_input})
        st.session_state.display_messages.append({"role": "user", "content": user_input}) # Also add to display list

        # Get assistant reply
        reply = get_openai_response(st.session_state.messages, model=st.session_state.model)
        st.session_state.messages.append({"role": "assistant", "content": reply})
        st.session_state.display_messages.append({"role": "assistant", "content": reply}) # Also add to display list

        with st.chat_message("assistant"):
            st.markdown(reply)

        # Keep only the last MAX_CONTEXT_MESSAGES messages (including system prompt)
        st.session_state.messages = st.session_state.messages[:1] + st.session_state.messages[-MAX_CONTEXT_MESSAGES + 1:]
        st.rerun() # Force a rerun to update the display



if __name__ == "__main__":
    main()

Analicemos este código de chatbot en Streamlit:

1. Importaciones y Configuración

  • Importa las bibliotecas esenciales (streamlit, openai, os, dotenv) para la funcionalidad del chat
  • Carga las variables de entorno y configura la clave API de OpenAI

2. Configuración

  • Define el prompt del sistema para la personalidad del chatbot
  • Establece el modelo predeterminado (gpt-4o) y el máximo de mensajes de contexto (10)

3. Funciones Auxiliares

  • get_openai_response(): Gestiona la comunicación API con OpenAI
    • Incluye manejo de errores para problemas de API
    • Establece un tiempo límite de 60 segundos
    • Devuelve la respuesta o mensaje de error
  • initialize_session_state(): Configura el estado de sesión de Streamlit
    • Crea historial de mensajes para llamadas API
    • Mantiene mensajes de visualización separados
    • Inicializa la selección del modelo

4. Aplicación Principal

  • Barra lateral con ajustes:
    • Menú desplegable de selección de modelo
    • Botón para borrar historial de chat
  • Interfaz de chat:
    • Muestra historial de mensajes
    • Maneja entrada del usuario
    • Muestra respuestas del bot
    • Mantiene contexto de conversación dentro del límite de mensajes

5. Características Principales

  • Gestión de memoria mediante estado de sesión
  • Manejo de errores para llamadas API
  • Limitación del historial de mensajes para rendimiento
  • Actualizaciones de chat en tiempo real usando componentes de chat de Streamlit

Este ejemplo proporciona un chatbot fácil de usar con mejor manejo de errores, un prompt de sistema y un límite en el historial de conversación. También permite al usuario seleccionar el modelo.

4.1 Implementaciones de Flask y Streamlit

En este capítulo exhaustivo, aprenderás a construir un chatbot sofisticado pero accesible para principiantes que demuestra capacidades avanzadas de memoria. A diferencia de los chatbots simples que solo responden al último mensaje, esta implementación mantendrá el contexto durante conversaciones completas, permitiendo interacciones más naturales y contextualmente conscientes. Trabajarás con dos potentes frameworks de Python para aplicaciones web: Flask, un micro-framework flexible que te da control total sobre tu aplicación, y Streamlit, un framework moderno diseñado para el desarrollo rápido de aplicaciones.

El capítulo proporciona una guía detallada paso a paso para ambos frameworks, permitiéndote elegir el enfoque que mejor se adapte a tus necesidades. Ya sea que elijas el control granular de Flask o el proceso de desarrollo simplificado de Streamlit, aprenderás a integrar tu chatbot con el modelo GPT-4o de OpenAI, aprovechando sus capacidades avanzadas de procesamiento del lenguaje natural para conversaciones inteligentes.

Al completar este capítulo, habrás creado un chatbot completamente funcional con estas características esenciales:

  • Se ejecuta en una aplicación web local - Tu chatbot operará a través de una interfaz web que podrás acceder desde cualquier navegador en tu máquina local
  • Maneja la entrada del usuario en tiempo real - La aplicación procesará y responderá a los mensajes del usuario inmediatamente, creando un flujo de conversación fluido
  • Mantiene memoria de conversación multiturnos - Tu chatbot recordará los intercambios previos y usará este contexto para proporcionar respuestas más relevantes y coherentes
  • Utiliza la API de Chat Completions de OpenAI para elaborar respuestas - Aprenderás a integrar la potente API de OpenAI para generar respuestas similares a las humanas basadas en el contexto de la conversación

Comenzaremos con 11.1 Implementaciones de Flask y Streamlit, proporcionando una exploración profunda de ambos frameworks y guiándote a través del proceso de configuración para cada enfoque. Aprenderás las ventajas específicas y consideraciones para ambas implementaciones, permitiéndote tomar una decisión informada para tu proyecto.

Profundicemos en estas poderosas herramientas de desarrollo web para entender sus arquitecturas, capacidades y casos de uso. Cada framework ofrece ventajas únicas para construir aplicaciones web, y entender sus características te ayudará a tomar una decisión informada para tu implementación de chatbot:

Flask es un micro framework web ligero y versátil para Python. Se le llama "micro" porque proporciona solo los componentes esenciales que necesitas para construir una aplicación web, dándote control completo sobre la arquitectura de tu proyecto. Las características principales incluyen:

  • Sistema de enrutamiento para manejar peticiones HTTP
  • Motor de plantillas para generación dinámica de HTML
  • Servidor de desarrollo incorporado
  • Documentación extensa y gran soporte de la comunidad
  • Fácil integración con varias extensiones

Streamlit es un framework moderno basado en Python diseñado específicamente para crear aplicaciones de datos con mínimo esfuerzo. Transforma scripts de Python en aplicaciones web compartibles a través de llamadas API simples. Las características notables incluyen:

  • Widgets incorporados para visualización interactiva de datos
  • Recarga automática durante el desarrollo
  • Soporte nativo para frameworks de aprendizaje automático
  • Proceso de implementación simple
  • Manejo de interacción del usuario en tiempo real

Ambos frameworks sobresalen en diferentes escenarios — Flask ofrece control granular y flexibilidad para aplicaciones web personalizadas, mientras que Streamlit se especializa en prototipado rápido y aplicaciones enfocadas en datos. Te invitamos a explorar uno o ambos enfoques mientras procedemos con la implementación. Veamos una implementación detallada de cada uno para ayudarte a entender sus fortalezas únicas.

Eligiendo Entre Flask y Streamlit

Considera probar ambos frameworks para ganar experiencia valiosa. Flask te dará perspectivas más profundas sobre conceptos de desarrollo web como enrutamiento, plantillas y solicitudes HTTP. Mientras tanto, Streamlit sobresale en prototipado rápido y es perfecto cuando necesitas demostrar funcionalidad rápidamente sin gastar tiempo en desarrollo frontend.

4.1.1 Eligiendo entre Flask y Streamlit: Una Comparación Detallada

Comencemos con una exploración exhaustiva de las consideraciones clave al elegir entre Flask y Streamlit para tu proyecto de chatbot. Ambos frameworks ofrecen ventajas distintivas y posibles compensaciones que pueden impactar significativamente tu experiencia de desarrollo y la aplicación final. Comprender estas diferencias te ayudará a tomar una decisión informada que se alinee con los objetivos de tu proyecto, requisitos técnicos y cronograma de desarrollo.

Flask y Streamlit representan dos enfoques filosóficos diferentes para el desarrollo de aplicaciones web. Flask encarna el concepto de microframework, proporcionando a los desarrolladores control y flexibilidad completos, mientras que Streamlit enfatiza el desarrollo rápido y resultados inmediatos a través de su enfoque optimizado y estructurado. La elección entre ellos a menudo depende de factores como la complejidad del proyecto, la personalización requerida, los requisitos de implementación y la experiencia técnica de tu equipo.

Al decidir entre Flask y Streamlit para tu proyecto de chatbot, exploremos estos factores clave en detalle:

  • Flask requiere más configuración inicial pero ofrece mayor control:
    • Necesitarás crear y configurar rutas para manejar diferentes puntos finales URL
    • La configuración de plantillas HTML requiere comprensión del desarrollo frontend
    • El manejo manual de solicitudes HTTP te da control minucioso sobre el flujo de datos
    • La gestión de sesiones y autenticación de usuarios necesitan implementación personalizada
    • Este nivel de control es poderoso pero requiere experiencia más profunda en desarrollo web y más tiempo de desarrollo
  • Streamlit permite prototipado rápido con configuración mínima:
    • Las funciones simples de Python pueden crear elementos web interactivos instantáneamente
    • La gestión de estado incorporada maneja la persistencia de datos automáticamente
    • No es necesario entender HTML, CSS o JavaScript
    • Los widgets interactivos están disponibles de forma inmediata
    • Perfecto para prototipos rápidos y aplicaciones enfocadas en datos donde la velocidad de desarrollo es crucial
  • Requisitos de la Aplicación
    • Elige Flask para aplicaciones web complejas y personalizadas:
      • Perfecto para proyectos que requieren personalización detallada de la interfaz de usuario y lógica backend
      • Ideal cuando necesitas control granular sobre sistemas de autenticación y gestión de usuarios
      • Excelente para aplicaciones con requisitos complejos de enrutamiento y múltiples endpoints
      • Mejor opción cuando tu aplicación necesita integrarse con varios servicios externos y APIs
      • Adecuado para proyectos que pueden necesitar escalar significativamente en el futuro
      • Recomendado cuando tienes desarrolladores experimentados que entienden los principios de desarrollo web
    • Elige Streamlit para aplicaciones centradas en datos que necesitan implementación rápida:
      • Excelente para proyectos de visualización de datos y paneles analíticos
      • Perfecto para prototipado rápido de interfaces de modelos de aprendizaje automático
      • Ideal para proyectos donde los científicos de datos necesitan demostrar resultados rápidamente
      • Genial para aplicaciones que se centran principalmente en la presentación e interacción con datos
      • Adecuado para equipos que quieren minimizar la sobrecarga del desarrollo frontend
      • Mejor cuando necesitas iterar rápidamente en características basadas en retroalimentación del usuario
  • Flask proporciona libertad completa de personalización frontend:
    • Diseña interfaces completamente personalizadas usando HTML, CSS y JavaScript
    • Crea diseños pixel-perfect y diseños específicos de marca
    • Implementa interacciones y animaciones complejas
    • Construye diseños responsivos que funcionan en todos los dispositivos
    • Añade bibliotecas y frameworks JavaScript personalizados según sea necesario
    • Crea experiencias de usuario únicas sin limitaciones
  • Streamlit ofrece componentes preconfigurados ideales para visualización de datos:
    • Conjunto rico de widgets listos para usar (gráficos, tablas, diagramas)
    • Elementos interactivos como deslizadores, botones y campos de entrada
    • Actualizaciones de datos y visualizaciones en tiempo real
    • Soporte nativo para bibliotecas populares de visualización de datos
    • API simple para crear interfaces complejas sin experiencia frontend
    • Capacidades de prototipado rápido para aplicaciones basadas en datos
  • Escalabilidad a Largo Plazo y Arquitectura del Sistema
    • La flexibilidad de Flask permite una escalabilidad robusta:
      • La arquitectura modular permite añadir nuevas características sin interrumpir el código existente
      • Soporta escalado horizontal a través de múltiples servidores para aumentar la capacidad
      • Fácil integración con balanceadores de carga y microservicios
      • Compatible con varios sistemas de bases de datos (SQL, NoSQL, bases de datos distribuidas)
      • Permite implementación de estrategias complejas de caché
      • Soporta middleware personalizado para optimización de rendimiento
      • Permite sistemas sofisticados de autenticación y autorización
    • La arquitectura de Streamlit tiene limitaciones específicas:
      • Construido principalmente para aplicaciones de una sola página y paneles de datos
      • Puede enfrentar desafíos de rendimiento con grandes bases de usuarios concurrentes
      • Opciones limitadas para enrutamiento complejo y gestión de URLs
      • Capacidad restringida para implementar gestión compleja de estado
      • Puede volverse más difícil de mantener a medida que crece la lógica de negocio
      • Menos adecuado para arquitectura de microservicios
      • Puede requerir reescritura completa al escalar más allá de cierta complejidad

4.1.2 Flask

Flask es un micro framework web potente y versátil para Python que ha revolucionado el desarrollo web con su elegante simplicidad y notable flexibilidad. Cuando lo llamamos framework "micro", esto no significa que tenga capacidades limitadas - más bien, sigue una filosofía minimalista donde los desarrolladores comienzan con un núcleo liviano y construyen exactamente lo que necesitan. Este enfoque reflexivo elimina la complejidad innecesaria mientras otorga a los desarrolladores un control sin precedentes sobre la arquitectura de su aplicación. Flask permite a los desarrolladores crear desde APIs simples hasta aplicaciones web complejas, manteniendo siempre un código limpio y mantenible.

Profundicemos en las características clave de Flask y entendamos por qué lo convierten en una opción tan poderosa:

  • Sistema de enrutamiento para manejar solicitudes HTTP - El sofisticado mecanismo de enrutamiento de Flask va más allá del simple mapeo de URLs. Proporciona una sintaxis basada en decoradores que hace intuitiva la creación de APIs RESTful, admite patrones de URL dinámicos con reglas variables y permite jerarquías de URL complejas. Esta flexibilidad permite a los desarrolladores estructurar sus aplicaciones de manera lógica mientras mantienen esquemas de URL limpios.
  • Motor de plantillas para generación dinámica de HTML - La integración con Jinja2, uno de los motores de plantillas más potentes de Python, ofrece mucho más que la generación básica de HTML. Proporciona herencia de plantillas para código DRY (No Te Repitas), filtros personalizados para manipulación de datos, procesadores de contexto para variables globales y soporte de macros para componentes HTML reutilizables. Estas características hacen posible crear código frontend sofisticado y mantenible sin sacrificar flexibilidad.
  • Servidor de desarrollo incorporado - El servidor de desarrollo de Flask es una herramienta sofisticada que va más allá del servicio HTTP básico. Incluye características como recarga automática cuando el código cambia, páginas de depuración detalladas con trazas de pila interactivas y la capacidad de manejar múltiples solicitudes concurrentes. Si bien es perfecto para desarrollo, Flask realiza una transición sin problemas a servidores de nivel de producción como Gunicorn o uWSGI cuando estás listo para implementar.
  • Documentación extensa y gran soporte de la comunidad - La documentación de Flask no es solo exhaustiva - es una clase magistral en desarrollo web con Python. Cada característica está explicada a fondo con ejemplos prácticos, mejores prácticas y consideraciones de seguridad. La vibrante comunidad contribuye con innumerables extensiones, tutoriales y soluciones a problemas comunes, haciendo de Flask uno de los frameworks mejor respaldados en el ecosistema Python.
  • Fácil integración con varias extensiones - El sistema de extensiones de Flask es un testimonio de su excelente diseño. A través de una API consistente, las extensiones pueden agregar características sofisticadas como soporte ORM para bases de datos (SQLAlchemy), validación de formularios (WTForms), autenticación de usuarios (Flask-Login), documentación de API (Swagger/OpenAPI) y mucho más. Estas extensiones mantienen la naturaleza liviana de Flask mientras proporcionan funcionalidad de nivel empresarial cuando se necesita.

4.1.3 Implementación del Chatbot con Flask

Este ejemplo implementa un chatbot simple usando Flask y la API de OpenAI. El chatbot recibe la entrada del usuario a través de un formulario web, la envía al modelo GPT-4o de OpenAI y muestra la respuesta del modelo en el navegador. También mantiene un historial básico de conversación.

Paso 1: Instalar Dependencias

pip install flask openai python-dotenv
  • flask: Un framework web para construir la aplicación del chatbot.
  • openai: La biblioteca de Python de OpenAI para interactuar con el modelo GPT-4o.
  • python-dotenv: Una biblioteca para cargar variables de entorno desde un archivo .env.

Paso 2: Crear la Aplicación Flask (app.py)

from flask import Flask, request, render_template, session
import openai
import os
from dotenv import load_dotenv

load_dotenv()
openai.api_key = os.getenv("OPENAI_API_KEY")

app = Flask(__name__)
app.secret_key = os.urandom(24)  # Required for session

@app.route("/", methods=["GET", "POST"])
def chat():
    # Use session to store conversation history
    if "conversation_history" not in session:
        session["conversation_history"] = []

    conversation_history = session["conversation_history"]

    if request.method == "POST":
        user_input = request.form["user_input"]
        conversation_history.append({"role": "user", "content": user_input})

        try:
            response = openai.ChatCompletion.create(
                model="gpt-4o",
                messages=[
                    {"role": "system", "content": "You are a helpful assistant."}
                ] + conversation_history
            )
            assistant_reply = response.choices[0].message.content
            conversation_history.append({"role": "assistant", "content": assistant_reply})
            session["conversation_history"] = conversation_history #save the updated history

        except openai.error.OpenAIError as e:
            assistant_reply = f"Error: {e}"
            conversation_history.append({"role": "assistant", "content": assistant_reply})
            session["conversation_history"] = conversation_history

        return render_template("chat.html", reply=assistant_reply)

    else:
        # Reset the history.  Important for starting a new chat.
        session["conversation_history"] = []
        assistant_reply = "" # Initialize
        return render_template("chat.html", reply=assistant_reply)

if __name__ == "__main__":
    app.run(debug=True)

Desglose del código

  • from flask import ...: Importa los módulos necesarios de Flask.
    • Flask: La clase Flask para crear la aplicación web.
    • request: Para acceder a los datos de solicitudes entrantes (datos de formularios).
    • render_template: Para renderizar plantillas HTML.
    • session: Para gestionar sesiones de usuario. El historial de conversación ahora se almacena en la sesión.
  • import openai: Importa la biblioteca OpenAI.
  • import os: Importa el módulo os para variables de entorno.
  • from dotenv import load_dotenv: Importa load_dotenv para cargar variables desde un archivo .env.
  • load_dotenv(): Carga las variables de entorno desde un archivo .env.
  • openai.api_key = os.getenv("OPENAI_API_KEY"): Obtiene la clave API de OpenAI desde la variable de entorno OPENAI_API_KEY y la configura para la biblioteca OpenAI.
  • app = Flask(__name__): Crea una instancia de la aplicación Flask.
  • app.secret_key = os.urandom(24)Importante: Establece una clave secreta para la aplicación Flask. Esto es necesario para usar sesiones. os.urandom(24) genera una clave aleatoria criptográficamente segura.
  • @app.route("/", methods=["GET", "POST"]): Este decorador define una ruta para la URL raíz ("/"). La función chat() manejará tanto solicitudes GET como POST a esta URL.
  • def chat():: La función que maneja las solicitudes a la URL raíz.
  • if "conversation_history" not in session: session["conversation_history"] = []: Esto es crucial para persistir el historial de conversación entre solicitudes. El historial de conversación se almacena como una lista de diccionarios en la sesión del usuario. Si conversation_history no está en la sesión, se inicializa como una lista vacía.
  • conversation_history = session["conversation_history"]: Obtiene el historial de conversación de la sesión.
  • if request.method == "POST":: Maneja las solicitudes POST, que ocurren cuando el usuario envía el formulario.
    • user_input = request.form["user_input"]: Obtiene la entrada del usuario desde los datos del formulario. El campo de entrada en la plantilla HTML se llama "user_input".
    • conversation_history.append({"role": "user", "content": user_input}): Añade la entrada del usuario al historial de conversación.
    • try...except openai.error.OpenAIError as e: Incluye manejo de errores para errores de la API de OpenAI.
    • response = openai.ChatCompletion.create(...): Llama a la API de OpenAI para obtener una respuesta del modelo GPT-4o.
      • model: Especifica el modelo de lenguaje a usar ("gpt-4o").
      • messages: Una lista de diccionarios de mensajes que representa el historial de conversación. El mensaje del sistema se incluye al principio, seguido por el historial de conversación.
    • assistant_reply = response.choices[0].message.content: Extrae la respuesta del asistente de la respuesta de la API.
    • conversation_history.append({"role": "assistant", "content": assistant_reply}): Añade la respuesta del asistente al historial de conversación.
    • session["conversation_history"] = conversation_historyCrucial: Actualiza el conversation_history en la sesión, para que se conserve para el siguiente turno de la conversación.
    • return render_template("chat.html", reply=assistant_reply): Renderiza la plantilla "chat.html" y pasa la respuesta del asistente a la plantilla.
  • else:: Maneja las solicitudes GET, que ocurren cuando el usuario carga inicialmente la página.
    • session["conversation_history"] = []: Reinicia el historial cuando el usuario carga la página.
    • assistant_reply = "": Inicializa assistant_reply como una cadena vacía.
    • return render_template("chat.html", reply=assistant_reply): Renderiza la plantilla "chat.html" con una respuesta vacía.
  • if __name__ == "__main__":: Esto asegura que el servidor de desarrollo Flask se inicie solo cuando el script se ejecuta directamente (no cuando se importa como módulo).
  • app.run(debug=True): Inicia el servidor de desarrollo Flask en modo debug. El modo debug proporciona mensajes de error útiles y recarga automática cuando se realizan cambios en el código.

Paso 3: Crear una Plantilla HTML Simple (templates/chat.html)

<!DOCTYPE html>
<html>
<head><title>Flask Chatbot</title></head>
<body>
  <h2>GPT-4o Chatbot</h2>
  <form method="post">
    <textarea name="user_input" rows="4" cols="50"></textarea><br>
    <input type="submit" value="Send">
  </form>
  <hr>
  <p><strong>Assistant:</strong> {{ reply }}</p>
</body>
</html>

Desglose del código:

  • &lt;!DOCTYPE html&gt;: Declara el tipo de documento como HTML5.
  • &lt;html&gt;: El elemento raíz del documento HTML.
  • &lt;head&gt;: Contiene metadatos sobre el documento HTML.
    • &lt;title&gt;: Especifica el título de la página HTML, que se muestra en la barra de título o pestaña del navegador.
  • &lt;body&gt;: Contiene el contenido visible de la página HTML.
    • &lt;h2&gt;: Define un encabezado de nivel 2.
    • &lt;form method="post"&gt;: Define un formulario HTML que envía datos usando el método POST.
      • &lt;textarea&gt;: Un campo de entrada de texto multilínea donde el usuario puede ingresar su consulta. El atributo name está configurado como "user_input", que se usa para acceder a la entrada en el código Flask.
      • &lt;input type="submit" value="Send"&gt;: Un botón de envío que manda los datos del formulario al servidor.
    • &lt;hr&gt;: Una línea horizontal, usada para separar contenido.
    • &lt;p&gt;: Un elemento de párrafo para mostrar la respuesta del asistente.
      • &lt;strong&gt;: Define texto enfatizado (generalmente mostrado en negrita).
      • {{ reply }}: Una variable de plantilla Jinja que será reemplazada con el valor de la variable reply pasada desde el código Flask.
  • templates: Flask, por defecto, busca las plantillas HTML en una carpeta llamada "templates" en el mismo directorio que tu archivo app.py. Por lo tanto, este archivo debe guardarse como templates/chat.html.

Este ejemplo crea una aplicación de chatbot robusta y funcional. Para implementarla, crea una carpeta templates en el mismo directorio que tu archivo app.py, guarda la plantilla HTML como chat.html dentro de esa carpeta, y configura la variable de entorno OPENAI_API_KEY.

4.1.4 Streamlit

Streamlit representa un avance revolucionario en el desarrollo de aplicaciones de datos. Este framework basado en Python ha transformado fundamentalmente cómo los desarrolladores abordan la creación de aplicaciones web. En su esencia, Streamlit encarna una filosofía de simplicidad y eficiencia, permitiendo a los desarrolladores convertir scripts de Python estándar en aplicaciones web sofisticadas con mínima sobrecarga de código.

Lo que lo distingue de los frameworks web convencionales es su enfoque innovador - mientras que los frameworks tradicionales exigen amplia experiencia en HTML, CSS y JavaScript, Streamlit introduce un cambio de paradigma al proporcionar una capa de abstracción a través de sus llamadas API intuitivas. Esta decisión de diseño lo ha convertido en una herramienta invaluable, particularmente para científicos de datos e ingenieros de aprendizaje automático que ahora pueden concentrarse en sus competencias principales mientras crean demostraciones interactivas de nivel profesional.

Exploremos en detalle su conjunto completo de características:

  • Widgets incorporados para visualización de datos interactiva - La extensa biblioteca de componentes de Streamlit incluye gráficos sofisticados, gráficos interactivos, controles deslizantes personalizables y campos de entrada versátiles. Estos componentes preconfigurados eliminan la necesidad de experiencia en desarrollo frontend, permitiendo a los creadores concentrarse en la presentación de datos en lugar de las complejidades del desarrollo web. El framework maneja toda la renderización compleja y la gestión de estado tras bambalinas.
  • Recarga automática durante el desarrollo - El entorno de desarrollo de Streamlit cuenta con un sistema inteligente de monitoreo de archivos que supervisa los cambios en tu código fuente. Cuando se detectan modificaciones, actualiza automáticamente la aplicación web, creando una experiencia de desarrollo fluida. Esta característica reduce significativamente el tiempo de desarrollo al eliminar el ciclo tradicional de guardar-actualizar común en el desarrollo web.
  • Soporte nativo para frameworks de aprendizaje automático - La profunda integración del framework con bibliotecas populares de aprendizaje automático como TensorFlow, PyTorch y scikit-learn va más allá de la simple compatibilidad. Proporciona componentes especializados y optimizaciones para flujos de trabajo de ML, convirtiéndolo en una plataforma ideal para crear demostraciones interactivas de modelos, interfaces de predicción en tiempo real y herramientas educativas para conceptos de aprendizaje automático.
  • Proceso de implementación simple - La infraestructura de implementación de Streamlit ha sido cuidadosamente diseñada para minimizar la complejidad operativa. Ya sea usando la plataforma en la nube de Streamlit o servicios de alojamiento alternativos, el proceso de implementación se ha simplificado para requerir una configuración mínima. Este enfoque asegura que los desarrolladores puedan compartir rápidamente sus aplicaciones con las partes interesadas sin quedar atrapados en tecnicismos de implementación.
  • Manejo de interacción del usuario en tiempo real - El framework incorpora mecanismos sofisticados de gestión de estado y caché que operan perfectamente en segundo plano. Estos sistemas aseguran un rendimiento óptimo durante interacciones complejas del usuario, gestionando el flujo de datos y las actualizaciones de componentes de manera eficiente sin requerir que los desarrolladores implementen lógica backend personalizada. Esto resulta en aplicaciones receptivas que pueden manejar tareas computacionales complejas mientras mantienen experiencias de usuario fluidas.

4.1.5 Implementación de Chatbot con Streamlit

Este ejemplo crea un chatbot usando Streamlit y la API de OpenAI. Es una aplicación simple que permite a los usuarios interactuar con el modelo GPT-4o a través de una interfaz de chat. La aplicación mantiene el historial de chat usando el estado de sesión de Streamlit. Esta versión mejorada incluye manejo de errores, un prompt de sistema y una barra lateral para configuraciones adicionales.

Paso 1: Instalar Dependencias

pip install streamlit openai python-dotenv

Desglose del código:

  • streamlit: Una biblioteca de Python para crear aplicaciones web interactivas, en este caso, la interfaz del chatbot.
  • openai: La biblioteca de Python de OpenAI para interactuar con el modelo GPT-4o.
  • python-dotenv: Una biblioteca para cargar variables de entorno desde un archivo .env.

Paso 2: Crear la Aplicación Streamlit (chatbot.py)

import streamlit as st
import openai
import os
from dotenv import load_dotenv
import time  # For handling potential API errors


load_dotenv()
openai.api_key = os.getenv("OPENAI_API_KEY")


# --- Configuration ---
SYSTEM_PROMPT = "You are a helpful, friendly, and knowledgeable assistant.  Answer all questions clearly and concisely."
DEFAULT_MODEL = "gpt-4o"
MAX_CONTEXT_MESSAGES = 10  # Limit conversation history


# --- Helper Functions ---
def get_openai_response(messages, model=DEFAULT_MODEL):
    """
    Sends a message to OpenAI's Chat API and handles potential errors.
    Args:
        messages: A list of message dictionaries.
        model: The OpenAI model to use.  Defaults to gpt-4o
    Returns:
        The assistant's reply, or an error message.
    """
    try:
        response = openai.ChatCompletion.create(
            model=model,
            messages=messages,
            timeout=60,  # Add a timeout to prevent hanging
        )
        return response.choices[0].message.content
    except openai.error.OpenAIError as e:
        st.error(f"OpenAI API Error: {e}")
        return f"Sorry, I encountered an error: {e}"
    except Exception as e:
        st.error(f"An unexpected error occurred: {e}")
        return "Sorry, I encountered an unexpected error."



def initialize_session_state():
    """Initializes session state variables."""
    if "messages" not in st.session_state:
        st.session_state.messages = [{"role": "system", "content": SYSTEM_PROMPT}]
    if "display_messages" not in st.session_state:
        st.session_state.display_messages = [{"role": "system", "content": SYSTEM_PROMPT}] # Separate list for displayed messages
    if "model" not in st.session_state:
        st.session_state.model = DEFAULT_MODEL


# --- Main App ---
def main():
    initialize_session_state()

    # --- Sidebar ---
    st.sidebar.header("Settings")
    model = st.sidebar.selectbox("Model", ["gpt-4o", "gpt-3.5-turbo"], index=0)  # Add model selection
    st.session_state.model = model #update the model
    clear_history = st.sidebar.button("Clear Chat History")
    if clear_history:
        st.session_state.messages = [{"role": "system", "content": SYSTEM_PROMPT}]
        st.session_state.display_messages = [{"role": "system", "content": SYSTEM_PROMPT}]  # Clear displayed messages too
        st.rerun()  # Force a rerun to update the display

    st.title("🧠 GPT-4o Chatbot with Memory") #moved title

    # Display previous messages
    for message in st.session_state.display_messages:
        if message["role"] != "system":  # Don't display the system prompt
            with st.chat_message(message["role"]):
                st.markdown(message["content"])

    # User input
    user_input = st.chat_input("You:", key="user_input")  # Use key for chat_input


    if user_input:
        st.session_state.messages.append({"role": "user", "content": user_input})
        st.session_state.display_messages.append({"role": "user", "content": user_input}) # Also add to display list

        # Get assistant reply
        reply = get_openai_response(st.session_state.messages, model=st.session_state.model)
        st.session_state.messages.append({"role": "assistant", "content": reply})
        st.session_state.display_messages.append({"role": "assistant", "content": reply}) # Also add to display list

        with st.chat_message("assistant"):
            st.markdown(reply)

        # Keep only the last MAX_CONTEXT_MESSAGES messages (including system prompt)
        st.session_state.messages = st.session_state.messages[:1] + st.session_state.messages[-MAX_CONTEXT_MESSAGES + 1:]
        st.rerun() # Force a rerun to update the display



if __name__ == "__main__":
    main()

Analicemos este código de chatbot en Streamlit:

1. Importaciones y Configuración

  • Importa las bibliotecas esenciales (streamlit, openai, os, dotenv) para la funcionalidad del chat
  • Carga las variables de entorno y configura la clave API de OpenAI

2. Configuración

  • Define el prompt del sistema para la personalidad del chatbot
  • Establece el modelo predeterminado (gpt-4o) y el máximo de mensajes de contexto (10)

3. Funciones Auxiliares

  • get_openai_response(): Gestiona la comunicación API con OpenAI
    • Incluye manejo de errores para problemas de API
    • Establece un tiempo límite de 60 segundos
    • Devuelve la respuesta o mensaje de error
  • initialize_session_state(): Configura el estado de sesión de Streamlit
    • Crea historial de mensajes para llamadas API
    • Mantiene mensajes de visualización separados
    • Inicializa la selección del modelo

4. Aplicación Principal

  • Barra lateral con ajustes:
    • Menú desplegable de selección de modelo
    • Botón para borrar historial de chat
  • Interfaz de chat:
    • Muestra historial de mensajes
    • Maneja entrada del usuario
    • Muestra respuestas del bot
    • Mantiene contexto de conversación dentro del límite de mensajes

5. Características Principales

  • Gestión de memoria mediante estado de sesión
  • Manejo de errores para llamadas API
  • Limitación del historial de mensajes para rendimiento
  • Actualizaciones de chat en tiempo real usando componentes de chat de Streamlit

Este ejemplo proporciona un chatbot fácil de usar con mejor manejo de errores, un prompt de sistema y un límite en el historial de conversación. También permite al usuario seleccionar el modelo.