cbpr-validate 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cbpr_validate-1.0.0/.claude/settings.local.json +17 -0
- cbpr_validate-1.0.0/.claude/settings.local.json.tmp.31316.7bec411697e7 +18 -0
- cbpr_validate-1.0.0/.github/workflows/ci.yml +22 -0
- cbpr_validate-1.0.0/.github/workflows/release.yml +123 -0
- cbpr_validate-1.0.0/.gitignore +17 -0
- cbpr_validate-1.0.0/BUILD_PLAN.md +480 -0
- cbpr_validate-1.0.0/CLAUDE.md +107 -0
- cbpr_validate-1.0.0/PKG-INFO +209 -0
- cbpr_validate-1.0.0/README.md +190 -0
- cbpr_validate-1.0.0/pyproject.toml +61 -0
- cbpr_validate-1.0.0/src/cbpr_validate/__init__.py +18 -0
- cbpr_validate-1.0.0/src/cbpr_validate/api/__init__.py +0 -0
- cbpr_validate-1.0.0/src/cbpr_validate/api/main.py +120 -0
- cbpr_validate-1.0.0/src/cbpr_validate/cli.py +247 -0
- cbpr_validate-1.0.0/src/cbpr_validate/codesets/__init__.py +0 -0
- cbpr_validate-1.0.0/src/cbpr_validate/codesets/data/iso20022_codesets.json +276 -0
- cbpr_validate-1.0.0/src/cbpr_validate/codesets/loader.py +35 -0
- cbpr_validate-1.0.0/src/cbpr_validate/config.py +37 -0
- cbpr_validate-1.0.0/src/cbpr_validate/core.py +132 -0
- cbpr_validate-1.0.0/src/cbpr_validate/match/__init__.py +20 -0
- cbpr_validate-1.0.0/src/cbpr_validate/match/matcher.py +449 -0
- cbpr_validate-1.0.0/src/cbpr_validate/match/result.py +98 -0
- cbpr_validate-1.0.0/src/cbpr_validate/model/__init__.py +15 -0
- cbpr_validate-1.0.0/src/cbpr_validate/model/finding.py +21 -0
- cbpr_validate-1.0.0/src/cbpr_validate/model/payment.py +89 -0
- cbpr_validate-1.0.0/src/cbpr_validate/model/validation_result.py +21 -0
- cbpr_validate-1.0.0/src/cbpr_validate/parsers/__init__.py +0 -0
- cbpr_validate-1.0.0/src/cbpr_validate/parsers/_common.py +97 -0
- cbpr_validate-1.0.0/src/cbpr_validate/parsers/detect.py +35 -0
- cbpr_validate-1.0.0/src/cbpr_validate/parsers/pacs002.py +39 -0
- cbpr_validate-1.0.0/src/cbpr_validate/parsers/pacs004.py +52 -0
- cbpr_validate-1.0.0/src/cbpr_validate/parsers/pacs008.py +108 -0
- cbpr_validate-1.0.0/src/cbpr_validate/parsers/pacs009.py +82 -0
- cbpr_validate-1.0.0/src/cbpr_validate/parsers/parse.py +50 -0
- cbpr_validate-1.0.0/src/cbpr_validate/report/__init__.py +0 -0
- cbpr_validate-1.0.0/src/cbpr_validate/report/json_report.py +57 -0
- cbpr_validate-1.0.0/src/cbpr_validate/report/junit_report.py +89 -0
- cbpr_validate-1.0.0/src/cbpr_validate/report/text_report.py +103 -0
- cbpr_validate-1.0.0/src/cbpr_validate/rules/__init__.py +0 -0
- cbpr_validate-1.0.0/src/cbpr_validate/rules/address.py +99 -0
- cbpr_validate-1.0.0/src/cbpr_validate/rules/agents.py +142 -0
- cbpr_validate-1.0.0/src/cbpr_validate/rules/amounts.py +87 -0
- cbpr_validate-1.0.0/src/cbpr_validate/rules/codes.py +77 -0
- cbpr_validate-1.0.0/src/cbpr_validate/rules/registry.py +58 -0
- cbpr_validate-1.0.0/src/cbpr_validate/rules/returns.py +222 -0
- cbpr_validate-1.0.0/src/cbpr_validate/rules/structural.py +123 -0
- cbpr_validate-1.0.0/src/cbpr_validate/schema/__init__.py +0 -0
- cbpr_validate-1.0.0/src/cbpr_validate/schema/xsd.py +104 -0
- cbpr_validate-1.0.0/tests/__init__.py +6 -0
- cbpr_validate-1.0.0/tests/conftest.py +157 -0
- cbpr_validate-1.0.0/tests/fixtures/pacs008_valid_hybrid_ro.xml +99 -0
- cbpr_validate-1.0.0/tests/test_addr004_country_codes.py +95 -0
- cbpr_validate-1.0.0/tests/test_api.py +165 -0
- cbpr_validate-1.0.0/tests/test_bicfi_agents.py +107 -0
- cbpr_validate-1.0.0/tests/test_cli.py +294 -0
- cbpr_validate-1.0.0/tests/test_cod004_pacs002.py +36 -0
- cbpr_validate-1.0.0/tests/test_core.py +161 -0
- cbpr_validate-1.0.0/tests/test_golden_valid.py +78 -0
- cbpr_validate-1.0.0/tests/test_interface_parity.py +133 -0
- cbpr_validate-1.0.0/tests/test_match_correlation.py +442 -0
- cbpr_validate-1.0.0/tests/test_misc_coverage.py +40 -0
- cbpr_validate-1.0.0/tests/test_parsers.py +124 -0
- cbpr_validate-1.0.0/tests/test_parsers_edgecases.py +57 -0
- cbpr_validate-1.0.0/tests/test_parsers_phase4.py +145 -0
- cbpr_validate-1.0.0/tests/test_phase3_rules.py +111 -0
- cbpr_validate-1.0.0/tests/test_report.py +226 -0
- cbpr_validate-1.0.0/tests/test_rules_address.py +157 -0
- cbpr_validate-1.0.0/tests/test_rules_agents.py +116 -0
- cbpr_validate-1.0.0/tests/test_rules_returns.py +111 -0
- cbpr_validate-1.0.0/tests/test_schema_xsd.py +149 -0
- cbpr_validate-1.0.0/tests/test_smoke.py +18 -0
- cbpr_validate-1.0.0/tests/test_str003_mandatory_amount.py +123 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"permissions": {
|
|
3
|
+
"allow": [
|
|
4
|
+
"Bash(.venv/Scripts/python.exe *)",
|
|
5
|
+
"Bash(python -c \"import json; d=json.load\\(open\\('src/cbpr_validate/codesets/data/iso20022_codesets.json'\\)\\); print\\('RETURN', sorted\\(d['ExternalReturnReason1Code']\\)\\); print\\('STATUS', sorted\\(d['ExternalStatusReason1Code']\\)\\); print\\('ISO3166', sorted\\(d['ISO3166-1-alpha-2']\\)\\)\")",
|
|
6
|
+
"Bash(python -m pytest -q)",
|
|
7
|
+
"Bash(python -m pip install -q pytest pytest-cov ruff mypy)",
|
|
8
|
+
"Bash(./.venv/Scripts/python.exe -m mypy src tests)",
|
|
9
|
+
"Bash(./.venv/Scripts/python.exe -m pytest -q)",
|
|
10
|
+
"Bash(./.venv/Scripts/python.exe -m ruff check src tests)",
|
|
11
|
+
"Bash(./.venv/Scripts/python.exe -)",
|
|
12
|
+
"Bash(./.venv/Scripts/cbpr-validate.exe check *)",
|
|
13
|
+
"Bash(echo \"exit=$?\")",
|
|
14
|
+
"Bash(./.venv/Scripts/cbpr-validate.exe match *)"
|
|
15
|
+
]
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"permissions": {
|
|
3
|
+
"allow": [
|
|
4
|
+
"Bash(.venv/Scripts/python.exe *)",
|
|
5
|
+
"Bash(python -c \"import json; d=json.load\\(open\\('src/cbpr_validate/codesets/data/iso20022_codesets.json'\\)\\); print\\('RETURN', sorted\\(d['ExternalReturnReason1Code']\\)\\); print\\('STATUS', sorted\\(d['ExternalStatusReason1Code']\\)\\); print\\('ISO3166', sorted\\(d['ISO3166-1-alpha-2']\\)\\)\")",
|
|
6
|
+
"Bash(python -m pytest -q)",
|
|
7
|
+
"Bash(python -m pip install -q pytest pytest-cov ruff mypy)",
|
|
8
|
+
"Bash(./.venv/Scripts/python.exe -m mypy src tests)",
|
|
9
|
+
"Bash(./.venv/Scripts/python.exe -m pytest -q)",
|
|
10
|
+
"Bash(./.venv/Scripts/python.exe -m ruff check src tests)",
|
|
11
|
+
"Bash(./.venv/Scripts/python.exe -)",
|
|
12
|
+
"Bash(./.venv/Scripts/cbpr-validate.exe check *)",
|
|
13
|
+
"Bash(echo \"exit=$?\")",
|
|
14
|
+
"Bash(./.venv/Scripts/cbpr-validate.exe match *)",
|
|
15
|
+
"Bash(./.venv/Scripts/python.exe -c ' *)"
|
|
16
|
+
]
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
test:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
strategy:
|
|
12
|
+
matrix:
|
|
13
|
+
python-version: ["3.11", "3.12", "3.13"]
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
|
+
- uses: actions/setup-python@v5
|
|
17
|
+
with:
|
|
18
|
+
python-version: ${{ matrix.python-version }}
|
|
19
|
+
- run: pip install -e ".[dev]"
|
|
20
|
+
- run: ruff check .
|
|
21
|
+
- run: mypy src
|
|
22
|
+
- run: pytest
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
# Publishes to PyPI via Trusted Publishing (OIDC) - no API token is stored in
|
|
4
|
+
# the repo or on anyone's laptop. PyPI verifies the workflow identity instead.
|
|
5
|
+
#
|
|
6
|
+
# push a v* tag -> publish to PyPI
|
|
7
|
+
# run manually -> publish to TestPyPI (or PyPI, if you pick it)
|
|
8
|
+
#
|
|
9
|
+
# A PyPI release is permanent: a version number can never be reused, even after
|
|
10
|
+
# deletion. So everything that can be checked is checked before the upload -
|
|
11
|
+
# the full test matrix, the tag/version agreement, and an install of the actual
|
|
12
|
+
# built wheel.
|
|
13
|
+
|
|
14
|
+
on:
|
|
15
|
+
push:
|
|
16
|
+
tags: ["v*"]
|
|
17
|
+
workflow_dispatch:
|
|
18
|
+
inputs:
|
|
19
|
+
target:
|
|
20
|
+
description: "Where to publish"
|
|
21
|
+
type: choice
|
|
22
|
+
options: [testpypi, pypi]
|
|
23
|
+
default: testpypi
|
|
24
|
+
|
|
25
|
+
permissions:
|
|
26
|
+
contents: read
|
|
27
|
+
|
|
28
|
+
jobs:
|
|
29
|
+
# Never publish a red build. Same matrix as CI, because "it passed on main"
|
|
30
|
+
# is not the same claim as "this tag passes".
|
|
31
|
+
test:
|
|
32
|
+
runs-on: ubuntu-latest
|
|
33
|
+
strategy:
|
|
34
|
+
matrix:
|
|
35
|
+
python-version: ["3.11", "3.12", "3.13"]
|
|
36
|
+
steps:
|
|
37
|
+
- uses: actions/checkout@v4
|
|
38
|
+
- uses: actions/setup-python@v5
|
|
39
|
+
with:
|
|
40
|
+
python-version: ${{ matrix.python-version }}
|
|
41
|
+
- run: pip install -e ".[dev]"
|
|
42
|
+
- run: ruff check .
|
|
43
|
+
- run: mypy src
|
|
44
|
+
- run: pytest
|
|
45
|
+
|
|
46
|
+
build:
|
|
47
|
+
needs: test
|
|
48
|
+
runs-on: ubuntu-latest
|
|
49
|
+
steps:
|
|
50
|
+
- uses: actions/checkout@v4
|
|
51
|
+
- uses: actions/setup-python@v5
|
|
52
|
+
with:
|
|
53
|
+
python-version: "3.11"
|
|
54
|
+
|
|
55
|
+
- name: Build sdist and wheel
|
|
56
|
+
run: |
|
|
57
|
+
pip install build twine
|
|
58
|
+
python -m build
|
|
59
|
+
twine check dist/*
|
|
60
|
+
|
|
61
|
+
# The version lives in the package and the tag is written by hand, so
|
|
62
|
+
# they can disagree. Catching that here costs seconds; catching it after
|
|
63
|
+
# an upload costs the version number.
|
|
64
|
+
- name: Tag must match the package version
|
|
65
|
+
if: startsWith(github.ref, 'refs/tags/v')
|
|
66
|
+
run: |
|
|
67
|
+
TAG="${GITHUB_REF_NAME#v}"
|
|
68
|
+
PKG=$(python -c "import re,pathlib; \
|
|
69
|
+
print(re.search(r'__version__ = \"([^\"]+)\"', \
|
|
70
|
+
pathlib.Path('src/cbpr_validate/__init__.py').read_text()).group(1))")
|
|
71
|
+
echo "tag=$TAG package=$PKG"
|
|
72
|
+
test "$TAG" = "$PKG" || { echo "::error::tag v$TAG != package $PKG"; exit 1; }
|
|
73
|
+
|
|
74
|
+
# A wheel can pass every test and still be broken on install - most often
|
|
75
|
+
# because a package-data file (here the ISO 20022 code-set snapshot) was
|
|
76
|
+
# left out of it. So exercise the artifact itself, not the source tree.
|
|
77
|
+
- name: Smoke-test the built wheel
|
|
78
|
+
run: |
|
|
79
|
+
python -m venv /tmp/smoke
|
|
80
|
+
/tmp/smoke/bin/pip install --quiet dist/*.whl
|
|
81
|
+
/tmp/smoke/bin/python -c "import cbpr_validate; print(cbpr_validate.__version__)"
|
|
82
|
+
/tmp/smoke/bin/python -c "from cbpr_validate.codesets.loader import get_codes; \
|
|
83
|
+
n=len(get_codes('ISO3166-1-alpha-2')); print('country codes:', n); assert n > 200"
|
|
84
|
+
/tmp/smoke/bin/cbpr-validate validate tests/fixtures/pacs008_valid_hybrid_ro.xml
|
|
85
|
+
|
|
86
|
+
- uses: actions/upload-artifact@v4
|
|
87
|
+
with:
|
|
88
|
+
name: dist
|
|
89
|
+
path: dist/
|
|
90
|
+
|
|
91
|
+
publish-testpypi:
|
|
92
|
+
needs: build
|
|
93
|
+
if: github.event_name == 'workflow_dispatch' && inputs.target == 'testpypi'
|
|
94
|
+
runs-on: ubuntu-latest
|
|
95
|
+
environment:
|
|
96
|
+
name: testpypi
|
|
97
|
+
url: https://test.pypi.org/p/cbpr-validate
|
|
98
|
+
permissions:
|
|
99
|
+
id-token: write # the OIDC token Trusted Publishing exchanges for an upload
|
|
100
|
+
steps:
|
|
101
|
+
- uses: actions/download-artifact@v4
|
|
102
|
+
with:
|
|
103
|
+
name: dist
|
|
104
|
+
path: dist/
|
|
105
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
106
|
+
with:
|
|
107
|
+
repository-url: https://test.pypi.org/legacy/
|
|
108
|
+
|
|
109
|
+
publish-pypi:
|
|
110
|
+
needs: build
|
|
111
|
+
if: startsWith(github.ref, 'refs/tags/v') || (github.event_name == 'workflow_dispatch' && inputs.target == 'pypi')
|
|
112
|
+
runs-on: ubuntu-latest
|
|
113
|
+
environment:
|
|
114
|
+
name: pypi
|
|
115
|
+
url: https://pypi.org/p/cbpr-validate
|
|
116
|
+
permissions:
|
|
117
|
+
id-token: write
|
|
118
|
+
steps:
|
|
119
|
+
- uses: actions/download-artifact@v4
|
|
120
|
+
with:
|
|
121
|
+
name: dist
|
|
122
|
+
path: dist/
|
|
123
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|