datadis_python.client.v1.simple_client module

Cliente V1 simplificado para Datadis.

class datadis_python.client.v1.simple_client.SimpleDatadisClientV1(username, password, timeout=120, retries=3)[fuente]

Bases: object

Cliente simplificado para la API V1 de Datadis.

Este cliente proporciona una interfaz fácil de usar para acceder a los datos de consumo eléctrico almacenados en las bases de datos de las distribuidoras eléctricas españolas a través de la plataforma Datadis.

Características principales: - Autenticación automática y renovación de tokens - Manejo robusto de timeouts y reintentos - Validación de datos con Pydantic para mayor seguridad - Soporte para tipos flexibles en parámetros de entrada - Context manager para gestión automática de recursos

Ejemplo

Uso básico del cliente:

from datadis_python.client.v1 import SimpleDatadisClientV1

# Inicializar el cliente
client = SimpleDatadisClientV1(
    username="12345678A",
    password="mi_password",
    timeout=120,
    retries=3
)

# Usar como context manager (recomendado)
with SimpleDatadisClientV1("12345678A", "mi_password") as client:
    # Obtener suministros
    supplies = client.get_supplies()

    # Obtener consumo para un suministro específico
    if supplies:
        consumption = client.get_consumption(
            cups=supplies[0].cups,
            distributor_code=supplies[0].distributorCode,
            date_from="2024/01",
            date_to="2024/12"
        )
Parámetros:
  • username (str) – NIF del usuario registrado en Datadis (ej: «12345678A»)

  • password (str) – Contraseña de acceso a la plataforma Datadis

  • timeout (int) – Timeout para requests HTTP en segundos. 120s por defecto debido a la lentitud característica de la API de Datadis

  • retries (int) – Número de reintentos automáticos en caso de fallos de red o timeouts. 3 intentos por defecto

Muestra:
__init__(username, password, timeout=120, retries=3)[fuente]

Inicializa el cliente simplificado.

Parámetros:
  • username (str) – NIF del usuario

  • password (str) – Contraseña

  • timeout (int) – Timeout en segundos (120s por defecto para Datadis)

  • retries (int) – Número de reintentos

authenticate()[fuente]

Autentica con la API de Datadis y obtiene el token de acceso.

Realiza una petición POST al endpoint /nikola-auth/tokens/login de la API de Datadis para obtener un token Bearer que será utilizado en todas las peticiones subsecuentes. El token se almacena automáticamente y se añade a los headers de la sesión HTTP.

Nota

Este método normalmente NO necesita ser llamado manualmente, ya que la autenticación se realiza automáticamente cuando se ejecuta cualquier método que requiera acceso a la API (como get_supplies(), get_consumption(), etc.).

Advertencia

Los tokens de Datadis tienen expiración, pero la renovación se maneja automáticamente cuando se detecta un error 401 (Unauthorized).

Ejemplo

Autenticación manual (opcional):

client = SimpleDatadisClientV1("12345678A", "mi_password")

# Verificar credenciales antes de hacer operaciones
if client.authenticate():
    print("Credenciales válidas")
    supplies = client.get_supplies()
else:
    print("Error en las credenciales")
Devuelve:

True si la autenticación fue exitosa, False en caso contrario

Tipo del valor devuelto:

bool

Muestra:
  • AuthenticationError – Si las credenciales (NIF/contraseña) son inválidas o el servidor devuelve un error de autenticación

  • DatadisError – Si ocurre un timeout o error de conexión con el servidor

Ver también

  • Documentación oficial: POST /nikola-auth/tokens/login

  • Los tokens son válidos por tiempo limitado y se renuevan automáticamente

get_supplies(authorized_nif=None, distributor_code=None)[fuente]

Obtiene la lista de puntos de suministro (CUPS) asociados al usuario.

Consulta el endpoint GET /api-private/api/get-supplies para obtener todos los puntos de suministro eléctrico que el usuario tiene registrados en Datadis. Los datos se validan automáticamente usando Pydantic para garantizar la integridad y consistencia de la información.

