En esta sección, exploraremos la interfaz para gestionar las API, que requiere varios tipos de API: una para que DeepL gestione la traducción de datos, otra para eludir el CAPTCHA y otra para el análisis de texto.

Los temas tratados en esta sección incluyen:

  1. Modelos de base de datos
  2. Backend para la gestión de API
  3. Frontend para la gestión de API
  4. Pruebas

Este capítulo será sencillo, ya que presenta las operaciones CRUD básicas. CRUD son las siglas de Create, Read, Update y Delete (crear, leer, actualizar y eliminar), operaciones fundamentales en el desarrollo de aplicaciones. De hecho, la mayoría de las aplicaciones se basan principalmente en la funcionalidad CRUD.


Modelos de base de datos

Tus modelos se encuentran dentro de app/database/models.py.

Así es como se ve la tabla para almacenar API:

class APIs(Base):
    __tablename__ = "apis"
    id = Column(Integer, primary_key=True, index=True)
    api_name = Column(String, unique=True, index=True)
    api_provider = Column(String)
    api_type = Column(String)
    api_key = Column(String)
    model = Column(String)
    prompt = Column(Text)
    max_tokens = Column(Integer)
    timestamp = Column(DateTime, default=datetime.utcnow)
    is_active = Column(Boolean, default=False)

Algunas API incluyen un parámetro llamado temperatura, pero no lo almacenaremos aquí. Según mi experiencia, la temperatura predeterminada de 0.1 es suficiente para la mayoría de las consultas. Sin embargo, puedes experimentar añadiendo una columna de temperatura a la base de datos, lo que requeriría las correspondientes actualizaciones tanto en el backend como en el frontend.


Backend para la gestión de API

El código para gestionar las API se encuentra dentro de app/routes/manage_api.py. A diferencia de otras rutas, esta no utiliza ningún servicio ni módulo de scraping.

El script manage_api.py define las rutas FastAPI para gestionar las configuraciones de las API (por ejemplo, DeepL, Anthropic, OpenAI) en la aplicación tornet_scraper, interactuando con la base de datos para crear, actualizar, eliminar, listar y activar las API. A continuación se ofrece una explicación concisa de sus componentes y funcionalidades clave.

Variables globales

  1. logger:
    • Propósito: Configura el registro para la depuración y el seguimiento de errores.
    • Detalles: Utiliza el módulo logging con el nivel INFO para registrar operaciones y errores.
  2. manage_api_router:
    • Propósito: Enrutador FastAPI para puntos finales de gestión de API.
    • Detalles: Configurado con el prefijo /api/manage-api y las etiquetas [«API», «API Management»] para su organización.

Modelos Pydantic

  1. DeepLCreateRequest:
    • Propósito: Valida los datos de la solicitud POST para crear una API DeepL.
    • Campos: api_name (str), api_key (str).
  2. IABCreateRequest:
    • Propósito: Valida los datos de la solicitud POST para crear una API Anthropic (IAB).
    • Campos: api_name (str), api_key (str), model (str), max_tokens (int), prompt (str).
  3. CaptchaCreateRequest:
    • Finalidad: Valida los datos de la solicitud POST para crear una API OpenAI (Captcha).
    • Campos: api_name (str), api_key (str), model (str), max_tokens (int), prompt (str).
  4. UpdateRequest:
    • Finalidad: Valida los datos de la solicitud PUT para actualizar una API.
    • Campos: api_name (str), api_key (str), model (str, opcional), max_tokens (int, opcional), prompt (str, opcional).

