Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
31b5cc9
Update dependencies and Python version support
Jan 30, 2025
6ceb003
Handle incomplete CEP responses and improve error handling
Jan 30, 2025
cb08a9f
Update GitHub Actions workflows to latest versions
Jan 30, 2025
8396bbf
Update PyPI badge URL to point to cepmex project
Jan 30, 2025
5d42bbc
Fix PyPI badge URL to point to correct project
Jan 30, 2025
f52e44e
Bump version to 1.0.0.dev1
Feb 7, 2025
cbf9c60
Release version 1.0.0
Feb 7, 2025
a21e39d
Update Python version to 3.13 in Makefile
Feb 7, 2025
f417ad5
Refactor CEP client and transfer validation logic
Feb 11, 2025
dc8e973
Add Config class and update base URL handling
Feb 13, 2025
dbd3ae0
Add NotFoundError
Feb 13, 2025
bd2f210
Update Transferencia class to remove unnecessary validation checks
Feb 13, 2025
a6a6cca
Bump version to 1.0.0.dev2
Feb 13, 2025
430cb6b
Improve transfer validation error handling
Feb 13, 2025
bfa17d3
Update README
Feb 13, 2025
ce92abc
Update README
Feb 13, 2025
d69d13c
Bump version to 1.0.0
Feb 13, 2025
4bb1e4b
Update README formatting
Feb 13, 2025
d60dbc4
Add CepNotAvailableError
Feb 14, 2025
9cb1a46
Rename NotFoundError to TransferNotFoundError
Feb 14, 2025
cd419d8
Simplify fecha_abono parsing
Feb 14, 2025
438799c
Optimize response decoding in transfer validation
Feb 14, 2025
08ad08e
Refactor configuration and base URL handling
Feb 14, 2025
9a67dd5
Update README
Feb 14, 2025
7be5f69
Update README example to use TransferNotFoundError
Feb 14, 2025
dc2f057
Change transfer amount handling to use cents as integer
Feb 18, 2025
9c7541d
Bumb version to 1.0.0.dev3
Feb 18, 2025
d62e4c7
Bumb version to 1.0.0
Feb 18, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,18 @@ jobs:
publish-pypi:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- name: Set up Python 3.8
uses: actions/setup-python@v4.1.0
- uses: actions/checkout@v4
- name: Set up Python 3.13
uses: actions/setup-python@v5
with:
python-version: 3.8
python-version: 3.13
- name: Install dependencies
run: pip install -qU setuptools wheel twine
- name: Generating distribution archives
run: python setup.py sdist bdist_wheel
- name: Publish distribution 📦 to PyPI
if: startsWith(github.event.ref, 'refs/tags')
uses: pypa/gh-action-pypi-publish@master
uses: pypa/gh-action-pypi-publish@release/v1
with:
user: __token__
password: ${{ secrets.pypi_password }}
21 changes: 11 additions & 10 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4.1.0
uses: actions/setup-python@v5
with:
python-version: 3.8
python-version: 3.13
- name: Install dependencies
run: make install-test
- name: Lint
Expand All @@ -20,11 +20,11 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.7, 3.8]
python-version: ['3.10', '3.11', '3.12', '3.13']
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4.1.0
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
Expand All @@ -35,18 +35,19 @@ jobs:
coverage:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v4.1.0
uses: actions/setup-python@v5
with:
python-version: 3.8
python-version: 3.13
- name: Install dependencies
run: make install-test
- name: Generate coverage report
run: pytest --cov-report=xml
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v2.1.0
uses: codecov/codecov-action@v5
with:
token: ${{ secrets.CODECOV_TOKEN }}
file: ./coverage.xml
flags: unittests
name: codecov-umbrella
Expand Down
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
SHELL := bash
PATH := ./venv/bin:${PATH}
PYTHON=python3.7
PYTHON=python3.13
PROJECT=cep
isort = isort $(PROJECT) tests setup.py
black = black -S -l 79 --target-version py37 $(PROJECT) tests setup.py
black = black -S -l 79 --target-version py313 $(PROJECT) tests setup.py

.PHONY: all
all: testt
Expand Down
79 changes: 66 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,84 @@

