¿Cómo me puedo conectar a las APIs de Prometeo?

En este post vamos a mostrar cómo es el paso a paso para conectarnos a las APIs de Prometeo.

¡Empecemos!

¿Qué necesitamos?

  1. Registrarnos en Prometeo.
  2. Obtener API Key del entorno de sandbox, esta clave se deberá utilizar en todas las peticiones que realices a nuestros endpoints, el cual nos permite autenticar tu usuario (esta clave la tienes que guardar, ¡no la expongas!); por otra parte, el entorno de sandbox nos ayudará a realizar peticiones de prueba para que armes tu integración, todos los datos devueltos en este entorno no son reales.
    Una vez que nos registramos e iniciamos sesión, nos ubicaremos en el dashboard y podremos ver nuestro API Key.

Implementación

Objetivos

  1. Conectarnos a Prometeo en su entorno de sandbox.
  2. Obtener los movimientos de las cuentas.
  3. Obtener los gastos del mes.

Vamos a dar por hecho que ya creaste tu entorno virtual, la implementación que se mostrará a continuación fue desarrollada con Python 3.8.

Ahora instalaremos la librería requests:

pip install requests

1. Conectarnos a Prometeo en su entorno de sandbox

Vamos a armar una estructura que se encargue de la autenticación con Prometeo.

import requests

API_KEY = "OWXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
BASE_URL = "https://banking.sandbox.prometeoapi.com"


class PrometeoAuth:
    def login(self) -> Dict:
        url = f"{BASE_URL}/login/"
        data = {
            "provider": "test",
            "username": "12345",
            "password": "gfdsa"
        }
        headers = {
            "X-API-Key": API_KEY
        }
        response = requests.post(url, data=data, headers=headers)
        if response.ok:
            return response.json()

    def get_session_key(self) -> str:
        login_data: Dict = self.login()
        return login_data.get("key")

    def logout(self) -> bool:
        url = f"{BASE_URL}/logout/"
        params = {
            "key": self.session_key
        }
        headers = {
            "X-API-Key": API_KEY
        }
        response = requests.get(url, params=params, headers=headers)
        return response.ok

def main():
    prometeo_auth = PrometeoAuth()
    session_key: str = prometeo_auth.get_session_key()
    print(session_key)

if __name__== "__main__":
    main()

Línea 3: Colocamos el API Key obtenido previamente.

Línea 8: Creamos una función que se encargará de realizar el login.

Línea 10: Definimos el payload con las credenciales, username y password lo encontramos aquí, el provider es un valor que indica a qué banco vamos a hacer las peticiones, en este caso particular vamos usar el provider “test” ya que nos devuelve datos mockeados del servidor; es decir, datos ficticios que no provienen de ningún banco.

Línea 15: En todas las peticiones que haremos a Prometeo debemos enviar por header el API Key, con esta clave Prometeo autentica e identifica tu usuario. Lo digo por segunda vez: ¡no la reveles!.

Línea 20: Una vez logueados vamos a obtener una respuesta similar al siguiente ejemplo:

{  
  "status": "logged_in",  
  "key": "163d06b2-3378-4383-9868-71c2b6fb28da"  
}

A partir de este diccionario tenemos que obtener el valor que se encuentra en “key”, es el identificador de la sesión (es de tipo uuid) y nos permite agrupar diferentes estados del usuario en todas las llamadas que se hagan posteriormente, por ello tenemos que enviarla como query param en todas las requests que hagamos a excepción del login ya que es quien devuelve este valor. Otra particularidad de esta clave de sesión es que caduca luego de 5 minutos desde la última request realizada.

Línea 26: Esta función la utilizaremos para cerrar la sesión, es decir que la clave de sesión obtenida anteriormente caduca.

Concluimos con el primer objetivo, ya sabemos cómo loguearnos y desloguearnos de las sesiones de Prometeo.


2. Obtener los movimientos de las cuentas

Ya tenemos la clave de sesión, ahora vamos a utilizarla en todas las llamadas que hagamos.

En este nuevo objetivo vamos a buscar los movimientos que tienen las cuentas, pero primero debemos saber cuales son las cuentas que tiene el usuario, por lo que necesitamos el número de cuenta para poder buscar los movimientos de cada una de ellas. Otra aspecto a tener en cuenta es que cada número de cuenta tiene asociado su currency, por ejemplo:

Número de cuenta: 0001 es una cuenta con la divisa UYU (Peso Uruguayo).

Número de cuenta: 0002 es una cuenta con la divisa USD (Dólares).

Primer paso: obtener las cuentas del usuario:

import requests

from typing import Dict, List

API_KEY = "OWXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
BASE_URL = "https://banking.sandbox.prometeoapi.com"


class PrometeoAuth:
    def login(self) -> Dict:
        url = f"{BASE_URL}/login/"
        data = {
            "provider": "test",
            "username": "12345",
            "password": "gfdsa"
        }
        headers = {
            "X-API-Key": API_KEY
        }
        response = requests.post(url, data=data, headers=headers)
        if response.ok:
            return response.json()

    def get_session_key(self) -> str:
        login_data: Dict = self.login()
        return login_data.get("key")

    def logout(self) -> bool:
        url = f"{BASE_URL}/logout/"
        params = {
            "key": self.session_key
        }
        headers = {
            "X-API-Key": API_KEY
        }
        response = requests.get(url, params=params, headers=headers)
        return response.ok


class PrometeoData:
    @classmethod
    def get_accounts(cls, session_key: str) -> List[Dict]:
        url = f"{BASE_URL}/account/"
        params = {
            "key": session_key
        }
        headers = {
            "X-API-Key": API_KEY
        }
        response = requests.get(url, params=params, headers=headers)
        if response.ok:
            return response.json().get("accounts", [])


def main():
    prometeo_auth = PrometeoAuth()
    session_key: str = prometeo_auth.get_session_key()
    accounts: List[Dict] = PrometeoData.get_accounts(session_key)
    print(accounts)

if __name__== "__main__":
    main()

Línea 42: En este método se define la url, params y headers que necesitamos para obtener las cuentas.

Línea 58: Obtenemos una respuesta similar a la del siguiente ejemplo:

[
    {
        "id": "12345",
        "name": "Test Account 1",
        "number": "12345678",
        "branch": "",
        "currency": "UYU",
        "balance": 21000,
    },
    {
        "id": "12346",
        "name": "Test Account 2",
        "number": "87654321",
        "branch": "",
        "currency": "USD",
        "balance": 12000,
    },
]

Ahora, el siguiente paso es obtener los movimientos de estas cuentas, por lo que tenemos que recuperar number y currency de cada cuenta.

Segundo paso: Obtener movimientos de las cuentas en un rango de fechas

import requests

from datetime import datetime
from typing import Dict, List

API_KEY = "OWXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
BASE_URL = "https://banking.sandbox.prometeoapi.com"


class PrometeoAuth:
    def login(self) -> Dict:
        url = f"{BASE_URL}/login/"
        data = {
            "provider": "test",
            "username": "12345",
            "password": "gfdsa"
        }
        headers = {
            "X-API-Key": API_KEY
        }
        response = requests.post(url, data=data, headers=headers)
        if response.ok:
            return response.json()

    def get_session_key(self) -> str:
        login_data: Dict = self.login()
        return login_data.get("key")

    def logout(self) -> bool:
        url = f"{BASE_URL}/logout/"
        params = {
            "key": self.session_key
        }
        headers = {
            "X-API-Key": API_KEY
        }
        response = requests.get(url, params=params, headers=headers)
        return response.ok


class PrometeoData:
    @classmethod
    def get_accounts(cls, session_key: str) -> List[Dict]:
        url = f"{BASE_URL}/account/"
        params = {
            "key": session_key
        }
        headers = {
            "X-API-Key": API_KEY
        }
        response = requests.get(url, params=params, headers=headers)
        if response.ok:
            return response.json().get("accounts", [])

    @classmethod
    def get_account_movements(cls, session_key:str, account_number: str, currency: str, date_start: datetime, date_end: datetime) -> List[Dict]:
        url = f"{BASE_URL}/account/{account_number}/movement/"
        params = {
            "accountNumber": account_number,
            "currency": currency,
            "date_start": date_start.strftime("%d/%m/%Y"),
            "date_end": date_end.strftime("%d/%m/%Y"),
            "key": session_key
        }
        headers = {
            "X-API-Key": API_KEY
        }
        response = requests.get(url, params=params, headers=headers)
        if response.ok:
            return response.json().get("movements", [])


def main():
    prometeo_auth = PrometeoAuth()
    session_key: str = prometeo_auth.get_session_key()
    accounts: List[Dict] = PrometeoData.get_accounts(session_key)
    for account in accounts:
        movements_data = PrometeoData.get_account_movements(
            session_key,
            account["number"],
            account["currency"],
            datetime(2022, 2, 1),
            datetime(2022, 2, 16)
        )
        print(movements_data)

if __name__== "__main__":
    main()

Línea 77: Recorremos cada cuenta obtenida.