Los puntos de suministro incluyen información detallada como: - Código CUPS (identificador único del punto de suministro) - Dirección física del suministro - Código postal, provincia y municipio - Distribuidor eléctrico y su código - Fechas de validez del contrato - Tipo de punto de medida (1-5)

Códigos de distribuidor más comunes:
  • 1: Viesgo

  • 2: E-distribución (Endesa)

  • 3: E-redes

  • 4: ASEME

  • 5: UFD (Naturgy)

  • 6: EOSA

  • 7: CIDE

  • 8: IDE

Ejemplo

Obtener todos los suministros del usuario:

with SimpleDatadisClientV1("12345678A", "password") as client:
    supplies = client.get_supplies()

    for supply in supplies:
        print(f"CUPS: {supply.cups}")
        print(f"Dirección: {supply.address}")
        print(f"Distribuidor: {supply.distributor} (código: {supply.distributorCode})")
        print(f"Tipo: {supply.pointType}")
        print("---")

Filtrar por distribuidor específico:

# Solo suministros de Endesa (E-distribución)
supplies_endesa = client.get_supplies(distributor_code=2)

# También funciona con string
supplies_endesa = client.get_supplies(distributor_code="2")
Parámetros:
  • authorized_nif (Optional[str]) – NIF de una persona autorizada para consultar sus suministros. Si se especifica, se obtendrán los suministros de esa persona en lugar de los del usuario autenticado

  • distributor_code (Optional[Union[str, int]]) – Código del distribuidor para filtrar suministros. Acepta tanto enteros como strings (ej: 2 o «2»)

Devuelve:

Lista de objetos SupplyData validados con Pydantic, cada uno representando un punto de suministro con toda su información asociada

Tipo del valor devuelto:

List[SupplyData]

Muestra:
  • AuthenticationError – Si las credenciales son inválidas o el token expira

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

  • DatadisError – Si ocurren errores de conexión o timeouts repetidos

  • ValidationError – Si los datos devueltos no pasan la validación Pydantic

Ver también

  • Documentación oficial: GET /api-private/api/get-supplies

  • Para obtener detalles del contrato: get_contract_detail()

  • Lista completa de códigos de distribuidor en la documentación de la API

get_distributors()[fuente]

Obtiene la lista de distribuidores eléctricos donde el usuario tiene suministros.

Consulta el endpoint GET /api-private/api/get-distributors-with-supplies para obtener información sobre las distribuidoras eléctricas donde el usuario autenticado tiene puntos de suministro activos. Esto es útil para conocer qué distribuidores están disponibles antes de realizar consultas específicas.

La respuesta incluye los códigos únicos de cada distribuidor, que son necesarios para realizar consultas posteriores como obtener consumos, contratos o potencias máximas de suministros específicos.

Distribuidores eléctricos en España:
  • Código 1: Viesgo (Cantabria, Asturias)

  • Código 2: E-distribución/Endesa (Nacional)

  • Código 3: E-redes (Galicia)

  • Código 4: ASEME (Melilla)

  • Código 5: UFD/Naturgy (Nacional)

  • Código 6: EOSA (Aragón)

  • Código 7: CIDE (Ceuta)

  • Código 8: IDE (Baleares)

Ejemplo

Listar distribuidores del usuario:

with SimpleDatadisClientV1("12345678A", "password") as client:
    distributors = client.get_distributors()

    print("Distribuidores con suministros:")
    for dist in distributors:
        print(f"- {dist.distributorName} (Código: {dist.distributorCode})")

    # Usar el primer distribuidor para consultas posteriores
    if distributors:
        first_dist_code = distributors[0].distributorCode
        supplies = client.get_supplies(distributor_code=first_dist_code)
Devuelve:

Lista de objetos DistributorData validados con Pydantic. Cada objeto contiene el código y nombre del distribuidor donde el usuario tiene suministros activos

Tipo del valor devuelto:

List[DistributorData]