Funciones

  1. set_active_api:

    • Propósito: Activa una API específica y desactiva otras del mismo proveedor.
    • Parámetros clave:
      • db: SQLAlchemy Session para operaciones de base de datos.
      • api_id: ID entero de la API que se va a activar.
      • api_provider: Cadena que identifica el proveedor (por ejemplo, deepl, anthropic).
    • Devuelve: Ninguno.
    • Detalles: Actualiza el campo is_active a False para todas las API del mismo proveedor, excepto la api_id especificada, que se establece en True. Confirma los cambios en la base de datos.
  2. create_deepl_api:

    • Propósito: Crea una nueva configuración de API DeepL.
    • Parámetros clave:
      • request: DeepLCreateRequest con el nombre y la clave de la API.
      • db: SQLAlchemy Session.
    • Devuelve: JSONResponse con un mensaje de éxito.
    • Detalles: comprueba si hay duplicados de api_name, crea una instancia del modelo APIs (api_provider=«deepl», api_type=«translation_api»), la guarda en la base de datos y devuelve una respuesta de éxito. Genera una HTTPException (400 para duplicados, 500 para errores).
  3. create_iab_api:

    • Propósito: Crea una nueva configuración de API de Anthropic (IAB).
    • Parámetros clave:
      • request: IABCreateRequest con nombre de API, clave, modelo, tokens máximos y mensaje.
      • db: SQLAlchemy Session.
    • Devuelve: JSONResponse con mensaje de éxito.
    • Detalles: Similar a create_deepl_api, pero establece api_provider=«anthropic», api_type=«iab_api». Valida y almacena campos adicionales (model, max_tokens, prompt).
  4. create_captcha_api:

    • Propósito: Crea una nueva configuración de API OpenAI (Captcha).
    • Parámetros clave:
      • request: CaptchaCreateRequest con nombre de API, clave, modelo, tokens máximos y mensaje.
      • db: SQLAlchemy Session.
    • Devuelve: JSONResponse con mensaje de éxito.
    • Detalles: Similar a create_iab_api, pero establece api_provider=«openai», api_type=«captcha_api».
  5. list_apis:

    • Propósito: Recupera todas las configuraciones de API.
    • Parámetros clave:
      • db: SQLAlchemy Session.
    • Devuelve: Diccionario con una lista de API (ID, nombre, proveedor, tipo, clave, modelo, tokens máximos, mensaje, marca de tiempo, estado activo).
    • Detalles: Consulta todos los registros APIs y los devuelve como JSON. Genera una HTTPException (500) en caso de error.
  6. update_api:

    • Propósito: Actualiza una configuración de API existente.
    • Parámetros clave:
      • api_id: ID entero de la API que se va a actualizar.
      • request: UpdateRequest con los campos actualizados.
      • db: SQLAlchemy Session.
    • Devuelve: JSONResponse con un mensaje de éxito.
    • Detalles: verifica que la API existe, comprueba si hay duplicados de api_name, actualiza los campos (solo valores que no sean None para model, max_tokens, prompt) y confirma los cambios. Genera una excepción HTTPException (404 si no se encuentra, 400 para duplicados, 500 para errores).
  7. delete_api:

    • Propósito: Elimina una configuración de API.
    • Parámetros clave:
      • api_id: ID entero de la API que se va a eliminar.
      • db: Session de SQLAlchemy.
    • Devuelve: JSONResponse con un mensaje de éxito.
    • Detalles: verifica que la API existe, la elimina de la base de datos y la confirma. Genera una excepción HTTPException (404 si no se encuentra, 500 para errores).
  8. activate_api:

    • Propósito: Activa una API específica y desactiva otras del mismo proveedor.
    • Parámetros clave:
      • api_id: ID entero de la API que se va a activar.
      • db: SQLAlchemy Session.
    • Devuelve: JSONResponse con un mensaje de éxito.
    • Detalles: verifica que la API existe, llama a set_active_api para alternar is_active y devuelve un mensaje de éxito. Genera una HTTPException (404 si no se encuentra, 500 para errores).
  9. get_api:

    • Propósito: recupera una única configuración de API por ID.
    • Parámetros clave:
      • api_id: ID entero de la API.
      • db: Session de SQLAlchemy.
    • Devuelve: Diccionario con los detalles de la API (ID, nombre, proveedor, tipo, clave, modelo, tokens máximos, mensaje, marca de tiempo, estado activo).
    • Detalles: Consulta la tabla APIs para el ID especificado y devuelve sus detalles. Genera una HTTPException (404 si no se encuentra, 500 en caso de error).

Interfaz para la gestión de API

El código de la interfaz se encuentra dentro de app/templates/manage_api.html.

