Skip to content

Commit 20700a1

Browse files
gmorales96gabino
andauthored
Update/py3 13 deps (#148)
* Update dependencies and Python version support * Handle incomplete CEP responses and improve error handling * Update GitHub Actions workflows to latest versions * Update PyPI badge URL to point to cepmex project * Fix PyPI badge URL to point to correct project * Bump version to 1.0.0.dev1 * Release version 1.0.0 * Update Python version to 3.13 in Makefile * Refactor CEP client and transfer validation logic * Add Config class and update base URL handling * Add NotFoundError * Update Transferencia class to remove unnecessary validation checks * Bump version to 1.0.0.dev2 * Improve transfer validation error handling * Update README * Update README * Bump version to 1.0.0 * Update README formatting * Add CepNotAvailableError * Rename NotFoundError to TransferNotFoundError * Simplify fecha_abono parsing * Optimize response decoding in transfer validation * Refactor configuration and base URL handling * Update README * Update README example to use TransferNotFoundError * Change transfer amount handling to use cents as integer * Bumb version to 1.0.0.dev3 * Bumb version to 1.0.0 --------- Co-authored-by: gabino <gabino@cuenca.com>
1 parent 118f05e commit 20700a1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+3646
-2374
lines changed

.github/workflows/release.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,18 @@ jobs:
66
publish-pypi:
77
runs-on: ubuntu-latest
88
steps:
9-
- uses: actions/checkout@master
10-
- name: Set up Python 3.8
11-
uses: actions/setup-python@v4.1.0
9+
- uses: actions/checkout@v4
10+
- name: Set up Python 3.13
11+
uses: actions/setup-python@v5
1212
with:
13-
python-version: 3.8
13+
python-version: 3.13
1414
- name: Install dependencies
1515
run: pip install -qU setuptools wheel twine
1616
- name: Generating distribution archives
1717
run: python setup.py sdist bdist_wheel
1818
- name: Publish distribution 📦 to PyPI
1919
if: startsWith(github.event.ref, 'refs/tags')
20-
uses: pypa/gh-action-pypi-publish@master
20+
uses: pypa/gh-action-pypi-publish@release/v1
2121
with:
2222
user: __token__
2323
password: ${{ secrets.pypi_password }}

.github/workflows/test.yml

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ jobs:
66
lint:
77
runs-on: ubuntu-latest
88
steps:
9-
- uses: actions/checkout@v2
9+
- uses: actions/checkout@v4
1010
- name: Set up Python
11-
uses: actions/setup-python@v4.1.0
11+
uses: actions/setup-python@v5
1212
with:
13-
python-version: 3.8
13+
python-version: 3.13
1414
- name: Install dependencies
1515
run: make install-test
1616
- name: Lint
@@ -20,11 +20,11 @@ jobs:
2020
runs-on: ubuntu-latest
2121
strategy:
2222
matrix:
23-
python-version: [3.7, 3.8]
23+
python-version: ['3.10', '3.11', '3.12', '3.13']
2424
steps:
25-
- uses: actions/checkout@v2
25+
- uses: actions/checkout@v4
2626
- name: Set up Python ${{ matrix.python-version }}
27-
uses: actions/setup-python@v4.1.0
27+
uses: actions/setup-python@v5
2828
with:
2929
python-version: ${{ matrix.python-version }}
3030
- name: Install dependencies
@@ -35,18 +35,19 @@ jobs:
3535
coverage:
3636
runs-on: ubuntu-latest
3737
steps:
38-
- uses: actions/checkout@master
38+
- uses: actions/checkout@v4
3939
- name: Setup Python
40-
uses: actions/setup-python@v4.1.0
40+
uses: actions/setup-python@v5
4141
with:
42-
python-version: 3.8
42+
python-version: 3.13
4343
- name: Install dependencies
4444
run: make install-test
4545
- name: Generate coverage report
4646
run: pytest --cov-report=xml
4747
- name: Upload coverage to Codecov
48-
uses: codecov/codecov-action@v2.1.0
48+
uses: codecov/codecov-action@v5
4949
with:
50+
token: ${{ secrets.CODECOV_TOKEN }}
5051
file: ./coverage.xml
5152
flags: unittests
5253
name: codecov-umbrella

Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
SHELL := bash
22
PATH := ./venv/bin:${PATH}
3-
PYTHON=python3.7
3+
PYTHON=python3.13
44
PROJECT=cep
55
isort = isort $(PROJECT) tests setup.py
6-
black = black -S -l 79 --target-version py37 $(PROJECT) tests setup.py
6+
black = black -S -l 79 --target-version py313 $(PROJECT) tests setup.py
77

88
.PHONY: all
99
all: testt

README.md

Lines changed: 66 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,31 +2,84 @@
22

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

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

99

10-
## Instalación
10+
## Installation
1111

1212
```bash
1313
pip install cepmex
1414
```
1515

16-
### Uso
16+
## Development & Testing
17+
18+
You can use a staging environment to test the library:
1719

1820
```python
19-
from datetime import date
21+
import cep
22+
23+
cep.configure(beta=True)
24+
```
2025

26+
To run unit tests, use `pytest`.
27+
```bash
28+
pytest
29+
```
30+
31+
## Usage
32+
33+
```python
34+
from datetime import date
2135
from cep import Transferencia
36+
from cep.exc import TransferNotFoundError
37+
38+
try:
39+
tr = Transferencia.validar(
40+
fecha=date(2019, 4, 12),
41+
clave_rastreo='CUENCA1555093850',
42+
emisor='90646', # STP
43+
receptor='40012', # BBVA
44+
cuenta='012180004643051249',
45+
monto=817, # In cents
46+
)
47+
pdf = tr.descargar()
48+
with open('CUENCA1555093850.pdf', 'wb') as f:
49+
f.write(pdf)
50+
except TransferNotFoundError as e:
51+
print('No se encontro la transferencia')
52+
```
53+
54+
## Validate Transfer Parameters
55+
56+
Use the `validar` method to validate a transfer with the following parameters:
57+
58+
### Required Parameters:
59+
- `fecha` (`datetime.date`): Transfer date.
60+
- `clave_rastreo` (`str`): Transfer tracking key.
61+
- `emisor` (`str`): Transfer sender bank code.
62+
- `receptor` (`str`): Transfer receiver bank code.
63+
- `cuenta` (`str`): Transfer account number.
64+
- `monto` (`int`): Transfer amount **in cents**.
65+
66+
### Optional Parameters:
67+
- `pago_a_banco` (`bool`, default=`False`): Set to `True` for transfer types 4 and 31.
68+
69+
## Download Transfer Data
2270

23-
tr = Transferencia.validar(
24-
fecha=date(2019, 4, 12),
25-
clave_rastreo='CUENCA1555093850',
26-
emisor='90646', # STP
27-
receptor='40012', # BBVA
28-
cuenta='012180004643051249',
29-
monto=8.17,
30-
)
31-
pdf = tr.descargar()
71+
Use the `descargar` method to download a transfer in one of the following formats:
72+
- `PDF` (default)
73+
- `XML`
74+
- `ZIP`
75+
76+
```python
77+
tr.descargar(formato='XML')
3278
```
79+
80+
## Exceptions
81+
82+
- `TransferNotFoundError`: The transfer was not found.
83+
- `MaxRequestError`: The maximum number of requests has been reached.
84+
- `CepNotAvailableError`: The transfer was found, but the CEP is not available.
85+

cep/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
__all__ = ['__version__', 'Cuenta', 'Client', 'Transferencia']
1+
__all__ = ['__version__', 'Cuenta', 'Client', 'Transferencia', 'configure']
22

3-
from .client import Client
3+
from .client import Client, configure
44
from .cuenta import Cuenta
55
from .transferencia import Transferencia
66
from .version import __version__

cep/client.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,28 @@
1+
from typing import ClassVar
2+
13
import requests
24

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

10+
BASE_URL = 'https://www.banxico.org.mx/cep'
11+
BASE_URL_BETA = 'https://www.banxico.org.mx/cep-beta'
12+
13+
14+
def configure(beta=False):
15+
Client.base_url = BASE_URL_BETA if beta else BASE_URL
16+
817

918
class Client:
10-
base_url = 'http://www.banxico.org.mx/cep'
19+
base_url: ClassVar[str] = BASE_URL
1120

1221
def __init__(self):
1322
self.session = requests.Session()
1423
self.session.headers['User-Agent'] = USER_AGENT
1524
self.base_data = dict(
1625
tipoCriterio='T',
17-
receptorParticipante=0,
1826
captcha='c',
1927
tipoConsulta=1,
2028
)
@@ -29,7 +37,7 @@ def post(self, endpoint: str, data: dict, **kwargs) -> bytes:
2937
def request(
3038
self, method: str, endpoint: str, data: dict, **kwargs
3139
) -> bytes:
32-
url = self.base_url + endpoint
40+
url = Client.base_url + endpoint
3341
response = self.session.request(method, url, data=data, **kwargs)
3442
if not response.ok:
3543
response.raise_for_status()

cep/cuenta.py

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,23 @@
66
@dataclass
77
class Cuenta:
88
nombre: str
9-
tipo: str
9+
tipo_cuenta: str
1010
banco: str
1111
numero: str
1212
rfc: str
1313

1414
@classmethod
1515
def from_etree(cls, element: etree._Element):
16-
cuenta = cls(
17-
nombre=element.get('Nombre'),
18-
tipo=element.get('TipoCuenta'),
19-
banco=element.get('BancoEmisor') or element.get('BancoReceptor'),
20-
numero=element.get('Cuenta'),
21-
rfc=element.get('RFC'),
16+
banco = (
17+
element.attrib['BancoEmisor']
18+
if 'BancoEmisor' in element.attrib
19+
else element.attrib['BancoReceptor']
20+
)
21+
22+
return cls(
23+
nombre=element.attrib['Nombre'],
24+
tipo_cuenta=element.attrib['TipoCuenta'],
25+
banco=banco,
26+
numero=element.attrib['Cuenta'],
27+
rfc=element.attrib['RFC'],
2228
)
23-
return cuenta

cep/exc.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,22 @@ class CepError(Exception):
55
"""
66

77

8+
class TransferNotFoundError(CepError):
9+
"""
10+
No se encontró la transferencia con
11+
los datos proporcionados
12+
"""
13+
14+
815
class MaxRequestError(CepError):
916
"""
1017
Máximo número de peticiones alcanzadas para
1118
obtener el CEP de una transferencia
1219
"""
20+
21+
22+
class CepNotAvailableError(CepError):
23+
"""
24+
La transferencia fue encontrada, pero el CEP no
25+
está disponible.
26+
"""

0 commit comments

Comments
 (0)