Muestra:
  • AuthenticationError – Si las credenciales son inválidas o el token expira

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

  • DatadisError – Si ocurren errores de conexión o timeouts repetidos

  • ValidationError – Si los datos devueltos no pasan la validación Pydantic

Ver también

Nota

Solo se devuelven distribuidores donde el usuario tiene suministros activos. Si no hay suministros registrados, la lista estará vacía.

get_contract_detail(cups, distributor_code)[fuente]

Obtiene los detalles del contrato eléctrico para un punto de suministro específico.

Consulta el endpoint GET /api-private/api/get-contract-detail para obtener información detallada del contrato asociado a un CUPS específico. Los datos incluyen información técnica, comercial y administrativa del suministro eléctrico.

Información del contrato incluida:
  • Datos básicos: CUPS, distribuidor, comercializadora

  • Características técnicas: Tensión, potencia contratada, tipo de punto

  • Datos tarifarios: Tarifa de acceso, discriminación horaria, código de tarifa

  • Ubicación: Provincia, municipio, código postal

  • Fechas: Inicio y fin de contrato, fechas de cambios

  • Autoconsumo: Tipo y características (si aplica)

  • Control de potencia: ICP o Maxímetro

  • CAU: Código de Autoconsumo Único (si es aplicable)

Types de punto de medida:
  • Tipo 1: > 450 kW (alta tensión)

  • Tipo 2: 50-450 kW (media tensión)

  • Tipo 3: 15-50 kW (baja tensión)

  • Tipo 4: < 15 kW con discriminación horaria

  • Tipo 5: < 15 kW sin discriminación horaria

Ejemplo

Obtener detalles de contrato:

with SimpleDatadisClientV1("12345678A", "password") as client:
    # Primero obtener suministros
    supplies = client.get_supplies()

    if supplies:
        supply = supplies[0]

        # Obtener detalles del contrato
        contracts = client.get_contract_detail(
            cups=supply.cups,
            distributor_code=supply.distributorCode
        )

        for contract in contracts:
            print(f"CUPS: {contract.cups}")
            print(f"Distribuidor: {contract.distributor}")
            print(f"Potencia contratada: {contract.contractedPowerkW} kW")
            print(f"Tarifa: {contract.accessFare}")
            print(f"Tipo de punto: {contract.pointType}")
            if contract.marketer:
                print(f"Comercializadora: {contract.marketer}")

Usando tipos flexibles de parámetros:

# Ambos formatos son válidos
contracts1 = client.get_contract_detail("ES001234567890123456AB", 2)
contracts2 = client.get_contract_detail("ES001234567890123456AB", "2")
Parámetros:
  • cups (str) – Código CUPS del punto de suministro (22 caracteres alfanuméricos que identifican únicamente el punto de suministro eléctrico)

  • distributor_code (Union[str, int]) – Código numérico del distribuidor eléctrico. Acepta tanto enteros como strings para mayor flexibilidad

Devuelve:

Lista de objetos ContractData validados con Pydantic. Normalmente contiene un solo contrato, pero pueden ser varios si ha habido cambios históricos en el suministro

Tipo del valor devuelto:

List[ContractData]

Muestra:
  • AuthenticationError – Si las credenciales son inválidas o el token expira

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

  • DatadisError – Si ocurren errores de conexión o timeouts repetidos

  • ValidationError – Si los datos devueltos no pasan la validación Pydantic

  • ValueError – Si el CUPS no tiene el formato correcto (22 caracteres)

Ver también

  • Documentación oficial: GET /api-private/api/get-contract-detail

  • Para obtener la lista de CUPS: get_supplies()

  • Para datos de consumo del contrato: get_consumption()

Nota

El CUPS debe ser exactamente de 22 caracteres alfanuméricos. Si el formato es incorrecto, la API devolverá un error.

get_consumption(cups, distributor_code, date_from, date_to, measurement_type=0, point_type=None)[fuente]

Obtiene los datos de consumo eléctrico para un punto de suministro específico.