La plantilla manage_api.html amplía base.html para proporcionar una interfaz de usuario para gestionar las configuraciones de API (DeepL, IAB/Anthropic, Captcha/OpenAI) en la aplicación tornet_scraper. Interactúa con el backend a través de llamadas a la API para crear, actualizar, eliminar, listar y activar API. A continuación se ofrece una explicación concisa de sus funciones clave y su interacción con el backend.

  1. Heredar plantillas:

    • Propósito: Aprovecha el diseño de base.html para mantener una estructura coherente.
    • Interacción con el backend: Hereda la barra de navegación y el manejo de mensajes flash de base.html. Establece el título de la página como «API Management» a través de {% block title %}. Los datos iniciales de la API (apis) se pasan desde main.py::manage_api y se representan en la tabla utilizando Jinja2. Los mensajes flash del backend (almacenados en la sesión) se muestran en el contenedor heredado.
  2. Creación de API:

    • Finalidad: Permite a los usuarios añadir nuevas configuraciones de API para los servicios DeepL, IAB o Captcha.
    • Interacción con el backend:
      • Tres botones («Añadir API DeepL», «Añadir API IAB», «Añadir API Captcha») abren los respectivos modales (addDeepLModal, addIABModal, addCaptchaModal) a través de openModal().
      • Cada modal contiene un formulario con los campos obligatorios (por ejemplo, api_name, api_key para DeepL; model, max_tokens, prompt adicionales para IAB/Captcha).
      • El envío del formulario activa createDeepLAPI(), createIABAPI() o createCaptchaAPI(), que envían solicitudes AJAX POST a /api/manage-api/create/deepl, /iab o /captcha (gestionadas por manage_api.py::create_deepl_api, create_iab_api, create_captcha_api).
      • El backend valida la solicitud (utilizando modelos Pydantic), comprueba si hay duplicados de api_name, guarda la API en la tabla APIs y devuelve un mensaje de éxito. Si se realiza correctamente, se muestra un mensaje flash, se cierra el modal, se restablece el formulario y se actualiza la tabla. Los errores activan un mensaje flash de error.
  3. Visualización y actualizaciones de la tabla API:

    • Objetivo: muestra una lista dinámica de API con estado en tiempo real.
    • Interacción con el backend:
      • La tabla se rellena inicialmente con apis de main.py::manage_api, mostrando el tipo de API, el nombre, la fecha de creación y el estado activo.
      • La función updateTable() se ejecuta cada 10 segundos (a través de setInterval) y después de las acciones de creación/actualización/eliminación/activación, enviando una solicitud AJAX GET a /api/manage-api/list (gestionada por manage_api.py::list_apis).
      • El backend consulta la tabla «APIs» y devuelve una lista JSON de API (ID, nombre, proveedor, tipo, clave, modelo, tokens máximos, mensaje, marca de tiempo, estado activo). La tabla se actualiza con estos datos, mostrando las etiquetas «Activo» o «Inactivo». Los errores activan un mensaje de error emergente.
  4. Edición de API:

    • Objetivo: Actualiza las configuraciones de API existentes.
    • Interacción con el backend:
      • Cada fila de la tabla tiene un botón «Editar» que llama a openEditModal(apiId), enviando una solicitud AJAX GET a /api/manage-api/get/{api_id} (gestionada por manage_api.py::get_api).
      • El backend devuelve los detalles de la API, que rellenan el formulario editAPIModal. Para las API de DeepL, solo se muestran los campos api_name y api_key; para IAB/Captcha, se muestran los campos adicionales model, max_tokens y prompt.
      • El envío del formulario activa updateAPI(), que envía una solicitud AJAX PUT a /api/manage-api/update/{api_id} (gestionada por manage_api.py::update_api) con los campos actualizados. El backend valida y actualiza la tabla APIs, devolviendo un mensaje de éxito. Si se realiza correctamente, se muestra un mensaje flash, se cierra el modal y se actualiza la tabla. Los errores activan un mensaje flash de error.
  5. Eliminación de API:

    • Objetivo: Elimina una configuración de API.
    • Interacción con el backend:
      • Cada fila de la tabla tiene un botón «Eliminar» que llama a openDeleteModal(apiId), abriendo el deleteAPIModal con el ID de la API almacenado en un campo oculto.
      • El botón «Eliminar» activa confirmDeleteAPI(), que envía una solicitud AJAX DELETE a /api/manage-api/delete/{api_id} (gestionada por manage_api.py::delete_api).
      • El backend verifica que la API existe, la elimina de la tabla APIs y devuelve un mensaje de éxito. Si se realiza correctamente, se muestra un mensaje flash, se cierra el modal y se actualiza la tabla. Los errores activan un mensaje flash de error.
  6. Activación de API:

    • Propósito: Activa una API específica y desactiva otras del mismo proveedor.
    • Interacción con el backend:
      • Cada fila de la tabla tiene un botón «Activar» (desactivado si ya está activo) que llama a activateAPI(apiId, apiType), enviando una solicitud AJAX POST a /api/manage-api/activate/{api_id} (gestionado por manage_api.py::activate_api).
      • El backend llama a set_active_api para establecer is_active=True para la API especificada y False para otras del mismo proveedor, confirmando los cambios en la tabla APIs. Si se realiza correctamente, se muestra un mensaje flash y la tabla se actualiza. Los errores activan un mensaje flash de error.

Aunque no es obligatorio utilizar Anthropic u OpenAI, he simplificado el proceso para facilitar su uso. En otra aplicación, implementé la compatibilidad con cuatro proveedores diferentes, que ofrecen docenas de modelos. Sin embargo, este nivel de flexibilidad suele ser innecesario, ya que añade complejidad al código del backend.


Pruebas

A continuación se muestra cómo se pueden añadir dos API de DeepL, pero activar solo una de ellas en cada momento.

Prueba de gestión de API