[![test](https://github.com/cuenca-mx/cep-python/workflows/test/badge.svg)](https://github.com/cuenca-mx/cep-python/actions?query=workflow%3Atest)
[![codecov](https://codecov.io/gh/cuenca-mx/cep-python/branch/master/graph/badge.svg)](https://codecov.io/gh/cuenca-mx/cep-python)
[![PyPI](https://img.shields.io/pypi/v/cuenca.svg)](https://pypi.org/project/cuenca/)
[![PyPI](https://img.shields.io/pypi/v/cepmex.svg)](https://pypi.org/project/cepmex/)

Python client library for CEP (http://www.banxico.org.mx/cep/)


## Instalación
## Installation

```bash
pip install cepmex
```

### Uso
## Development & Testing

You can use a staging environment to test the library:

```python
from datetime import date
import cep

cep.configure(beta=True)
```

To run unit tests, use `pytest`.
```bash
pytest
```

## Usage

```python
from datetime import date
from cep import Transferencia
from cep.exc import TransferNotFoundError

try:
tr = Transferencia.validar(
fecha=date(2019, 4, 12),
clave_rastreo='CUENCA1555093850',
emisor='90646', # STP
receptor='40012', # BBVA
cuenta='012180004643051249',
monto=817, # In cents
)
pdf = tr.descargar()
with open('CUENCA1555093850.pdf', 'wb') as f:
f.write(pdf)
except TransferNotFoundError as e:
print('No se encontro la transferencia')
```

## Validate Transfer Parameters

Use the `validar` method to validate a transfer with the following parameters:

### Required Parameters:
- `fecha` (`datetime.date`): Transfer date.
- `clave_rastreo` (`str`): Transfer tracking key.
- `emisor` (`str`): Transfer sender bank code.
- `receptor` (`str`): Transfer receiver bank code.
- `cuenta` (`str`): Transfer account number.
- `monto` (`int`): Transfer amount **in cents**.

### Optional Parameters:
- `pago_a_banco` (`bool`, default=`False`): Set to `True` for transfer types 4 and 31.

## Download Transfer Data

tr = Transferencia.validar(
fecha=date(2019, 4, 12),
clave_rastreo='CUENCA1555093850',
emisor='90646', # STP
receptor='40012', # BBVA
cuenta='012180004643051249',
monto=8.17,
)
pdf = tr.descargar()
Use the `descargar` method to download a transfer in one of the following formats:
- `PDF` (default)
- `XML`
- `ZIP`

```python
tr.descargar(formato='XML')
```

## Exceptions

- `TransferNotFoundError`: The transfer was not found.
- `MaxRequestError`: The maximum number of requests has been reached.
- `CepNotAvailableError`: The transfer was found, but the CEP is not available.

4 changes: 2 additions & 2 deletions cep/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
__all__ = ['__version__', 'Cuenta', 'Client', 'Transferencia']
__all__ = ['__version__', 'Cuenta', 'Client', 'Transferencia', 'configure']

from .client import Client
from .client import Client, configure
from .cuenta import Cuenta
from .transferencia import Transferencia
from .version import __version__
14 changes: 11 additions & 3 deletions cep/client.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,28 @@
from typing import ClassVar

import requests

USER_AGENT = (
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 '
'(KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36'
)

BASE_URL = 'https://www.banxico.org.mx/cep'
BASE_URL_BETA = 'https://www.banxico.org.mx/cep-beta'


def configure(beta=False):
Client.base_url = BASE_URL_BETA if beta else BASE_URL


class Client:
base_url = 'http://www.banxico.org.mx/cep'
base_url: ClassVar[str] = BASE_URL

def __init__(self):
self.session = requests.Session()
self.session.headers['User-Agent'] = USER_AGENT
self.base_data = dict(
tipoCriterio='T',
receptorParticipante=0,
captcha='c',
tipoConsulta=1,
)
Expand All @@ -29,7 +37,7 @@ def post(self, endpoint: str, data: dict, **kwargs) -> bytes:
def request(
self, method: str, endpoint: str, data: dict, **kwargs
) -> bytes:
url = self.base_url + endpoint
url = Client.base_url + endpoint
response = self.session.request(method, url, data=data, **kwargs)
if not response.ok:
response.raise_for_status()
Expand Down
21 changes: 13 additions & 8 deletions cep/cuenta.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,23 @@
@dataclass
class Cuenta:
nombre: str
tipo: str
tipo_cuenta: str
banco: str
numero: str
rfc: str

@classmethod
def from_etree(cls, element: etree._Element):
cuenta = cls(
nombre=element.get('Nombre'),
tipo=element.get('TipoCuenta'),
banco=element.get('BancoEmisor') or element.get('BancoReceptor'),
numero=element.get('Cuenta'),
rfc=element.get('RFC'),
banco = (
element.attrib['BancoEmisor']
if 'BancoEmisor' in element.attrib
else element.attrib['BancoReceptor']
)

return cls(
nombre=element.attrib['Nombre'],
tipo_cuenta=element.attrib['TipoCuenta'],
banco=banco,
numero=element.attrib['Cuenta'],
rfc=element.attrib['RFC'],
)
return cuenta
14 changes: 14 additions & 0 deletions cep/exc.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,22 @@ class CepError(Exception):
"""


class TransferNotFoundError(CepError):
"""
No se encontró la transferencia con
los datos proporcionados
"""


class MaxRequestError(CepError):
"""
Máximo número de peticiones alcanzadas para
obtener el CEP de una transferencia
"""


class CepNotAvailableError(CepError):
"""
La transferencia fue encontrada, pero el CEP no
está disponible.
"""
Loading
Loading