Consulta el endpoint GET /api-private/api/get-consumption-data para obtener la curva de carga (datos de consumo) de un CUPS en un período determinado. Los datos incluyen consumo, excedentes, generación y autoconsumo cuando aplique.

IMPORTANTE - Limitación de fechas:

La API de Datadis SOLO acepta fechas en formato mensual (YYYY/MM). NO se permiten fechas con días específicos. El SDK convierte automáticamente fechas datetime/date al formato requerido.

IMPORTANTE - Disponibilidad de datos cuarto-horarios:

Los datos cada 15 minutos (measurement_type=1) solo están disponibles para: - Tipos de punto 1 y 2 (alta y media tensión) - Tipo de punto 3 en E-distribución únicamente - Para el resto de casos, solo están disponibles datos horarios (measurement_type=0)

Tipos de medición:
  • 0: Datos horarios (disponible para todos los tipos de punto)

  • 1: Datos cuarto-horarios/15 min (limitado según tipo de punto)

Tipos de punto de medida:
  • 1: > 450 kW - Datos horarios y cuarto-horarios

  • 2: 50-450 kW - Datos horarios y cuarto-horarios

  • 3: 15-50 kW - Cuarto-horarios solo en E-distribución

  • 4: < 15 kW con DH - Solo datos horarios

  • 5: < 15 kW sin DH - Solo datos horarios

Datos incluidos en la respuesta:
  • Consumo: Energía consumida de la red (kWh)

  • Excedentes: Energía vertida a la red (kWh)

  • Generación: Energía generada por autoconsumo (kWh)

  • Autoconsumo: Energía autoconsumida directamente (kWh)

  • Método de obtención: Real (medido) o Estimada (calculada)

Ejemplo

Obtener consumo horario para todo un año:

with SimpleDatadisClientV1("12345678A", "password") as client:
    supplies = client.get_supplies()

    if supplies:
        supply = supplies[0]

        # Consumo horario del año 2024
        consumption = client.get_consumption(
            cups=supply.cups,
            distributor_code=supply.distributorCode,
            date_from="2024/01",  # Enero 2024
            date_to="2024/12",    # Diciembre 2024
            measurement_type=0    # Datos horarios
        )

        # Analizar los datos
        total_kwh = sum(c.consumptionKWh for c in consumption if c.consumptionKWh)
        print(f"Consumo total 2024: {total_kwh:.2f} kWh")

        # Filtrar datos reales vs estimados
        real_data = [c for c in consumption if c.obtainMethod == "Real"]
        print(f"Datos reales: {len(real_data)}/{len(consumption)}")

Obtener datos cuarto-horarios (solo para tipos 1, 2, y 3 en E-distribución):

# Solo si el tipo de punto lo permite
consumption_15min = client.get_consumption(
    cups="ES001234567890123456AB",
    distributor_code=2,  # E-distribución
    date_from="2024/06",
    date_to="2024/06",
    measurement_type=1,  # Cuarto-horarios
    point_type=3         # Tipo de punto
)

Usando diferentes tipos de fecha:

from datetime import date, datetime

# Con strings (recomendado)
consumption1 = client.get_consumption(cups, dist_code, "2024/01", "2024/03")

# Con objetos datetime (se convertirán automáticamente)
start_date = datetime(2024, 1, 1)
end_date = datetime(2024, 3, 31)
consumption2 = client.get_consumption(cups, dist_code, start_date, end_date)
Parámetros:
  • cups (str) – Código CUPS del punto de suministro (22 caracteres alfanuméricos)

  • distributor_code (Union[str, int]) – Código del distribuidor eléctrico (acepta int o str)

  • date_from (Union[str, datetime, date]) – Fecha de inicio en formato YYYY/MM. También acepta objetos datetime/date que se convertirán automáticamente

  • date_to (Union[str, datetime, date]) – Fecha de fin en formato YYYY/MM. También acepta objetos datetime/date que se convertirán automáticamente

  • measurement_type (Union[int, float, str]) – Tipo de medición - 0: horarios (defecto), 1: cuarto-horarios. Acepta int, float o str

  • point_type (Optional[Union[int, float, str]]) – Tipo de punto de medida (1-5). Requerido para datos cuarto-horarios. Acepta int, float o str

