datadis_python.utils.http module

Cliente HTTP robusto y reutilizable para el SDK de Datadis.

Este módulo proporciona una clase HTTPClient especializada para realizar peticiones HTTP a la API de Datadis con funcionalidades avanzadas como reintentos automáticos, manejo de timeouts, gestión de headers y procesamiento de respuestas.

La clase está optimizada específicamente para las características de la API de Datadis: - Timeouts largos debido a la lentitud característica del servicio - Reintentos automáticos con backoff exponencial para manejar inestabilidad - Soporte para autenticación Bearer Token - Manejo especial de diferentes tipos de contenido (JSON, form-data, texto plano) - Procesamiento de respuestas con normalización de texto para caracteres especiales

Características principales:
  • Gestión automática de reintentos: Backoff exponencial para timeouts y errores de red

  • Flexibilidad de contenido: Soporte para JSON y form-data según el endpoint

  • Manejo robusto de errores: Clasificación inteligente de errores HTTP

  • Integración con Pydantic: Preparado para validación de datos

  • Rate limiting integrado: Delays automáticos para evitar sobrecarga del servidor

Ejemplo

Uso básico del cliente HTTP:

from datadis_python.utils.http import HTTPClient

# Inicializar con configuración personalizada
client = HTTPClient(timeout=120, retries=5)

# Petición GET simple
response = client.make_request(
    method="GET",
    url="https://api.example.com/data",
    params={"param1": "value1"}
)

# Petición POST con autenticación
client.set_auth_header("bearer_token_here")
response = client.make_request(
    method="POST",
    url="https://api.example.com/auth",
    data={"username": "user", "password": "pass"},
    use_form_data=True
)

# Cerrar recursos
client.close()

Uso como context manager (recomendado):

with HTTPClient(timeout=90, retries=3) as client:
    client.set_auth_header("token")
    response = client.make_request("GET", "https://api.example.com/data")
    # El cliente se cierra automáticamente

Advertencia

Este cliente está específicamente optimizado para la API de Datadis. Para uso general, considere usar directamente la biblioteca requests o un cliente HTTP más genérico.

author:

TacoronteRiveroCristian

class datadis_python.utils.http.HTTPClient(timeout=60, retries=3)[fuente]

Bases: object

Cliente HTTP robusto especializado para la API de Datadis.

Esta clase proporciona una interfaz de alto nivel para realizar peticiones HTTP con características específicamente optimizadas para interactuar con la API de Datadis. Incluye manejo automático de reintentos, timeouts largos, gestión de autenticación y procesamiento especializado de respuestas.

Optimizaciones para Datadis:
  • Timeouts largos: Por defecto 60s, recomendado 90-120s para Datadis

  • Reintentos robustos: Backoff exponencial con hasta 5 reintentos

  • Rate limiting: Delays automáticos para evitar sobrecarga del servidor

  • Manejo de encoding: Desactiva compresión gzip para evitar problemas

  • Procesamiento de texto: Normalización automática de caracteres especiales

Estrategia de reintentos:
  • Errores de red y timeouts: Se reintentan automáticamente

  • Errores HTTP 4xx/5xx: Se propagan inmediatamente (no reintentos)

  • Backoff exponencial: 2s → 4s → 8s → 16s → 32s (máximo 10s para timeouts)

  • Error 401: Se propaga para permitir renovación de token

Ejemplo

Configuración típica para Datadis:

# Configuración robusta para API lenta de Datadis
client = HTTPClient(timeout=120, retries=5)

# Autenticación Bearer Token
client.set_auth_header("jwt_token_from_datadis")

# Petición con gestión automática de errores
response = client.make_request(
    method="GET",
    url="https://datadis.es/api-private/api/get-supplies",
    params={"distributor_code": "2"}
)

Diferentes tipos de contenido:

# Para autenticación (form-data)
auth_response = client.make_request(
    method="POST",
    url="https://datadis.es/nikola-auth/tokens/login",
    data={"username": "12345678A", "password": "password"},
    use_form_data=True
)

# Para endpoints de datos (JSON, por defecto)
data_response = client.make_request(
    method="GET",
    url="https://datadis.es/api-private/api/get-consumption-data",
    params={"cups": "ES001234567890123456AB"}
)
Parámetros:
  • timeout (int) – Timeout para peticiones HTTP en segundos. Recomendado: 90-120s para Datadis

  • retries (int) – Número máximo de reintentos automáticos para errores de red/timeouts

Nota

La API de Datadis puede ser muy lenta (60-90 segundos) al procesar consultas complejas que requieren agregar datos de múltiples distribuidoras eléctricas.

Ver también

  • SimpleDatadisClientV1 y SimpleDatadisClientV2 para uso de alto nivel

  • Documentación oficial de Datadis para límites de rate limiting

__init__(timeout=60, retries=3)[fuente]

Inicializa el cliente HTTP con configuración optimizada para Datadis.

Configura una sesión HTTP persistente con headers optimizados y timeouts apropiados para la API de Datadis. La configuración por defecto está pensada para un uso general, pero se recomienda ajustar los valores para Datadis.

