From 02458a1b73ba84ed97514ca3bd1055e99a56ceb5 Mon Sep 17 00:00:00 2001 From: gabino Date: Tue, 10 Dec 2024 17:24:26 -0600 Subject: [PATCH 01/27] ci: add Codecov token to workflow configuration --- .github/workflows/test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 6ff81db..293a6f1 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -51,4 +51,5 @@ jobs: flags: unittests name: codecov-umbrella fail_ci_if_error: true + token: ${{ secrets.CODECOV_TOKEN }} From fe79bec6500b6a6a8fbc7677660b77579f44724b Mon Sep 17 00:00:00 2001 From: gabino Date: Tue, 10 Dec 2024 18:00:15 -0600 Subject: [PATCH 02/27] feat: add error handling for existing bank codes and names --- clabe/errors.py | 10 ++++++++++ clabe/validations.py | 28 ++++++++++++++++++++++++++++ clabe/version.py | 2 +- 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/clabe/errors.py b/clabe/errors.py index 6ecd610..4a3a396 100644 --- a/clabe/errors.py +++ b/clabe/errors.py @@ -9,3 +9,13 @@ class BankCodeValidationError(PydanticValueError): class ClabeControlDigitValidationError(PydanticValueError): code = 'clabe.control_digit' msg_template = 'clabe d铆gito de control no es v谩lido' + + +class BankCodeAlreadyExistsError(PydanticValueError): + code = 'clabe.bank_code_already_exists' + msg_template = 'c贸digo de banco ya existe' + + +class BankNameAlreadyExistsError(PydanticValueError): + code = 'clabe.bank_name_already_exists' + msg_template = 'nombre de banco ya existe' diff --git a/clabe/validations.py b/clabe/validations.py index ef25b16..d2d4cfe 100644 --- a/clabe/validations.py +++ b/clabe/validations.py @@ -2,6 +2,7 @@ from typing import List, Union from .banks import BANK_NAMES, BANKS +from .errors import BankCodeAlreadyExistsError, BankNameAlreadyExistsError CLABE_LENGTH = 18 CLABE_WEIGHTS = [3, 7, 1, 3, 7, 1, 3, 7, 1, 3, 7, 1, 3, 7, 1, 3, 7] @@ -61,3 +62,30 @@ def generate_new_clabes(number_of_clabes: int, prefix: str) -> List[str]: assert validate_clabe(clabe) clabes.append(clabe) return clabes + + +def configure_additional_bank( + bank_code_abm: str, bank_code_banxico: str, bank_name: str +) -> None: + """ + Configures an additional bank. + + Args: + bank_code_abm (str): The ABM code for the bank. + bank_code_banxico (str): The Banxico code for the bank. + bank_name (str): The name of the bank. + + Raises: + ValueError: If the bank_code_abm or bank_code_banxico + already exists in the provided dictionaries. + """ + + if bank_code_abm in BANKS: + raise BankCodeAlreadyExistsError + + if bank_code_banxico in BANK_NAMES: + raise BankNameAlreadyExistsError + + BANKS.update({bank_code_abm: bank_code_banxico}) + + BANK_NAMES.update({bank_code_banxico: bank_name}) diff --git a/clabe/version.py b/clabe/version.py index dee93a9..7f46aab 100644 --- a/clabe/version.py +++ b/clabe/version.py @@ -1 +1 @@ -__version__ = '1.2.16' +__version__ = '1.2.17.dev0' From 7ae5528103372e33e935907fb4440eee951ec039 Mon Sep 17 00:00:00 2001 From: gabino Date: Wed, 11 Dec 2024 09:08:18 -0600 Subject: [PATCH 03/27] ci: update GitHub Actions workflow to use new action versions --- .github/workflows/release.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0cda24d..84c7eba 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -6,9 +6,9 @@ jobs: publish-pypi: runs-on: ubuntu-latest steps: - - uses: actions/checkout@master + - uses: actions/checkout@v4 - name: Set up Python 3.8 - uses: actions/setup-python@v2.2.1 + uses: actions/setup-python@v4 with: python-version: 3.8 - name: Install dependencies From e2e4cb987eb27daf4e6d914376e702ad7b59b55f Mon Sep 17 00:00:00 2001 From: gabino Date: Wed, 11 Dec 2024 09:19:43 -0600 Subject: [PATCH 04/27] chore: bump version to 1.2.17.dev1 --- clabe/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clabe/version.py b/clabe/version.py index 7f46aab..3416a74 100644 --- a/clabe/version.py +++ b/clabe/version.py @@ -1 +1 @@ -__version__ = '1.2.17.dev0' +__version__ = '1.2.17.dev1' From 2a4566e30a3c4e22acc09a3ab0d325cafc86c53f Mon Sep 17 00:00:00 2001 From: gabino Date: Wed, 11 Dec 2024 11:49:29 -0600 Subject: [PATCH 05/27] chore: update GitHub Actions workflows for release and testing --- .github/workflows/release.yml | 6 +++--- .github/workflows/test.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0cda24d..e722ac1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -6,9 +6,9 @@ jobs: publish-pypi: runs-on: ubuntu-latest steps: - - uses: actions/checkout@master + - uses: actions/checkout@v4 - name: Set up Python 3.8 - uses: actions/setup-python@v2.2.1 + uses: actions/setup-python@v4 with: python-version: 3.8 - name: Install dependencies @@ -17,7 +17,7 @@ jobs: 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 }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 6ff81db..27058df 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -51,4 +51,4 @@ jobs: flags: unittests name: codecov-umbrella fail_ci_if_error: true - + token: ${{ secrets.CODECOV_TOKEN }} \ No newline at end of file From b356cd1b6b06e4ec2ced9cdd7eb71e386d4f2e94 Mon Sep 17 00:00:00 2001 From: gabino Date: Wed, 11 Dec 2024 12:39:28 -0600 Subject: [PATCH 06/27] fix: update PyPI token reference in GitHub Actions workflow --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e722ac1..1e04214 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -20,4 +20,4 @@ jobs: uses: pypa/gh-action-pypi-publish@release/v1 with: user: __token__ - password: ${{ secrets.pypi_password }} + password: ${{ secrets.PYPI_TOKEN }} From 982d1317b1e24700aac4b1155a60b1e9ee34f672 Mon Sep 17 00:00:00 2001 From: gabino Date: Wed, 11 Dec 2024 12:44:33 -0600 Subject: [PATCH 07/27] fix: update PyPI token reference in release workflow to use PYPI_API_TOKEN --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1e04214..04cc895 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -20,4 +20,4 @@ jobs: uses: pypa/gh-action-pypi-publish@release/v1 with: user: __token__ - password: ${{ secrets.PYPI_TOKEN }} + password: ${{ secrets.PYPI_API_TOKEN }} From cf757b3266910b00e7df2e77dbed90395e58ec3d Mon Sep 17 00:00:00 2001 From: gabino Date: Fri, 13 Dec 2024 11:38:34 -0600 Subject: [PATCH 08/27] refactor: rename and update error classes for bank code validation --- clabe/errors.py | 12 ++++++------ clabe/validations.py | 9 ++++++--- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/clabe/errors.py b/clabe/errors.py index 4a3a396..02b0c83 100644 --- a/clabe/errors.py +++ b/clabe/errors.py @@ -11,11 +11,11 @@ class ClabeControlDigitValidationError(PydanticValueError): msg_template = 'clabe d铆gito de control no es v谩lido' -class BankCodeAlreadyExistsError(PydanticValueError): - code = 'clabe.bank_code_already_exists' - msg_template = 'c贸digo de banco ya existe' +class BankCodeABMAlreadyExistsError(PydanticValueError): + code = 'clabe.bank_code_abm_already_exists' + msg_template = 'c贸digo de banco ABM ya existe' -class BankNameAlreadyExistsError(PydanticValueError): - code = 'clabe.bank_name_already_exists' - msg_template = 'nombre de banco ya existe' +class BankCodeBanxicoAlreadyExistsError(PydanticValueError): + code = 'clabe.bank_code_banxico_already_exists' + msg_template = 'c贸digo de banco banxico ya existe' diff --git a/clabe/validations.py b/clabe/validations.py index d2d4cfe..54915ab 100644 --- a/clabe/validations.py +++ b/clabe/validations.py @@ -2,7 +2,10 @@ from typing import List, Union from .banks import BANK_NAMES, BANKS -from .errors import BankCodeAlreadyExistsError, BankNameAlreadyExistsError +from .errors import ( + BankCodeABMAlreadyExistsError, + BankCodeBanxicoAlreadyExistsError, +) CLABE_LENGTH = 18 CLABE_WEIGHTS = [3, 7, 1, 3, 7, 1, 3, 7, 1, 3, 7, 1, 3, 7, 1, 3, 7] @@ -81,10 +84,10 @@ def configure_additional_bank( """ if bank_code_abm in BANKS: - raise BankCodeAlreadyExistsError + raise BankCodeABMAlreadyExistsError if bank_code_banxico in BANK_NAMES: - raise BankNameAlreadyExistsError + raise BankCodeBanxicoAlreadyExistsError BANKS.update({bank_code_abm: bank_code_banxico}) From 04b96f105052cebea3dc2f208dcdb02e8cbd8348 Mon Sep 17 00:00:00 2001 From: gabino Date: Fri, 13 Dec 2024 11:51:32 -0600 Subject: [PATCH 09/27] feat: add configure_additional_bank function and corresponding tests --- clabe/__init__.py | 2 ++ tests/test_clabe.py | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/clabe/__init__.py b/clabe/__init__.py index c3bd33c..23a453a 100644 --- a/clabe/__init__.py +++ b/clabe/__init__.py @@ -7,12 +7,14 @@ 'generate_new_clabes', 'get_bank_name', 'validate_clabe', + 'configure_additional_bank', ] from .banks import BANK_NAMES, BANKS from .types import Clabe from .validations import ( compute_control_digit, + configure_additional_bank, generate_new_clabes, get_bank_name, validate_clabe, diff --git a/tests/test_clabe.py b/tests/test_clabe.py index 3fb9b2e..16f2650 100644 --- a/tests/test_clabe.py +++ b/tests/test_clabe.py @@ -2,10 +2,15 @@ from clabe import ( compute_control_digit, + configure_additional_bank, generate_new_clabes, get_bank_name, validate_clabe, ) +from clabe.errors import ( + BankCodeABMAlreadyExistsError, + BankCodeBanxicoAlreadyExistsError, +) VALID_CLABE = '002000000000000008' INVALID_CLABE_CONTROL_DIGIT = '002000000000000007' @@ -36,3 +41,18 @@ def test_generate_new_clabes(): for clabe in clabes: assert clabe.startswith(prefix) assert validate_clabe(clabe) + + +def test_configure_additional_bank_success(): + configure_additional_bank("777", "713", "New Bank") + assert get_bank_name('777') == 'New Bank' + + +def test_configure_additional_bank_existing_abm_code(): + with pytest.raises(BankCodeABMAlreadyExistsError): + configure_additional_bank("002", "40002", "Banamex") + + +def test_configure_additional_bank_existing_banxico_code(): + with pytest.raises(BankCodeBanxicoAlreadyExistsError): + configure_additional_bank("666", "40137", "New Bank") From b3fc82375ca03e0fc82a5040b91acae1d4cae6e0 Mon Sep 17 00:00:00 2001 From: gabino Date: Mon, 16 Dec 2024 09:56:15 -0600 Subject: [PATCH 10/27] docs: update README to include instructions for add a new bank --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index 78f1051..d67c628 100644 --- a/README.md +++ b/README.md @@ -57,3 +57,10 @@ Para generar nuevo v谩lido CLABES import clabe clabe.generate_new_clabes(10, '002123456') ``` + +Para generar un nuevo banco + +```python +import clabe +clabe.configure_additional_bank('777', '713', 'New Bank') +``` From 17056cdeb7cf03afd5b7c28ad15fb4fb3cda73cf Mon Sep 17 00:00:00 2001 From: gabino Date: Mon, 16 Dec 2024 10:02:23 -0600 Subject: [PATCH 11/27] chore: bump version to 1.2.17.dev2 --- clabe/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clabe/version.py b/clabe/version.py index 3416a74..d27d6a9 100644 --- a/clabe/version.py +++ b/clabe/version.py @@ -1 +1 @@ -__version__ = '1.2.17.dev1' +__version__ = '1.2.17.dev2' From 63aa59d2c45a277c791c69548d233f1a534976f6 Mon Sep 17 00:00:00 2001 From: gabino Date: Mon, 16 Dec 2024 11:03:30 -0600 Subject: [PATCH 12/27] chore: bump version to 1.2.17 --- clabe/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clabe/version.py b/clabe/version.py index d27d6a9..d2309e3 100644 --- a/clabe/version.py +++ b/clabe/version.py @@ -1 +1 @@ -__version__ = '1.2.17.dev2' +__version__ = '1.2.17' From 8c0a10553adb64185602be807fc763630b6f5d09 Mon Sep 17 00:00:00 2001 From: gabino Date: Wed, 11 Dec 2024 11:49:29 -0600 Subject: [PATCH 13/27] chore: update GitHub Actions workflows for release and testing --- .github/workflows/release.yml | 2 +- .github/workflows/test.yml | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 84c7eba..e722ac1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -17,7 +17,7 @@ jobs: 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 }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 293a6f1..27058df 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -51,5 +51,4 @@ jobs: flags: unittests name: codecov-umbrella fail_ci_if_error: true - token: ${{ secrets.CODECOV_TOKEN }} - + token: ${{ secrets.CODECOV_TOKEN }} \ No newline at end of file From e7d7e47618142c739dd77fd8b1ac1b7f9672cdfe Mon Sep 17 00:00:00 2001 From: gabino Date: Wed, 11 Dec 2024 12:39:28 -0600 Subject: [PATCH 14/27] fix: update PyPI token reference in GitHub Actions workflow --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e722ac1..1e04214 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -20,4 +20,4 @@ jobs: uses: pypa/gh-action-pypi-publish@release/v1 with: user: __token__ - password: ${{ secrets.pypi_password }} + password: ${{ secrets.PYPI_TOKEN }} From 224adf23e8fd8cfcaa0a36326149aeb5c4b71716 Mon Sep 17 00:00:00 2001 From: gabino Date: Wed, 11 Dec 2024 12:44:33 -0600 Subject: [PATCH 15/27] fix: update PyPI token reference in release workflow to use PYPI_API_TOKEN --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1e04214..04cc895 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -20,4 +20,4 @@ jobs: uses: pypa/gh-action-pypi-publish@release/v1 with: user: __token__ - password: ${{ secrets.PYPI_TOKEN }} + password: ${{ secrets.PYPI_API_TOKEN }} From 7c035932914174f36cd897418b3a4ca1c6b7d622 Mon Sep 17 00:00:00 2001 From: gabino Date: Fri, 13 Dec 2024 11:38:34 -0600 Subject: [PATCH 16/27] refactor: rename and update error classes for bank code validation --- clabe/errors.py | 12 ++++++------ clabe/validations.py | 9 ++++++--- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/clabe/errors.py b/clabe/errors.py index 4a3a396..02b0c83 100644 --- a/clabe/errors.py +++ b/clabe/errors.py @@ -11,11 +11,11 @@ class ClabeControlDigitValidationError(PydanticValueError): msg_template = 'clabe d铆gito de control no es v谩lido' -class BankCodeAlreadyExistsError(PydanticValueError): - code = 'clabe.bank_code_already_exists' - msg_template = 'c贸digo de banco ya existe' +class BankCodeABMAlreadyExistsError(PydanticValueError): + code = 'clabe.bank_code_abm_already_exists' + msg_template = 'c贸digo de banco ABM ya existe' -class BankNameAlreadyExistsError(PydanticValueError): - code = 'clabe.bank_name_already_exists' - msg_template = 'nombre de banco ya existe' +class BankCodeBanxicoAlreadyExistsError(PydanticValueError): + code = 'clabe.bank_code_banxico_already_exists' + msg_template = 'c贸digo de banco banxico ya existe' diff --git a/clabe/validations.py b/clabe/validations.py index d2d4cfe..54915ab 100644 --- a/clabe/validations.py +++ b/clabe/validations.py @@ -2,7 +2,10 @@ from typing import List, Union from .banks import BANK_NAMES, BANKS -from .errors import BankCodeAlreadyExistsError, BankNameAlreadyExistsError +from .errors import ( + BankCodeABMAlreadyExistsError, + BankCodeBanxicoAlreadyExistsError, +) CLABE_LENGTH = 18 CLABE_WEIGHTS = [3, 7, 1, 3, 7, 1, 3, 7, 1, 3, 7, 1, 3, 7, 1, 3, 7] @@ -81,10 +84,10 @@ def configure_additional_bank( """ if bank_code_abm in BANKS: - raise BankCodeAlreadyExistsError + raise BankCodeABMAlreadyExistsError if bank_code_banxico in BANK_NAMES: - raise BankNameAlreadyExistsError + raise BankCodeBanxicoAlreadyExistsError BANKS.update({bank_code_abm: bank_code_banxico}) From eeeaa7d956c675d8fdb0b5aaf9b6f8d590297f1d Mon Sep 17 00:00:00 2001 From: gabino Date: Fri, 13 Dec 2024 11:51:32 -0600 Subject: [PATCH 17/27] feat: add configure_additional_bank function and corresponding tests --- clabe/__init__.py | 2 ++ tests/test_clabe.py | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/clabe/__init__.py b/clabe/__init__.py index c3bd33c..23a453a 100644 --- a/clabe/__init__.py +++ b/clabe/__init__.py @@ -7,12 +7,14 @@ 'generate_new_clabes', 'get_bank_name', 'validate_clabe', + 'configure_additional_bank', ] from .banks import BANK_NAMES, BANKS from .types import Clabe from .validations import ( compute_control_digit, + configure_additional_bank, generate_new_clabes, get_bank_name, validate_clabe, diff --git a/tests/test_clabe.py b/tests/test_clabe.py index 3fb9b2e..16f2650 100644 --- a/tests/test_clabe.py +++ b/tests/test_clabe.py @@ -2,10 +2,15 @@ from clabe import ( compute_control_digit, + configure_additional_bank, generate_new_clabes, get_bank_name, validate_clabe, ) +from clabe.errors import ( + BankCodeABMAlreadyExistsError, + BankCodeBanxicoAlreadyExistsError, +) VALID_CLABE = '002000000000000008' INVALID_CLABE_CONTROL_DIGIT = '002000000000000007' @@ -36,3 +41,18 @@ def test_generate_new_clabes(): for clabe in clabes: assert clabe.startswith(prefix) assert validate_clabe(clabe) + + +def test_configure_additional_bank_success(): + configure_additional_bank("777", "713", "New Bank") + assert get_bank_name('777') == 'New Bank' + + +def test_configure_additional_bank_existing_abm_code(): + with pytest.raises(BankCodeABMAlreadyExistsError): + configure_additional_bank("002", "40002", "Banamex") + + +def test_configure_additional_bank_existing_banxico_code(): + with pytest.raises(BankCodeBanxicoAlreadyExistsError): + configure_additional_bank("666", "40137", "New Bank") From bab2612521009a73eab13680ac00f5266c216ce1 Mon Sep 17 00:00:00 2001 From: gabino Date: Mon, 16 Dec 2024 09:56:15 -0600 Subject: [PATCH 18/27] docs: update README to include instructions for add a new bank --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index 78f1051..d67c628 100644 --- a/README.md +++ b/README.md @@ -57,3 +57,10 @@ Para generar nuevo v谩lido CLABES import clabe clabe.generate_new_clabes(10, '002123456') ``` + +Para generar un nuevo banco + +```python +import clabe +clabe.configure_additional_bank('777', '713', 'New Bank') +``` From 4bb61cf4c838b0b7e6ea8c0626227005c9465379 Mon Sep 17 00:00:00 2001 From: gabino Date: Mon, 16 Dec 2024 10:02:23 -0600 Subject: [PATCH 19/27] chore: bump version to 1.2.17.dev2 --- clabe/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clabe/version.py b/clabe/version.py index 3416a74..d27d6a9 100644 --- a/clabe/version.py +++ b/clabe/version.py @@ -1 +1 @@ -__version__ = '1.2.17.dev1' +__version__ = '1.2.17.dev2' From 247f3b493a45927a40757c5643746a5cd46d60bf Mon Sep 17 00:00:00 2001 From: gabino Date: Mon, 16 Dec 2024 11:03:30 -0600 Subject: [PATCH 20/27] chore: bump version to 1.2.17 --- clabe/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clabe/version.py b/clabe/version.py index d27d6a9..d2309e3 100644 --- a/clabe/version.py +++ b/clabe/version.py @@ -1 +1 @@ -__version__ = '1.2.17.dev2' +__version__ = '1.2.17' From 51856eddec88cb5864bc2d90573d99521ecd1a0f Mon Sep 17 00:00:00 2001 From: gabino Date: Tue, 17 Dec 2024 12:15:42 -0600 Subject: [PATCH 21/27] feat: enhance configure_additional_bank with input validation --- clabe/validations.py | 22 +++++++++++++++++++--- tests/test_clabe.py | 13 +++++++++++++ 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/clabe/validations.py b/clabe/validations.py index 54915ab..e9de0f8 100644 --- a/clabe/validations.py +++ b/clabe/validations.py @@ -1,6 +1,8 @@ import random from typing import List, Union +from pydantic.errors import NotDigitError + from .banks import BANK_NAMES, BANKS from .errors import ( BankCodeABMAlreadyExistsError, @@ -83,12 +85,26 @@ def configure_additional_bank( already exists in the provided dictionaries. """ + if not all( + isinstance(x, str) + for x in [bank_code_abm, bank_code_banxico, bank_name] + ): + raise TypeError("All parameters must be strings") + + if not bank_code_abm.isdigit(): + raise NotDigitError + + if not bank_code_banxico.isdigit(): + raise NotDigitError + + if not bank_name.strip(): + raise ValueError("bank_name cannot be empty") + if bank_code_abm in BANKS: raise BankCodeABMAlreadyExistsError if bank_code_banxico in BANK_NAMES: raise BankCodeBanxicoAlreadyExistsError - BANKS.update({bank_code_abm: bank_code_banxico}) - - BANK_NAMES.update({bank_code_banxico: bank_name}) + BANKS[bank_code_abm] = bank_code_banxico + BANK_NAMES[bank_code_banxico] = bank_name.strip() diff --git a/tests/test_clabe.py b/tests/test_clabe.py index 16f2650..a476d45 100644 --- a/tests/test_clabe.py +++ b/tests/test_clabe.py @@ -56,3 +56,16 @@ def test_configure_additional_bank_existing_abm_code(): def test_configure_additional_bank_existing_banxico_code(): with pytest.raises(BankCodeBanxicoAlreadyExistsError): configure_additional_bank("666", "40137", "New Bank") + + +def test_configure_additional_bank_invalid_inputs(): + with pytest.raises(TypeError): + configure_additional_bank(3, 3, 3) + with pytest.raises(ValueError): + configure_additional_bank("A", "B", "C") + with pytest.raises(ValueError): + configure_additional_bank("666", "B", "C") + with pytest.raises(ValueError): + configure_additional_bank("777", "713", "") + with pytest.raises(ValueError): + configure_additional_bank("abc", "def", "Test Bank") From e4c5146d2952c8c0a0d2f1f86d1546808f4dd072 Mon Sep 17 00:00:00 2001 From: gabino Date: Wed, 18 Dec 2024 11:58:48 -0600 Subject: [PATCH 22/27] refactor: streamline bank configuration by replacing error classes with Pydantic model validation --- clabe/errors.py | 10 ------- clabe/validations.py | 66 ++++++++++++++++++-------------------------- tests/test_clabe.py | 55 +++++++++++++++++------------------- 3 files changed, 53 insertions(+), 78 deletions(-) diff --git a/clabe/errors.py b/clabe/errors.py index 02b0c83..6ecd610 100644 --- a/clabe/errors.py +++ b/clabe/errors.py @@ -9,13 +9,3 @@ class BankCodeValidationError(PydanticValueError): class ClabeControlDigitValidationError(PydanticValueError): code = 'clabe.control_digit' msg_template = 'clabe d铆gito de control no es v谩lido' - - -class BankCodeABMAlreadyExistsError(PydanticValueError): - code = 'clabe.bank_code_abm_already_exists' - msg_template = 'c贸digo de banco ABM ya existe' - - -class BankCodeBanxicoAlreadyExistsError(PydanticValueError): - code = 'clabe.bank_code_banxico_already_exists' - msg_template = 'c贸digo de banco banxico ya existe' diff --git a/clabe/validations.py b/clabe/validations.py index e9de0f8..2c007fd 100644 --- a/clabe/validations.py +++ b/clabe/validations.py @@ -1,13 +1,10 @@ import random from typing import List, Union +from pydantic import BaseModel, Field, validator from pydantic.errors import NotDigitError from .banks import BANK_NAMES, BANKS -from .errors import ( - BankCodeABMAlreadyExistsError, - BankCodeBanxicoAlreadyExistsError, -) CLABE_LENGTH = 18 CLABE_WEIGHTS = [3, 7, 1, 3, 7, 1, 3, 7, 1, 3, 7, 1, 3, 7, 1, 3, 7] @@ -69,42 +66,33 @@ def generate_new_clabes(number_of_clabes: int, prefix: str) -> List[str]: return clabes -def configure_additional_bank( - bank_code_abm: str, bank_code_banxico: str, bank_name: str -) -> None: - """ - Configures an additional bank. - - Args: - bank_code_abm (str): The ABM code for the bank. - bank_code_banxico (str): The Banxico code for the bank. - bank_name (str): The name of the bank. - - Raises: - ValueError: If the bank_code_abm or bank_code_banxico - already exists in the provided dictionaries. - """ - - if not all( - isinstance(x, str) - for x in [bank_code_abm, bank_code_banxico, bank_name] - ): - raise TypeError("All parameters must be strings") - - if not bank_code_abm.isdigit(): - raise NotDigitError - - if not bank_code_banxico.isdigit(): - raise NotDigitError +class BankConfigRequest(BaseModel): + bank_code_abm: str = Field(..., description="The ABM code for the bank") + bank_code_banxico: str = Field( + ..., description="The Banxico code for the bank" + ) + bank_name: str = Field(..., description="The name of the bank") - if not bank_name.strip(): - raise ValueError("bank_name cannot be empty") + @validator('bank_code_abm', 'bank_code_banxico') + def validate_numeric_codes(cls, v: str) -> str: + if not v.isdigit(): + raise NotDigitError + return v - if bank_code_abm in BANKS: - raise BankCodeABMAlreadyExistsError + @validator('bank_name') + def validate_bank_name(cls, v: str) -> str: + if not v.strip(): + raise ValueError("bank_name cannot be empty") + return v.strip() - if bank_code_banxico in BANK_NAMES: - raise BankCodeBanxicoAlreadyExistsError - BANKS[bank_code_abm] = bank_code_banxico - BANK_NAMES[bank_code_banxico] = bank_name.strip() +def configure_additional_bank( + bank_code_abm: str, bank_code_banxico: str, bank_name: str +) -> None: + request = BankConfigRequest( + bank_code_abm=bank_code_abm, + bank_code_banxico=bank_code_banxico, + bank_name=bank_name, + ) + BANKS[request.bank_code_abm] = request.bank_code_banxico + BANK_NAMES[request.bank_code_banxico] = request.bank_name diff --git a/tests/test_clabe.py b/tests/test_clabe.py index a476d45..be38647 100644 --- a/tests/test_clabe.py +++ b/tests/test_clabe.py @@ -7,10 +7,6 @@ get_bank_name, validate_clabe, ) -from clabe.errors import ( - BankCodeABMAlreadyExistsError, - BankCodeBanxicoAlreadyExistsError, -) VALID_CLABE = '002000000000000008' INVALID_CLABE_CONTROL_DIGIT = '002000000000000007' @@ -43,29 +39,30 @@ def test_generate_new_clabes(): assert validate_clabe(clabe) -def test_configure_additional_bank_success(): - configure_additional_bank("777", "713", "New Bank") - assert get_bank_name('777') == 'New Bank' - - -def test_configure_additional_bank_existing_abm_code(): - with pytest.raises(BankCodeABMAlreadyExistsError): - configure_additional_bank("002", "40002", "Banamex") - - -def test_configure_additional_bank_existing_banxico_code(): - with pytest.raises(BankCodeBanxicoAlreadyExistsError): - configure_additional_bank("666", "40137", "New Bank") - - -def test_configure_additional_bank_invalid_inputs(): - with pytest.raises(TypeError): - configure_additional_bank(3, 3, 3) - with pytest.raises(ValueError): - configure_additional_bank("A", "B", "C") - with pytest.raises(ValueError): - configure_additional_bank("666", "B", "C") - with pytest.raises(ValueError): - configure_additional_bank("777", "713", "") +@pytest.mark.parametrize( + 'abm_code, banxico_code, name', + [ + ('713', '90713', 'Cuenca DMZ'), + ('777', '713', 'Cuenca Gem DMZ'), + ('666', '723', 'Cuenca Gem Beta'), + ], +) +def test_configure_additional_bank_success(abm_code, banxico_code, name): + configure_additional_bank(abm_code, banxico_code, name) + assert get_bank_name(abm_code) == name + + +@pytest.mark.parametrize( + 'abm_code, banxico_code, name', + [ + ('A', 'B', 'C'), # Invalid format for both codes + ('666', 'B', 'Test Bank'), # Valid ABM code, invalid Banxico code + ('777', '713', ''), # Valid codes, empty name + ('abc', 'def', 'Test Bank'), # Non-numeric codes + ], +) +def test_configure_additional_bank_invalid_inputs( + abm_code, banxico_code, name +): with pytest.raises(ValueError): - configure_additional_bank("abc", "def", "Test Bank") + configure_additional_bank(abm_code, banxico_code, name) From 4eb15b9b8b5d0b6de5e0c3e6023b1aef7395048e Mon Sep 17 00:00:00 2001 From: gabino Date: Mon, 23 Dec 2024 15:59:02 -0600 Subject: [PATCH 23/27] refactor: update BankConfigRequest model and validation logic for bank codes - Replaced bank_code_abm with a derived property from bank_code_banxico. - Enhanced validation for bank_code_banxico to ensure it is exactly 5 digits. - Updated tests to reflect changes in bank configuration logic and validation rules. --- clabe/validations.py | 38 ++++++++++++++++++++------------------ tests/test_clabe.py | 22 ++++++++++------------ 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/clabe/validations.py b/clabe/validations.py index 2c007fd..ce5d228 100644 --- a/clabe/validations.py +++ b/clabe/validations.py @@ -1,8 +1,8 @@ import random +import re from typing import List, Union from pydantic import BaseModel, Field, validator -from pydantic.errors import NotDigitError from .banks import BANK_NAMES, BANKS @@ -67,30 +67,32 @@ def generate_new_clabes(number_of_clabes: int, prefix: str) -> List[str]: class BankConfigRequest(BaseModel): - bank_code_abm: str = Field(..., description="The ABM code for the bank") + bank_name: str = Field( + min_length=1, + strip_whitespace=True, + description="The name of the bank - cannot be empty", + ) + bank_code_banxico: str = Field( - ..., description="The Banxico code for the bank" + min_length=5, max_length=5, description="The Banxico code for the bank" ) - bank_name: str = Field(..., description="The name of the bank") - @validator('bank_code_abm', 'bank_code_banxico') - def validate_numeric_codes(cls, v: str) -> str: - if not v.isdigit(): - raise NotDigitError - return v + @validator("bank_code_banxico") + def validate_bank_code(cls, value): + if not re.fullmatch(r"\d{5}", value): + raise ValueError( + "bank_code_banxico must be a string of exactly 5 digits" + ) + return value + + @property + def bank_code_abm(self): + return self.bank_code_banxico[-3:] - @validator('bank_name') - def validate_bank_name(cls, v: str) -> str: - if not v.strip(): - raise ValueError("bank_name cannot be empty") - return v.strip() +def configure_additional_bank(bank_code_banxico: str, bank_name: str) -> None: -def configure_additional_bank( - bank_code_abm: str, bank_code_banxico: str, bank_name: str -) -> None: request = BankConfigRequest( - bank_code_abm=bank_code_abm, bank_code_banxico=bank_code_banxico, bank_name=bank_name, ) diff --git a/tests/test_clabe.py b/tests/test_clabe.py index be38647..c0f0491 100644 --- a/tests/test_clabe.py +++ b/tests/test_clabe.py @@ -43,26 +43,24 @@ def test_generate_new_clabes(): 'abm_code, banxico_code, name', [ ('713', '90713', 'Cuenca DMZ'), - ('777', '713', 'Cuenca Gem DMZ'), - ('666', '723', 'Cuenca Gem Beta'), + ('714', '90714', 'Cuenca Gem DMZ'), + ('715', '90715', 'Cuenca Gem Beta'), ], ) def test_configure_additional_bank_success(abm_code, banxico_code, name): - configure_additional_bank(abm_code, banxico_code, name) + configure_additional_bank(banxico_code, name) assert get_bank_name(abm_code) == name @pytest.mark.parametrize( - 'abm_code, banxico_code, name', + 'banxico_code, name', [ - ('A', 'B', 'C'), # Invalid format for both codes - ('666', 'B', 'Test Bank'), # Valid ABM code, invalid Banxico code - ('777', '713', ''), # Valid codes, empty name - ('abc', 'def', 'Test Bank'), # Non-numeric codes + ('1234', 'Test Bank'), # invalid Banxico code 4 digits + ('123456', 'Test Bank'), # invalid Banxico code 6 digits + ('12345', ''), # Valid code, empty name + ('123AT', 'Test Bank'), # Non-numeric codes ], ) -def test_configure_additional_bank_invalid_inputs( - abm_code, banxico_code, name -): +def test_configure_additional_bank_invalid_inputs(banxico_code, name): with pytest.raises(ValueError): - configure_additional_bank(abm_code, banxico_code, name) + configure_additional_bank(banxico_code, name) From d84ee8a66e36763be1dea16072ce95798bd1d2bd Mon Sep 17 00:00:00 2001 From: gabino Date: Mon, 23 Dec 2024 16:21:21 -0600 Subject: [PATCH 24/27] feat: add remove_bank function to manage bank entries --- clabe/__init__.py | 2 ++ clabe/validations.py | 15 +++++++++++++++ tests/test_clabe.py | 7 +++++++ 3 files changed, 24 insertions(+) diff --git a/clabe/__init__.py b/clabe/__init__.py index 23a453a..0905da0 100644 --- a/clabe/__init__.py +++ b/clabe/__init__.py @@ -8,6 +8,7 @@ 'get_bank_name', 'validate_clabe', 'configure_additional_bank', + 'remove_bank', ] from .banks import BANK_NAMES, BANKS @@ -17,6 +18,7 @@ configure_additional_bank, generate_new_clabes, get_bank_name, + remove_bank, validate_clabe, ) from .version import __version__ diff --git a/clabe/validations.py b/clabe/validations.py index ce5d228..9677567 100644 --- a/clabe/validations.py +++ b/clabe/validations.py @@ -98,3 +98,18 @@ def configure_additional_bank(bank_code_banxico: str, bank_name: str) -> None: ) BANKS[request.bank_code_abm] = request.bank_code_banxico BANK_NAMES[request.bank_code_banxico] = request.bank_name + + +def remove_bank(bank_code_banxico: str) -> None: + bank_code_abm = next( + ( + abm + for abm, banxico in BANKS.items() + if banxico == bank_code_banxico + ), + None, + ) + + if bank_code_abm: + BANKS.pop(bank_code_abm) + BANK_NAMES.pop(bank_code_banxico) diff --git a/tests/test_clabe.py b/tests/test_clabe.py index c0f0491..0e8cd22 100644 --- a/tests/test_clabe.py +++ b/tests/test_clabe.py @@ -5,6 +5,7 @@ configure_additional_bank, generate_new_clabes, get_bank_name, + remove_bank, validate_clabe, ) @@ -64,3 +65,9 @@ def test_configure_additional_bank_success(abm_code, banxico_code, name): def test_configure_additional_bank_invalid_inputs(banxico_code, name): with pytest.raises(ValueError): configure_additional_bank(banxico_code, name) + + +def test_remove_bank(): + remove_bank('40138') + with pytest.raises(ValueError): + get_bank_name('138') From acb464465c3dde013a81e649894171d264bc4427 Mon Sep 17 00:00:00 2001 From: gabino Date: Mon, 23 Dec 2024 16:38:34 -0600 Subject: [PATCH 25/27] docs: update README to include instructions for adding a new bank --- README.md | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d67c628..6054eda 100644 --- a/README.md +++ b/README.md @@ -58,9 +58,20 @@ import clabe clabe.generate_new_clabes(10, '002123456') ``` -Para generar un nuevo banco +### Para agregar un nuevo banco + +A partir de la versi贸n 2.0.0, el paquete se actualizar谩 a **Pydantic v2**, lo que significa que las versiones anteriores ya no recibir谩n soporte. + +Sin embargo, hemos a帽adido una funci贸n para agregar bancos adicionales a la lista, en caso de que sea necesario. Esto se puede hacer sin necesidad de crear un PR. Para agregar un banco, simplemente llama a la siguiente funci贸n con el c贸digo de Banxico y el nombre del banco: + +```python +import clabe +clabe.configure_additional_bank('12345', 'New Bank') +``` + +Para eliminar un banco ```python import clabe -clabe.configure_additional_bank('777', '713', 'New Bank') +clabe.remove_bank('12345') ``` From c94a35abd35ab20baae19f531fa5953449a3474b Mon Sep 17 00:00:00 2001 From: gabino Date: Mon, 23 Dec 2024 18:37:10 -0600 Subject: [PATCH 26/27] refactor: rename configure_additional_bank to add_bank and update validation logic - Refactored the add_bank function to improve clarity and validation. - Updated tests to align with the new function name and validation rules. --- README.md | 2 +- clabe/__init__.py | 4 ++-- clabe/validations.py | 49 ++++++++++++++++++++++---------------------- tests/test_clabe.py | 35 +++++++++++++++++++++++-------- 4 files changed, 55 insertions(+), 35 deletions(-) diff --git a/README.md b/README.md index 6054eda..e0aa222 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,7 @@ import clabe clabe.generate_new_clabes(10, '002123456') ``` -### Para agregar un nuevo banco +## Para agregar un nuevo banco A partir de la versi贸n 2.0.0, el paquete se actualizar谩 a **Pydantic v2**, lo que significa que las versiones anteriores ya no recibir谩n soporte. diff --git a/clabe/__init__.py b/clabe/__init__.py index 0905da0..81593be 100644 --- a/clabe/__init__.py +++ b/clabe/__init__.py @@ -7,15 +7,15 @@ 'generate_new_clabes', 'get_bank_name', 'validate_clabe', - 'configure_additional_bank', + 'add_bank', 'remove_bank', ] from .banks import BANK_NAMES, BANKS from .types import Clabe from .validations import ( + add_bank, compute_control_digit, - configure_additional_bank, generate_new_clabes, get_bank_name, remove_bank, diff --git a/clabe/validations.py b/clabe/validations.py index 9677567..d4488c4 100644 --- a/clabe/validations.py +++ b/clabe/validations.py @@ -1,8 +1,7 @@ import random -import re from typing import List, Union -from pydantic import BaseModel, Field, validator +from pydantic import BaseModel, Field from .banks import BANK_NAMES, BANKS @@ -67,31 +66,37 @@ def generate_new_clabes(number_of_clabes: int, prefix: str) -> List[str]: class BankConfigRequest(BaseModel): + """ + Validates and processes bank configuration requests. + + The class handles validation of bank names and codes, ensuring: + - Bank names are non-empty strings + - Banxico codes are exactly 5 digits + """ + bank_name: str = Field( min_length=1, strip_whitespace=True, - description="The name of the bank - cannot be empty", + description="Bank name must have at least 1 character.", ) bank_code_banxico: str = Field( - min_length=5, max_length=5, description="The Banxico code for the bank" + regex=r"^\d{5}$", description="Banxico code must be a 5-digit string." ) - @validator("bank_code_banxico") - def validate_bank_code(cls, value): - if not re.fullmatch(r"\d{5}", value): - raise ValueError( - "bank_code_banxico must be a string of exactly 5 digits" - ) - return value - @property def bank_code_abm(self): return self.bank_code_banxico[-3:] -def configure_additional_bank(bank_code_banxico: str, bank_name: str) -> None: +def add_bank(bank_code_banxico: str, bank_name: str) -> None: + """ + Add a bank configuration. + Args: + bank_code_banxico: 5-digit Banxico bank code + bank_name: Bank name + """ request = BankConfigRequest( bank_code_banxico=bank_code_banxico, bank_name=bank_name, @@ -101,15 +106,11 @@ def configure_additional_bank(bank_code_banxico: str, bank_name: str) -> None: def remove_bank(bank_code_banxico: str) -> None: - bank_code_abm = next( - ( - abm - for abm, banxico in BANKS.items() - if banxico == bank_code_banxico - ), - None, - ) + """ + Remove a bank configuration by its Banxico code. - if bank_code_abm: - BANKS.pop(bank_code_abm) - BANK_NAMES.pop(bank_code_banxico) + Args: + bank_code_banxico: 5-digit Banxico bank code + """ + BANKS.pop(bank_code_banxico[-3:], None) + BANK_NAMES.pop(bank_code_banxico, None) diff --git a/tests/test_clabe.py b/tests/test_clabe.py index 0e8cd22..140991e 100644 --- a/tests/test_clabe.py +++ b/tests/test_clabe.py @@ -1,8 +1,10 @@ import pytest from clabe import ( + BANK_NAMES, + BANKS, + add_bank, compute_control_digit, - configure_additional_bank, generate_new_clabes, get_bank_name, remove_bank, @@ -48,8 +50,8 @@ def test_generate_new_clabes(): ('715', '90715', 'Cuenca Gem Beta'), ], ) -def test_configure_additional_bank_success(abm_code, banxico_code, name): - configure_additional_bank(banxico_code, name) +def test_add_bank_success(abm_code, banxico_code, name): + add_bank(banxico_code, name) assert get_bank_name(abm_code) == name @@ -62,12 +64,29 @@ def test_configure_additional_bank_success(abm_code, banxico_code, name): ('123AT', 'Test Bank'), # Non-numeric codes ], ) -def test_configure_additional_bank_invalid_inputs(banxico_code, name): +def test_add_bank_invalid_inputs(banxico_code, name): with pytest.raises(ValueError): - configure_additional_bank(banxico_code, name) + add_bank(banxico_code, name) def test_remove_bank(): - remove_bank('40138') - with pytest.raises(ValueError): - get_bank_name('138') + test_code = "90716" + test_name = "To Delete Bank" + add_bank(test_code, test_name) + + assert test_code[-3:] in BANKS + assert test_code in BANK_NAMES + + remove_bank(test_code) + + assert test_code[-3:] not in BANKS + assert test_code not in BANK_NAMES + + +def test_remove_nonexistent_bank(): + nonexistent_code = "99999" + + remove_bank(nonexistent_code) + + assert nonexistent_code[-3:] not in BANKS + assert nonexistent_code not in BANK_NAMES From 2cec6f6da0b6be38ef305e09bcbb72daa28fc6d9 Mon Sep 17 00:00:00 2001 From: gabino Date: Mon, 23 Dec 2024 18:43:29 -0600 Subject: [PATCH 27/27] docs: update README to reflect function name change from configure_additional_bank to add_bank --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e0aa222..a00bd5e 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,7 @@ Sin embargo, hemos a帽adido una funci贸n para agregar bancos adicionales a la li ```python import clabe -clabe.configure_additional_bank('12345', 'New Bank') +clabe.add_bank('12345', 'New Bank') ``` Para eliminar un banco