Devuelve:

Lista de objetos ConsumptionData validados con Pydantic. Cada objeto representa una lectura de consumo con timestamp

Tipo del valor devuelto:

List[ConsumptionData]

Muestra:
  • AuthenticationError – Si las credenciales son inválidas o el token expira

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

  • DatadisError – Si ocurren errores de conexión o timeouts repetidos

  • ValidationError – Si las fechas no están en formato mensual válido o los datos no pasan la validación Pydantic

  • ValueError – Si se solicitan datos cuarto-horarios para un tipo de punto no compatible

Ver también

  • Documentación oficial: GET /api-private/api/get-consumption-data

  • Para obtener CUPS: get_supplies()

  • Para datos de potencia máxima: get_max_power()

Advertencia

Los datos cuarto-horarios no están disponibles para todos los tipos de punto. Verifique la compatibilidad antes de solicitar measurement_type=1.

get_max_power(cups, distributor_code, date_from, date_to)[fuente]

Obtiene los datos de potencia máxima demandada para un punto de suministro.

Consulta el endpoint GET /api-private/api/get-max-power para obtener las potencias máximas registradas en cada período tarifario durante el rango de fechas especificado. Esta información es crucial para optimizar la potencia contratada y evitar penalizaciones por excesos.

IMPORTANTE - Limitación de fechas:

Al igual que los datos de consumo, la API SOLO acepta fechas en formato mensual (YYYY/MM). El SDK convierte automáticamente fechas datetime/date al primer día del mes correspondiente.

Períodos tarifarios incluidos:
  • VALLE: Período de menor coste energético (madrugada)

  • LLANO: Período de coste intermedio (mañana/tarde)

  • PUNTA: Período de mayor coste energético (mediodía/noche)

  • P1, P2, P3, P4, P5, P6: Períodos específicos según tarifa

La potencia se mide en Vatios (W) y representa la demanda máxima registrada en cada período durante el mes consultado. Esta información es especialmente útil para:

  • Optimizar la potencia contratada

  • Identificar picos de consumo

  • Evaluar la eficiencia energética

  • Planificar instalaciones de autoconsumo

Ejemplo

Obtener potencias máximas del último año:

with SimpleDatadisClientV1("12345678A", "password") as client:
    supplies = client.get_supplies()

    if supplies:
        supply = supplies[0]

        # Potencias máximas de 2024
        max_powers = client.get_max_power(
            cups=supply.cups,
            distributor_code=supply.distributorCode,
            date_from="2024/01",
            date_to="2024/12"
        )

        # Analizar potencias por período
        periods = {}
        for power in max_powers:
            period = power.period
            if period not in periods:
                periods[period] = []
            periods[period].append(power.maxPower)

        # Mostrar potencia máxima por período
        for period, powers in periods.items():
            max_power_w = max(powers)
            max_power_kw = max_power_w / 1000
            print(f"Período {period}: {max_power_kw:.2f} kW")

Identificar el mes con mayor demanda:

# Agrupar por mes
monthly_max = {}
for power in max_powers:
    month = power.date[:7]  # YYYY/MM
    if month not in monthly_max:
        monthly_max[month] = 0
    monthly_max[month] = max(monthly_max[month], power.maxPower)

# Encontrar el mes de mayor demanda
peak_month = max(monthly_max, key=monthly_max.get)
peak_power_kw = monthly_max[peak_month] / 1000
print(f"Mayor demanda: {peak_power_kw:.2f} kW en {peak_month}")
Parámetros:
  • cups (str) – Código CUPS del punto de suministro (22 caracteres alfanuméricos)

  • distributor_code (Union[str, int]) – Código del distribuidor eléctrico (acepta int o str)

  • date_from (Union[str, datetime, date]) – Fecha de inicio en formato YYYY/MM. También acepta objetos datetime/date que se convertirán automáticamente

  • date_to (Union[str, datetime, date]) – Fecha de fin en formato YYYY/MM. También acepta objetos datetime/date que se convertirán automáticamente