Configuración recomendada para Datadis:
  • timeout: 90-120 segundos (la API puede ser muy lenta)

  • retries: 3-5 reintentos (para manejar inestabilidad ocasional)

Parámetros:
  • timeout (int) – Timeout para peticiones HTTP en segundos. Para Datadis se recomienda 90-120s debido a la lentitud del servicio

  • retries (int) – Número máximo de reintentos automáticos para errores de red. 3-5 reintentos recomendados para Datadis por su inestabilidad ocasional

Ejemplo

Configuraciones típicas:

# Configuración conservadora (rápida, pocos reintentos)
client = HTTPClient(timeout=60, retries=2)

# Configuración robusta para Datadis (recomendada)
client = HTTPClient(timeout=120, retries=5)

# Configuración para desarrollo/testing (muy paciente)
client = HTTPClient(timeout=180, retries=3)
make_request(method, url, data=None, params=None, headers=None, use_form_data=False)[fuente]

Realiza una petición HTTP robusta con reintentos automáticos y manejo de errores.

Este método es el núcleo del cliente HTTP y maneja toda la lógica de peticiones incluyendo reintentos con backoff exponencial, manejo de diferentes tipos de contenido, rate limiting automático y procesamiento especializado de respuestas.

Flujo de operación:
  1. Rate limiting: Delay automático de 0.1s (excepto para autenticación)

  2. Configuración de headers: Combina headers por defecto con personalizados

  3. Selección de formato: JSON o form-data según use_form_data

  4. Ejecución con reintentos: Hasta self.retries intentos con backoff exponencial

  5. Procesamiento de respuesta: Manejo especializado según tipo de contenido

Estrategia de reintentos:
  • Errores de red/timeout: Reintentos con backoff: 2s → 4s → 8s → 16s…

  • Errores HTTP: Propagación inmediata sin reintentos

  • Máximo wait: 10 segundos entre reintentos para evitar timeouts excesivos

Tipos de contenido soportados:
  • JSON (por defecto): Para la mayoría de endpoints de datos

  • Form-data: Para autenticación y algunos endpoints legacy

  • Detección automática: Basada en el parámetro use_form_data

Parámetros:
  • method (str) – Método HTTP a usar (GET, POST, PUT, DELETE, etc.)

  • url (str) – URL completa del endpoint a consultar

  • data (Optional[Dict[str, Any]]) – Datos a enviar en el cuerpo de la petición. Para GET se ignora, para POST se usa según use_form_data

  • params (Optional[Dict[str, Any]]) – Parámetros de query string a añadir a la URL

  • headers (Optional[Dict[str, str]]) – Headers HTTP adicionales a combinar con los por defecto. Los headers personalizados tienen prioridad sobre los por defecto

  • use_form_data (bool) – Si True, envía datos como application/x-www-form-urlencoded. Si False (por defecto), envía como application/json

Devuelve:

Respuesta procesada del servidor. El tipo depende del endpoint:

  • JWT tokens: str (para endpoints de autenticación)

  • Datos JSON: Dict[str, Any] o List[Any] (para endpoints de datos)

  • Respuestas de texto: str (para endpoints que no devuelven JSON)

Tipo del valor devuelto:

Union[Dict[str, Any], str, list]

Muestra:
  • DatadisError – Si se agotan todos los reintentos por errores de red/timeouts

  • AuthenticationError – Si hay errores de autenticación (401)

  • APIError – Si la API devuelve errores HTTP (400, 403, 404, 500, etc.)

Ejemplo

Diferentes tipos de peticiones:

# GET con parámetros de query
response = client.make_request(
    method="GET",
    url="https://datadis.es/api-private/api/get-supplies",
    params={"distributor_code": "2", "authorized_nif": "12345678A"}
)

# POST con autenticación (form-data)
token = client.make_request(
    method="POST",
    url="https://datadis.es/nikola-auth/tokens/login",
    data={"username": "12345678A", "password": "mi_password"},
    use_form_data=True
)

# GET con headers personalizados
response = client.make_request(
    method="GET",
    url="https://datadis.es/api-private/api/get-consumption-data",
    params={"cups": "ES001234567890123456AB"},
    headers={"Authorization": f"Bearer {token}"}
)

Nota

El rate limiting automático (delay de 0.1s) se aplica a todas las peticiones excepto las de autenticación para evitar sobrecargar los servidores de Datadis que pueden tener límites de rate restrictivos.

Ver también

  • _handle_response() para detalles del procesamiento de respuestas

  • La normalización de texto se realiza automáticamente en respuestas JSON

close()[fuente]

Cierra la sesión HTTP y libera recursos asociados.

Cierra explícitamente la sesión HTTP subyacente, liberando conexiones de red y otros recursos. Es una buena práctica llamar este método cuando se termina de usar el cliente, especialmente en aplicaciones de larga duración.

Este método es seguro de llamar múltiples veces y no genera errores si la sesión ya está cerrada.

Ejemplo

Uso manual de cierre:

client = HTTPClient(timeout=120, retries=5)
try:
    # Usar cliente para peticiones...
    response = client.make_request("GET", "https://example.com")
finally:
    # Asegurar limpieza de recursos
    client.close()

Uso como context manager (recomendado):

with HTTPClient(timeout=120, retries=5) as client:
    # Usar cliente...
    response = client.make_request("GET", "https://example.com")
    # client.close() se llama automáticamente

Nota

Cuando se usa el cliente como context manager (with statement), este método se llama automáticamente al salir del bloque, por lo que no es necesario llamarlo manualmente.

Tipo del valor devuelto:

None

set_auth_header(token)[fuente]

Establece el header de autorización Bearer Token para todas las peticiones futuras.

Configura el token de autenticación que se añadirá automáticamente a todas las peticiones HTTP subsecuentes. Este método es típicamente llamado después de una autenticación exitosa para configurar el cliente para peticiones autenticadas.

El token se almacena en los headers de la sesión persistent, por lo que se aplicará automáticamente a todas las peticiones realizadas con este cliente hasta que se reemplace con un nuevo token o se elimine.

Parámetros:

token (str) – Token JWT obtenido del endpoint de autenticación de Datadis. Debe ser un token válido sin el prefijo «Bearer « (se añade automáticamente)

Tipo del valor devuelto:

None

Ejemplo

Configurar autenticación después del login:

client = HTTPClient(timeout=120, retries=5)

# Autenticar y obtener token
token = client.make_request(
    method="POST",
    url="https://datadis.es/nikola-auth/tokens/login",
    data={"username": "12345678A", "password": "mi_password"},
    use_form_data=True
)

# Configurar token para peticiones futuras
client.set_auth_header(token)

# Ahora todas las peticiones incluirán el header Authorization
response = client.make_request(
    method="GET",
    url="https://datadis.es/api-private/api/get-supplies"
)

Nota

El token se prefija automáticamente con «Bearer « según el estándar RFC 6750. No incluya este prefijo en el parámetro token.

Ver también

  • remove_auth_header() para eliminar la autenticación

  • RFC 6750 para especificación completa de Bearer Token

remove_auth_header()[fuente]

Elimina el header de autorización de todas las peticiones futuras.

Remueve el token de autenticación de los headers de la sesión, haciendo que las peticiones subsecuentes se realicen sin autenticación. Esto es útil para limpiar credenciales cuando se cambia de usuario o cuando se quiere realizar peticiones no autenticadas.

Esta operación es segura y no genera errores si no existe un header de autorización configurado.

Ejemplo

Limpiar autenticación para cambio de usuario:

# Usuario 1 autenticado
client.set_auth_header(token_user1)
data_user1 = client.make_request("GET", "/get-supplies")

# Cambiar a usuario 2
client.remove_auth_header()  # Limpiar credenciales anteriores
token_user2 = client.make_request(
    "POST", "/nikola-auth/tokens/login",
    data={"username": "87654321B", "password": "other_password"},
    use_form_data=True
)
client.set_auth_header(token_user2)
data_user2 = client.make_request("GET", "/get-supplies")

Peticiones sin autenticación:

client.remove_auth_header()
# Ahora las peticiones no incluirán Authorization header
public_data = client.make_request("GET", "/public-endpoint")

Nota

Después de llamar este método, las peticiones a endpoints que requieren autenticación fallarán con error 401 hasta que se establezca un nuevo token con set_auth_header().

Ver también

Tipo del valor devuelto:

None

__enter__()[fuente]

Método de entrada para context manager.

Permite usar el HTTPClient con la declaración with de Python para gestión automática de recursos. Al entrar en el bloque with, retorna la instancia del cliente lista para usar.

Devuelve:

La instancia del cliente HTTP configurada

Tipo del valor devuelto:

HTTPClient

Ejemplo

Uso como context manager:

with HTTPClient(timeout=120, retries=5) as client:
    # Configurar autenticación
    token = client.make_request(
        "POST", "/auth",
        data={"user": "12345678A", "pass": "password"},
        use_form_data=True
    )
    client.set_auth_header(token)

    # Realizar peticiones
    data = client.make_request("GET", "/api/data")

# client.close() se llama automáticamente aquí

Nota

El uso como context manager es la forma recomendada de usar HTTPClient ya que garantiza la liberación adecuada de recursos de red.

__exit__(exc_type, exc_val, exc_tb)[fuente]

Método de salida para context manager.

Se llama automáticamente al salir del bloque with, garantizando que los recursos del cliente HTTP se liberen adecuadamente, independientemente de si el bloque se completó exitosamente o se produjo una excepción.

Parámetros:
  • exc_type – Tipo de excepción si ocurrió una excepción, None en caso contrario

  • exc_val – Valor de la excepción si ocurrió una excepción, None en caso contrario

  • exc_tb – Traceback de la excepción si ocurrió una excepción, None en caso contrario

Nota

Este método siempre retorna None, lo que significa que no suprime ninguna excepción que pueda haber ocurrido dentro del bloque with. Las excepciones se propagan normalmente después de la limpieza de recursos.