Línea 78: Obtenemos number y currency de los datos de la cuenta. También establecemos el rango de fechas de los movimientos que necesitamos.

[
    {
        "id": "5b5f170de40bfa249603fcbb576fc662",
        "reference": "ref 52",
        "date": "03/02/2022",
        "detail": "REDIVA 19210UTE095042195",
        "debit": "",
        "credit": 2577.43,
        "extra_data": None,
    },
    {
        "id": "fc25184d47c8628ab6b6c68799560a0c",
        "reference": "ref 53",
        "date": "03/02/2022",
        "detail": "DEPOSITO POR BUZONERA 00000000-S60BUZ638 TX:76625 10/7004048622 TRJ:**0000-7-590297",
        "debit": "",
        "credit": 12401.5,
        "extra_data": None,
    },
    {
        "id": "47b5963267ec8e66ecc8a8997bbf83ce",
        "reference": "ref 54",
        "date": "03/02/2022",
        "detail": "CRE. CAMBIOSOP....180240",
        "debit": "",
        "credit": 9666.1,
        "extra_data": None,
    },
]

3. Obtener los gastos del mes

Y para concluir con todos los objetivos planteados, implementaremos la funcionalidad de calcular todos los gastos del mes actual discriminado por cuenta.

Ahora vamos a jugar con los valores de los movimientos, en donde tendremos que filtrar y sumar aquellos movimientos que tengan un débito realizado.

import requests

from datetime import datetime
from typing import Dict, List

API_KEY = "OWXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
BASE_URL = "https://banking.sandbox.prometeoapi.com"


class PrometeoAuth:
    def login(self) -> Dict:
        url = f"{BASE_URL}/login/"
        data = {
            "provider": "test",
            "username": "12345",
            "password": "gfdsa"
        }
        headers = {
            "X-API-Key": API_KEY
        }
        response = requests.post(url, data=data, headers=headers)
        if response.ok:
            return response.json()

    def get_session_key(self) -> str:
        login_data: Dict = self.login()
        return login_data.get("key")

    def logout(self) -> bool:
        url = f"{BASE_URL}/logout/"
        params = {
            "key": self.session_key
        }
        headers = {
            "X-API-Key": API_KEY
        }
        response = requests.get(url, params=params, headers=headers)
        return response.ok


class PrometeoData:
    @classmethod
    def get_accounts(cls, session_key: str) -> List[Dict]:
        url = f"{BASE_URL}/account/"
        params = {
            "key": session_key
        }
        headers = {
            "X-API-Key": API_KEY
        }
        response = requests.get(url, params=params, headers=headers)
        if response.ok:
            return response.json().get("accounts", [])

    @classmethod
    def get_account_movements(cls, session_key:str, account_number: str, currency: str, date_start: datetime, date_end: datetime) -> List[Dict]:
        url = f"{BASE_URL}/account/{account_number}/movement/"
        params = {
            "accountNumber": account_number,
            "currency": currency,
            "date_start": date_start.strftime("%d/%m/%Y"),
            "date_end": date_end.strftime("%d/%m/%Y"),
            "key": session_key
        }
        headers = {
            "X-API-Key": API_KEY
        }
        response = requests.get(url, params=params, headers=headers)
        if response.ok:
            return response.json().get("movements", [])


def main():
    prometeo_auth = PrometeoAuth()
    session_key: str = prometeo_auth.get_session_key()
    accounts: List[Dict] = PrometeoData.get_accounts(session_key)
    start_date = datetime.today().replace(day=1)
    end_date = datetime.today()
    accounts_expenses = {}
    for account in accounts:
        account_number = account["number"]
        movements_data = PrometeoData.get_account_movements(
            session_key,
            account_number,
            account["currency"],
            start_date,
            end_date
        )
        for movement in movements_data:
            debit = movement.get("debit")
            if debit:
                accounts_expenses[account_number] = accounts_expenses.get(account_number, 0) + debit

    print(accounts_expenses)

    
if __name__== "__main__":
    main()

Línea 89: Recorremos cada movimiento para comprobar si en dicho registro hubo un débito, si lo hubo tenemos que ir sumando estos débitos, la suma de todos ellos nos dirá el total de gastos que tenemos discriminado por número de cuenta.

El resultado obtenido será algo similar al siguiente ejemplo:

{'12345678': 78228.49, '87654321': 78228.49}

Conclusión

En menos de 101 líneas nos conectamos a Prometeo, manejamos las sesiones, buscamos los movimientos de todas las cuentas y además calculamos los gastos del mes de cada cuenta.