Devuelve:

Lista de objetos MaxPowerData validados con Pydantic. Cada objeto representa la potencia máxima registrada en un período específico con fecha, hora y período tarifario

Tipo del valor devuelto:

List[MaxPowerData]

Muestra:
  • AuthenticationError – Si las credenciales son inválidas o el token expira

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

  • DatadisError – Si ocurren errores de conexión o timeouts repetidos

  • ValidationError – Si las fechas no están en formato mensual válido o los datos no pasan la validación Pydantic

  • ValueError – Si el CUPS no tiene el formato correcto

Ver también

Nota

Las potencias se devuelven en Vatios (W). Para obtener kilovatios (kW) divida el valor entre 1000.

close()[fuente]

Cierra la sesión HTTP y libera recursos del cliente.

Este método limpia los recursos utilizados por el cliente: - Cierra la sesión HTTP de requests - Elimina el token de autenticación almacenado - Libera las conexiones de red activas

Es una buena práctica llamar a este método cuando termine de usar el cliente, aunque se recomienda usar el cliente como context manager con with para gestión automática de recursos.

Ejemplo

Uso manual (no recomendado):

client = SimpleDatadisClientV1("12345678A", "password")
try:
    supplies = client.get_supplies()
    # ... más operaciones
finally:
    client.close()  # Limpiar recursos

Uso recomendado con context manager:

with SimpleDatadisClientV1("12345678A", "password") as client:
    supplies = client.get_supplies()
    # ... más operaciones
# close() se llama automáticamente

Nota

Si usa el cliente como context manager (con with), este método se llama automáticamente al salir del bloque.

__enter__()[fuente]

Entrada del context manager para gestión automática de recursos.

Este método se llama automáticamente cuando se usa el cliente con la declaración with. Permite usar el patrón context manager para garantizar la limpieza automática de recursos.

Ejemplo

Uso como context manager (recomendado):

with SimpleDatadisClientV1("12345678A", "password") as client:
    # El método __enter__ se llama aquí automáticamente
    supplies = client.get_supplies()
    consumption = client.get_consumption(...)
    # ... más operaciones
# El método __exit__ se llama automáticamente al salir
Devuelve:

La propia instancia del cliente para usar en el bloque with

Tipo del valor devuelto:

SimpleDatadisClientV1

Ver también

__exit__() - Método de salida del context manager close() - Limpieza manual de recursos

__exit__(exc_type, exc_val, exc_tb)[fuente]

Salida del context manager con limpieza automática de recursos.

Este método se llama automáticamente al salir del bloque with, garantizando que los recursos se liberen correctamente incluso si ocurre una excepción durante la ejecución.

La limpieza incluye: - Cierre de la sesión HTTP - Eliminación del token de autenticación - Liberación de conexiones de red

Ejemplo

El context manager maneja automáticamente las excepciones:

try:
    with SimpleDatadisClientV1("12345678A", "password") as client:
        supplies = client.get_supplies()
        # Si ocurre una excepción aquí...
        raise Exception("Algo salió mal")
except Exception as e:
    # ... los recursos se limpian automáticamente
    print(f"Error: {e}")
# El cliente ya está cerrado y los recursos liberados
Parámetros:
  • exc_type (Optional[type]) – Tipo de excepción que causó la salida (None si no hay excepción)

  • exc_val (Optional[BaseException]) – Instancia de la excepción (None si no hay excepción)

  • exc_tb (Optional[TracebackType]) – Traceback de la excepción (None si no hay excepción)

Devuelve:

None (no suprime excepciones)

Tipo del valor devuelto:

None

Ver también

__enter__() - Método de entrada del context manager close() - Método de limpieza llamado internamente

Nota

Este método no suprime excepciones - si ocurre un error en el bloque with, la excepción se propagará normalmente después de la limpieza.