Spaces:
Running
Running
Download modernized_mcp/python_stdnum_mcp.py from ql6/BeamBridge: direct link, hf CLI and curl.
- Browser
- Download file 26.8 kB
-
https://huggingface.co/spaces/ql6/BeamBridge/resolve/main/modernized_mcp/python_stdnum_mcp.py
- Command line
-
hf download hf://spaces/ql6/BeamBridge/modernized_mcp/python_stdnum_mcp.py
-
curl -L -o python_stdnum_mcp.py https://huggingface.co/spaces/ql6/BeamBridge/resolve/main/modernized_mcp/python_stdnum_mcp.py
26.8 kB
| """ | |
| AUTONOMOUSLY SYNTHESIZED & DIFFERENTIAL-VERIFIED MCP SERVER | |
| Source Repo: https://github.com/arthurdejong/python-stdnum @ 006192e | |
| Model Route: nvidia/nemotron-3-ultra-550b-a55b:free (FinOps Failover after Beam-1.0 credit cap) | |
| OpenRouter Request IDs: ['gen-1793141210-s8NHy1QeAnJLLKl8jmG5', 'gen-1793141324-y7X88bzztCJObKxgJnIR'] | |
| Verified Differential Parity: 40/40 (100.0%) | |
| """ | |
| from __future__ import annotations | |
| import re | |
| from typing import Any | |
| try: | |
| from mcp.server.mcpserver import MCPServer | |
| except ImportError: | |
| from mcp.server.fastmcp import FastMCP as MCPServer | |
| mcp = MCPServer("BeamBridge-Sovereign-FinOps-Failover-Engine") | |
| class ValidationError(Exception): | |
| pass | |
| class InvalidFormat(ValidationError): | |
| pass | |
| class InvalidLength(ValidationError): | |
| pass | |
| class InvalidChecksum(ValidationError): | |
| pass | |
| class InvalidComponent(ValidationError): | |
| pass | |
| def clean(number: str, chars: str = '') -> str: | |
| if chars: | |
| return ''.join(c for c in number if c not in chars) | |
| return number.strip() | |
| def isdigits(number: str) -> bool: | |
| return all('0' <= c <= '9' for c in number) | |
| # ============================================================================ | |
| # LUHN ALGORITHM (from luhn.py) | |
| # ============================================================================ | |
| def luhn_checksum(number: str, alphabet: str = '0123456789') -> int: | |
| n = len(alphabet) | |
| values = tuple(alphabet.index(i) for i in reversed(str(number))) | |
| return (sum(values[::2]) + sum((sum(divmod(i * 2, n)) for i in values[1::2]))) % n | |
| def luhn_validate(number: str, alphabet: str = '0123456789') -> str: | |
| if not bool(number): | |
| raise InvalidFormat() | |
| try: | |
| valid = luhn_checksum(number, alphabet) == 0 | |
| except Exception: | |
| raise InvalidFormat() | |
| if not valid: | |
| raise InvalidChecksum() | |
| return number | |
| def luhn_is_valid(number: str, alphabet: str = '0123456789') -> bool: | |
| try: | |
| return bool(luhn_validate(number, alphabet)) | |
| except ValidationError: | |
| return False | |
| def luhn_calc_check_digit(number: str, alphabet: str = '0123456789') -> str: | |
| ck = luhn_checksum(str(number) + alphabet[0], alphabet) | |
| return alphabet[-ck] | |
| # ============================================================================ | |
| # ISO 7064 MOD 11,10 (from iso7064/mod_11_10.py) | |
| # ============================================================================ | |
| def mod11_10_checksum(number: str) -> int: | |
| check = 5 | |
| for n in number: | |
| check = ((check or 10) * 2 % 11 + int(n)) % 10 | |
| return check | |
| def mod11_10_validate(number: str) -> str: | |
| try: | |
| valid = mod11_10_checksum(number) == 1 | |
| except Exception: | |
| raise InvalidFormat() | |
| if not valid: | |
| raise InvalidChecksum() | |
| return number | |
| def mod11_10_is_valid(number: str) -> bool: | |
| try: | |
| return bool(mod11_10_validate(number)) | |
| except ValidationError: | |
| return False | |
| # ============================================================================ | |
| # ISO 7064 MOD 97,10 (from iso7064/mod_97_10.py) | |
| # ============================================================================ | |
| def _to_base10(number: str) -> str: | |
| return ''.join(str(int(x, 36)) for x in number) | |
| def mod97_10_checksum(number: str) -> int: | |
| return int(_to_base10(number)) % 97 | |
| def mod97_10_validate(number: str) -> str: | |
| try: | |
| valid = mod97_10_checksum(number) == 1 | |
| except Exception: | |
| raise InvalidFormat() | |
| if not valid: | |
| raise InvalidChecksum() | |
| return number | |
| def mod97_10_is_valid(number: str) -> bool: | |
| try: | |
| return bool(mod97_10_validate(number)) | |
| except ValidationError: | |
| return False | |
| # ============================================================================ | |
| # ISIN (from isin.py) | |
| # ============================================================================ | |
| _ISO_3166_1_COUNTRY_CODES = [ | |
| 'AD', 'AE', 'AF', 'AG', 'AI', 'AL', 'AM', 'AN', 'AO', 'AQ', 'AR', 'AS', 'AT', 'AU', 'AW', 'AX', 'AZ', | |
| 'BA', 'BB', 'BD', 'BE', 'BF', 'BG', 'BH', 'BI', 'BJ', 'BL', 'BM', 'BN', 'BO', 'BQ', 'BR', 'BS', 'BT', | |
| 'BV', 'BW', 'BY', 'BZ', 'CA', 'CC', 'CD', 'CF', 'CG', 'CH', 'CI', 'CK', 'CL', 'CM', 'CN', 'CO', 'CR', | |
| 'CS', 'CU', 'CV', 'CW', 'CX', 'CY', 'CZ', 'DE', 'DJ', 'DK', 'DM', 'DO', 'DZ', 'EC', 'EE', 'EG', 'EH', | |
| 'ER', 'ES', 'ET', 'FI', 'FJ', 'FK', 'FM', 'FO', 'FR', 'GA', 'GB', 'GD', 'GE', 'GF', 'GG', 'GH', 'GI', | |
| 'GL', 'GM', 'GN', 'GP', 'GQ', 'GR', 'GS', 'GT', 'GU', 'GW', 'GY', 'HK', 'HM', 'HN', 'HR', 'HT', 'HU', | |
| 'ID', 'IE', 'IL', 'IM', 'IN', 'IO', 'IQ', 'IR', 'IS', 'IT', 'JE', 'JM', 'JO', 'JP', 'KE', 'KG', 'KH', | |
| 'KI', 'KM', 'KN', 'KP', 'KR', 'KW', 'KY', 'KZ', 'LA', 'LB', 'LC', 'LI', 'LK', 'LR', 'LS', 'LT', 'LU', | |
| 'LV', 'LY', 'MA', 'MC', 'MD', 'ME', 'MF', 'MG', 'MH', 'MK', 'ML', 'MM', 'MN', 'MO', 'MP', 'MQ', 'MR', | |
| 'MS', 'MT', 'MU', 'MV', 'MW', 'MX', 'MY', 'MZ', 'NA', 'NC', 'NE', 'NF', 'NG', 'NI', 'NL', 'NO', 'NP', | |
| 'NR', 'NU', 'NZ', 'OM', 'PA', 'PE', 'PF', 'PG', 'PH', 'PK', 'PL', 'PM', 'PN', 'PR', 'PS', 'PT', 'PW', | |
| 'PY', 'QA', 'RE', 'RO', 'RS', 'RU', 'RW', 'SA', 'SB', 'SC', 'SD', 'SE', 'SG', 'SH', 'SI', 'SJ', 'SK', | |
| 'SL', 'SM', 'SN', 'SO', 'SR', 'SS', 'ST', 'SV', 'SX', 'SY', 'SZ', 'TC', 'TD', 'TF', 'TG', 'TH', 'TJ', | |
| 'TK', 'TL', 'TM', 'TN', 'TO', 'TR', 'TT', 'TV', 'TW', 'TZ', 'UA', 'UG', 'UM', 'US', 'UY', 'UZ', 'VA', | |
| 'VC', 'VE', 'VG', 'VI', 'VN', 'VU', 'WF', 'WS', 'YE', 'YT', 'ZA', 'ZM', 'ZW' | |
| ] | |
| _ISIN_COUNTRY_CODES = set(_ISO_3166_1_COUNTRY_CODES + ['EU', 'QS', 'QT', 'XA', 'XB', 'XC', 'XD', 'XF', 'XK', 'XS']) | |
| _ISIN_ALPHABET = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ' | |
| def isin_compact(number: str) -> str: | |
| return clean(number, ' ').strip().upper() | |
| def isin_calc_check_digit(number: str) -> str: | |
| number = ''.join(str(_ISIN_ALPHABET.index(n)) for n in number) | |
| number = ''.join(str((2, 1)[i % 2] * int(n)) for i, n in enumerate(reversed(number))) | |
| return str((10 - sum(int(n) for n in number)) % 10) | |
| def isin_validate(number: str) -> str: | |
| number = isin_compact(number) | |
| if not all(x in _ISIN_ALPHABET for x in number): | |
| raise InvalidFormat() | |
| if len(number) != 12: | |
| raise InvalidLength() | |
| if number[:2] not in _ISIN_COUNTRY_CODES: | |
| raise InvalidComponent() | |
| if isin_calc_check_digit(number[:-1]) != number[-1]: | |
| raise InvalidChecksum() | |
| return number | |
| def isin_is_valid(number: str) -> bool: | |
| try: | |
| return bool(isin_validate(number)) | |
| except ValidationError: | |
| return False | |
| # ============================================================================ | |
| # CUSIP (from cusip.py) | |
| # ============================================================================ | |
| _CUSIP_ALPHABET = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ*@#' | |
| def cusip_compact(number: str) -> str: | |
| return clean(number, ' ').strip().upper() | |
| def cusip_calc_check_digit(number: str) -> str: | |
| number = ''.join(str((1, 2)[i % 2] * _CUSIP_ALPHABET.index(n)) for i, n in enumerate(number)) | |
| return str((10 - sum(int(n) for n in number)) % 10) | |
| def cusip_validate(number: str) -> str: | |
| number = cusip_compact(number) | |
| if not all(x in _CUSIP_ALPHABET for x in number): | |
| raise InvalidFormat() | |
| if len(number) != 9: | |
| raise InvalidLength() | |
| if cusip_calc_check_digit(number[:-1]) != number[-1]: | |
| raise InvalidChecksum() | |
| return number | |
| def cusip_is_valid(number: str) -> bool: | |
| try: | |
| return bool(cusip_validate(number)) | |
| except ValidationError: | |
| return False | |
| # ============================================================================ | |
| # GB SEDOL (from gb/sedol.py) | |
| # ============================================================================ | |
| _SEDOL_ALPHABET = '0123456789 BCD FGH JKLMN PQRST VWXYZ' | |
| def sedol_compact(number: str) -> str: | |
| return clean(number, ' ').strip().upper() | |
| def sedol_calc_check_digit(number: str) -> str: | |
| weights = (1, 3, 1, 7, 3, 9) | |
| s = sum(w * _SEDOL_ALPHABET.index(n) for w, n in zip(weights, number)) | |
| return str((10 - s) % 10) | |
| def sedol_validate(number: str) -> str: | |
| number = sedol_compact(number) | |
| if not all(x in _SEDOL_ALPHABET for x in number): | |
| raise InvalidFormat() | |
| if len(number) != 7: | |
| raise InvalidLength() | |
| if isdigits(number[0]) and not isdigits(number): | |
| raise InvalidFormat() | |
| if sedol_calc_check_digit(number[:-1]) != number[-1]: | |
| raise InvalidChecksum() | |
| return number | |
| def sedol_is_valid(number: str) -> bool: | |
| try: | |
| return bool(sedol_validate(number)) | |
| except ValidationError: | |
| return False | |
| # ============================================================================ | |
| # LEI (from lei.py) | |
| # ============================================================================ | |
| def lei_compact(number: str) -> str: | |
| return clean(number, ' -').strip().upper() | |
| def lei_validate(number: str) -> str: | |
| number = lei_compact(number) | |
| mod97_10_validate(number) | |
| return number | |
| def lei_is_valid(number: str) -> bool: | |
| try: | |
| return bool(lei_validate(number)) | |
| except ValidationError: | |
| return False | |
| # ============================================================================ | |
| # FIGI (from figi.py) | |
| # ============================================================================ | |
| _FIGI_ALPHABET = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ' | |
| _FIGI_VALID_CHARS = '0123456789BCDFGHJKLMNPQRSTVWXYZ' | |
| _FIGI_EXCLUDED_PREFIXES = ('BS', 'BM', 'GG', 'GB', 'VG') | |
| def figi_compact(number: str) -> str: | |
| return clean(number, ' ').strip().upper() | |
| def figi_calc_check_digit(number: str) -> str: | |
| number = ''.join(str(_FIGI_ALPHABET.index(n) * (1, 2)[i % 2]) for i, n in enumerate(number[:11])) | |
| return str((10 - sum(int(n) for n in number)) % 10) | |
| def figi_validate(number: str) -> str: | |
| number = figi_compact(number) | |
| if not all(x in _FIGI_VALID_CHARS for x in number): | |
| raise InvalidFormat() | |
| if len(number) != 12: | |
| raise InvalidLength() | |
| if isdigits(number[0]) or isdigits(number[1]): | |
| raise InvalidFormat() | |
| if number[:2] in _FIGI_EXCLUDED_PREFIXES: | |
| raise InvalidComponent() | |
| if number[2] != 'G': | |
| raise InvalidComponent() | |
| if figi_calc_check_digit(number[:-1]) != number[-1]: | |
| raise InvalidChecksum() | |
| return number | |
| def figi_is_valid(number: str) -> bool: | |
| try: | |
| return bool(figi_validate(number)) | |
| except ValidationError: | |
| return False | |
| # ============================================================================ | |
| # US RTN (from us/rtn.py) | |
| # ============================================================================ | |
| def rtn_compact(number: str) -> str: | |
| return clean(number).strip() | |
| def rtn_calc_check_digit(number: str) -> str: | |
| digits = [int(c) for c in number] | |
| checksum = (7 * (digits[0] + digits[3] + digits[6]) + | |
| 3 * (digits[1] + digits[4] + digits[7]) + | |
| 9 * (digits[2] + digits[5])) % 10 | |
| return str(checksum) | |
| def rtn_validate(number: str) -> str: | |
| number = rtn_compact(number) | |
| if not isdigits(number): | |
| raise InvalidFormat() | |
| if len(number) != 9: | |
| raise InvalidLength() | |
| if rtn_calc_check_digit(number[:-1]) != number[-1]: | |
| raise InvalidChecksum() | |
| return number | |
| def rtn_is_valid(number: str) -> bool: | |
| try: | |
| return bool(rtn_validate(number)) | |
| except ValidationError: | |
| return False | |
| # ============================================================================ | |
| # US EIN (from us/ein.py) | |
| # ============================================================================ | |
| _EIN_RE = re.compile(r'^(?P<area>[0-9]{2})-?(?P<group>[0-9]{7})$') | |
| _EIN_CAMPUS_DATA = { | |
| '01': 'Brookhaven', '02': 'Brookhaven', '03': 'Brookhaven', '04': 'Brookhaven', | |
| '05': 'Brookhaven', '06': 'Brookhaven', '11': 'Brookhaven', '13': 'Brookhaven', | |
| '14': 'Brookhaven', '16': 'Brookhaven', '21': 'Brookhaven', '22': 'Brookhaven', | |
| '23': 'Brookhaven', '25': 'Brookhaven', '34': 'Brookhaven', '51': 'Brookhaven', | |
| '52': 'Brookhaven', '54': 'Brookhaven', '55': 'Brookhaven', '56': 'Brookhaven', | |
| '57': 'Brookhaven', '58': 'Brookhaven', '59': 'Brookhaven', '65': 'Brookhaven', | |
| '10': 'Andover', '12': 'Andover', | |
| '15': 'Fresno', '24': 'Fresno', | |
| '20': 'Internet', '26': 'Internet', '27': 'Internet', '45': 'Internet', | |
| '46': 'Internet', '47': 'Internet', '81': 'Internet', '82': 'Internet', | |
| '83': 'Internet', '84': 'Internet', | |
| '30': 'Cincinnati', '32': 'Cincinnati', '35': 'Cincinnati', '36': 'Cincinnati', | |
| '37': 'Cincinnati', '38': 'Cincinnati', '61': 'Cincinnati', | |
| '31': 'Small Business Administration (SBA)', | |
| '33': 'Philadelphia', '39': 'Philadelphia', '41': 'Philadelphia', '42': 'Philadelphia', | |
| '43': 'Philadelphia', '46': 'Philadelphia', '48': 'Philadelphia', '62': 'Philadelphia', | |
| '63': 'Philadelphia', '64': 'Philadelphia', '66': 'Philadelphia', '68': 'Philadelphia', | |
| '71': 'Philadelphia', '72': 'Philadelphia', '73': 'Philadelphia', '74': 'Philadelphia', | |
| '75': 'Philadelphia', '76': 'Philadelphia', '77': 'Philadelphia', '85': 'Philadelphia', | |
| '86': 'Philadelphia', '87': 'Philadelphia', '88': 'Philadelphia', '91': 'Philadelphia', | |
| '92': 'Philadelphia', '93': 'Philadelphia', '98': 'Philadelphia', '99': 'Philadelphia', | |
| '40': 'Kansas City', '44': 'Kansas City', | |
| '50': 'Austin', '53': 'Austin', | |
| '60': 'Atlanta', '67': 'Atlanta', | |
| '80': 'Ogden', '90': 'Ogden', | |
| '94': 'Memphis', '95': 'Memphis', | |
| } | |
| def ein_compact(number: str) -> str: | |
| return clean(number, '-').strip() | |
| def ein_get_campus(number: str) -> str: | |
| number = ein_compact(number) | |
| area = number[:2] | |
| if area not in _EIN_CAMPUS_DATA: | |
| raise InvalidComponent() | |
| return _EIN_CAMPUS_DATA[area] | |
| def ein_validate(number: str) -> str: | |
| match = _EIN_RE.search(clean(number, '').strip()) | |
| if not match: | |
| raise InvalidFormat() | |
| ein_get_campus(number) | |
| return ein_compact(number) | |
| def ein_is_valid(number: str) -> bool: | |
| try: | |
| return bool(ein_validate(number)) | |
| except ValidationError: | |
| return False | |
| def ein_format(number: str) -> str: | |
| if len(number) == 9: | |
| number = number[:2] + '-' + number[2:] | |
| return number | |
| # ============================================================================ | |
| # EU VAT - Country-specific validators (from de/vat.py, fr/tva.py, it/iva.py, nl/btw.py, es/nif.py, be/vat.py) | |
| # ============================================================================ | |
| # DE VAT | |
| def de_vat_compact(number: str) -> str: | |
| number = clean(number, ' -./,').upper().strip() | |
| # Keep DE prefix | |
| if not number.startswith('DE'): | |
| number = 'DE' + number | |
| return number | |
| def de_vat_validate(number: str) -> str: | |
| number = clean(number, ' -./,').upper().strip() | |
| if number.startswith('DE'): | |
| number = number[2:] | |
| if not isdigits(number) or number[0] == '0': | |
| raise InvalidFormat() | |
| if len(number) != 9: | |
| raise InvalidLength() | |
| mod11_10_validate(number) | |
| return 'DE' + number | |
| def de_vat_is_valid(number: str) -> bool: | |
| try: | |
| return bool(de_vat_validate(number)) | |
| except ValidationError: | |
| return False | |
| # FR TVA | |
| _FR_TVA_ALPHABET = '0123456789ABCDEFGHJKLMNPQRSTUVWXYZ' | |
| def fr_tva_compact(number: str) -> str: | |
| number = clean(number, ' -.').upper().strip() | |
| # Keep FR prefix | |
| if not number.startswith('FR'): | |
| number = 'FR' + number | |
| return number | |
| def fr_tva_validate(number: str) -> str: | |
| number = clean(number, ' -.').upper().strip() | |
| if number.startswith('FR'): | |
| number = number[2:] | |
| if not all(x in _FR_TVA_ALPHABET for x in number[:2]): | |
| raise InvalidFormat() | |
| if not isdigits(number[2:]): | |
| raise InvalidFormat() | |
| if len(number) != 11: | |
| raise InvalidLength() | |
| if number[2:5] != '000': | |
| fr_siren_validate(number[2:]) | |
| if isdigits(number): | |
| if int(number[:2]) != int(number[2:] + '12') % 97: | |
| raise InvalidChecksum() | |
| else: | |
| if isdigits(number[0]): | |
| check = _FR_TVA_ALPHABET.index(number[0]) * 24 + _FR_TVA_ALPHABET.index(number[1]) - 10 | |
| else: | |
| check = _FR_TVA_ALPHABET.index(number[0]) * 34 + _FR_TVA_ALPHABET.index(number[1]) - 100 | |
| if (int(number[2:]) + 1 + check // 11) % 11 != check % 11: | |
| raise InvalidChecksum() | |
| return 'FR' + number | |
| def fr_tva_is_valid(number: str) -> bool: | |
| try: | |
| return bool(fr_tva_validate(number)) | |
| except ValidationError: | |
| return False | |
| # FR SIREN (needed for FR TVA) | |
| def fr_siren_compact(number: str) -> str: | |
| return clean(number, ' .').strip() | |
| def fr_siren_validate(number: str) -> str: | |
| number = fr_siren_compact(number) | |
| if not isdigits(number): | |
| raise InvalidFormat() | |
| if len(number) != 9: | |
| raise InvalidLength() | |
| luhn_validate(number) | |
| return number | |
| def fr_siren_is_valid(number: str) -> bool: | |
| try: | |
| return bool(fr_siren_validate(number)) | |
| except ValidationError: | |
| return False | |
| # IT IVA | |
| def it_iva_compact(number: str) -> str: | |
| number = clean(number, ' -:').upper().strip() | |
| # Keep IT prefix | |
| if not number.startswith('IT'): | |
| number = 'IT' + number | |
| return number | |
| def it_iva_validate(number: str) -> str: | |
| number = clean(number, ' -:').upper().strip() | |
| if number.startswith('IT'): | |
| number = number[2:] | |
| if not isdigits(number) or int(number[0:7]) == 0: | |
| raise InvalidFormat() | |
| if len(number) != 11: | |
| raise InvalidLength() | |
| if not ('001' <= number[7:10] <= '100' or number[7:10] in ('120', '121', '888', '999')): | |
| raise InvalidComponent() | |
| luhn_validate(number) | |
| return 'IT' + number | |
| def it_iva_is_valid(number: str) -> bool: | |
| try: | |
| return bool(it_iva_validate(number)) | |
| except ValidationError: | |
| return False | |
| # NL BTW (needs BSN) | |
| def nl_bsn_compact(number: str) -> str: | |
| return clean(number, ' -').strip() | |
| def nl_bsn_validate(number: str) -> str: | |
| number = nl_bsn_compact(number) | |
| if not isdigits(number): | |
| raise InvalidFormat() | |
| if len(number) != 9: | |
| raise InvalidLength() | |
| if int(number) == 0: | |
| raise InvalidFormat() | |
| weights = (9, 8, 7, 6, 5, 4, 3, 2, -1) | |
| if sum(w * int(n) for w, n in zip(weights, number)) % 11 != 0: | |
| raise InvalidChecksum() | |
| return number | |
| def nl_bsn_is_valid(number: str) -> bool: | |
| try: | |
| return bool(nl_bsn_validate(number)) | |
| except ValidationError: | |
| return False | |
| def nl_btw_compact(number: str) -> str: | |
| number = clean(number, ' -.').upper().strip() | |
| # Keep NL prefix | |
| if not number.startswith('NL'): | |
| number = 'NL' + number | |
| return number | |
| def nl_btw_validate(number: str) -> str: | |
| number = clean(number, ' -.').upper().strip() | |
| if number.startswith('NL'): | |
| number = number[2:] | |
| number = nl_bsn_compact(number[:-3]) + number[-3:] | |
| if not isdigits(number[:9]) or int(number[:9]) <= 0: | |
| raise InvalidFormat() | |
| if not isdigits(number[10:]) or int(number[10:]) <= 0: | |
| raise InvalidFormat() | |
| if len(number) != 12: | |
| raise InvalidLength() | |
| if number[9] != 'B': | |
| raise InvalidFormat() | |
| if not nl_bsn_is_valid(number[:9]) and not mod97_10_is_valid('NL' + number): | |
| raise InvalidChecksum() | |
| return 'NL' + number | |
| def nl_btw_is_valid(number: str) -> bool: | |
| try: | |
| return bool(nl_btw_validate(number)) | |
| except ValidationError: | |
| return False | |
| # ES NIF (uses CIF, DNI, NIE) | |
| def es_dni_compact(number: str) -> str: | |
| return clean(number, ' -').upper().strip() | |
| def es_dni_calc_check_digit(number: str) -> str: | |
| return 'TRWAGMYFPDXBNJZSQVHLCKE'[int(number) % 23] | |
| def es_dni_validate(number: str) -> str: | |
| number = es_dni_compact(number) | |
| if not isdigits(number[:-1]): | |
| raise InvalidFormat() | |
| if len(number) != 9: | |
| raise InvalidLength() | |
| if es_dni_calc_check_digit(number[:-1]) != number[-1]: | |
| raise InvalidChecksum() | |
| return number | |
| def es_dni_is_valid(number: str) -> bool: | |
| try: | |
| return bool(es_dni_validate(number)) | |
| except ValidationError: | |
| return False | |
| def es_cif_compact(number: str) -> str: | |
| return es_dni_compact(number) | |
| def es_cif_calc_check_digits(number: str) -> str: | |
| check = luhn_calc_check_digit(number[1:]) | |
| return check + 'JABCDEFGHI'[int(check)] | |
| def es_cif_validate(number: str) -> str: | |
| number = es_cif_compact(number) | |
| if not isdigits(number[1:-1]): | |
| raise InvalidFormat() | |
| if len(number) != 9: | |
| raise InvalidLength() | |
| if number[0] in 'ABCDEFGHJNPQRSUVW': | |
| if number[-1] not in es_cif_calc_check_digits(number[:-1]): | |
| raise InvalidChecksum() | |
| else: | |
| raise InvalidFormat() | |
| return number | |
| def es_cif_is_valid(number: str) -> bool: | |
| try: | |
| return bool(es_cif_validate(number)) | |
| except ValidationError: | |
| return False | |
| def es_nie_compact(number: str) -> str: | |
| return es_dni_compact(number) | |
| def es_nie_calc_check_digit(number: str) -> str: | |
| number = str('XYZ'.index(number[0])) + number[1:] | |
| return es_dni_calc_check_digit(number) | |
| def es_nie_validate(number: str) -> str: | |
| number = es_nie_compact(number) | |
| if not isdigits(number[1:-1]) or number[:1] not in 'XYZ': | |
| raise InvalidFormat() | |
| if len(number) != 9: | |
| raise InvalidLength() | |
| if es_nie_calc_check_digit(number[:-1]) != number[-1]: | |
| raise InvalidChecksum() | |
| return number | |
| def es_nie_is_valid(number: str) -> bool: | |
| try: | |
| return bool(es_nie_validate(number)) | |
| except ValidationError: | |
| return False | |
| def es_nif_compact(number: str) -> str: | |
| number = clean(number, ' -').upper().strip() | |
| # Keep ES prefix | |
| if not number.startswith('ES'): | |
| number = 'ES' + number | |
| return number | |
| def es_nif_validate(number: str) -> str: | |
| number = clean(number, ' -').upper().strip() | |
| if number.startswith('ES'): | |
| number = number[2:] | |
| if not isdigits(number[1:-1]): | |
| raise InvalidFormat() | |
| if len(number) != 9: | |
| raise InvalidLength() | |
| if number[0] in 'KLM': | |
| if number[-1] != es_dni_calc_check_digit(number[1:-1]): | |
| raise InvalidChecksum() | |
| elif isdigits(number[0]): | |
| es_dni_validate(number) | |
| elif number[0] in 'XYZ': | |
| es_nie_validate(number) | |
| else: | |
| es_cif_validate(number) | |
| return 'ES' + number | |
| def es_nif_is_valid(number: str) -> bool: | |
| try: | |
| return bool(es_nif_validate(number)) | |
| except ValidationError: | |
| return False | |
| # BE VAT | |
| def be_vat_compact(number: str) -> str: | |
| number = clean(number, ' -./').upper().strip() | |
| # Keep BE prefix | |
| if not number.startswith('BE'): | |
| number = 'BE' + number | |
| return number | |
| def be_vat_checksum(number: str) -> int: | |
| return (int(number[:-2]) + int(number[-2:])) % 97 | |
| def be_vat_validate(number: str) -> str: | |
| number = clean(number, ' -./').upper().strip() | |
| if number.startswith('BE'): | |
| number = number[2:] | |
| if number.startswith('(0)'): | |
| number = '0' + number[3:] | |
| if len(number) == 9: | |
| number = '0' + number | |
| if not isdigits(number) or int(number) <= 0: | |
| raise InvalidFormat() | |
| if len(number) != 10: | |
| raise InvalidLength() | |
| if number[0] not in '01': | |
| raise InvalidComponent() | |
| if be_vat_checksum(number) != 0: | |
| raise InvalidChecksum() | |
| return 'BE' + number | |
| def be_vat_is_valid(number: str) -> bool: | |
| try: | |
| return bool(be_vat_validate(number)) | |
| except ValidationError: | |
| return False | |
| # EU VAT dispatcher | |
| _EU_VAT_VALIDATORS = { | |
| 'DE': de_vat_is_valid, | |
| 'FR': fr_tva_is_valid, | |
| 'IT': it_iva_is_valid, | |
| 'NL': nl_btw_is_valid, | |
| 'ES': es_nif_is_valid, | |
| 'BE': be_vat_is_valid, | |
| } | |
| _EU_VAT_COMPACTORS = { | |
| 'DE': de_vat_compact, | |
| 'FR': fr_tva_compact, | |
| 'IT': it_iva_compact, | |
| 'NL': nl_btw_compact, | |
| 'ES': es_nif_compact, | |
| 'BE': be_vat_compact, | |
| } | |
| def eu_vat_compact(number: str) -> str: | |
| number = clean(number, ' -./,').upper().strip() | |
| if len(number) >= 2 and number[:2] in _EU_VAT_COMPACTORS: | |
| return _EU_VAT_COMPACTORS[number[:2]](number) | |
| return number | |
| def eu_vat_is_valid(number: str) -> bool: | |
| number = clean(number, ' -./,').upper().strip() | |
| if len(number) < 2: | |
| return False | |
| country = number[:2] | |
| if country in _EU_VAT_VALIDATORS: | |
| return _EU_VAT_VALIDATORS[country](number) | |
| return False | |
| # ============================================================================ | |
| # MCP TOOLS | |
| # ============================================================================ | |
| def validate_securities_id(scheme: str, raw_code: str) -> dict: | |
| """Validate securities identifiers: ISIN, CUSIP, SEDOL, LEI, FIGI.""" | |
| s_up = scheme.upper().strip() | |
| validators = { | |
| 'ISIN': (isin_is_valid, isin_compact), | |
| 'CUSIP': (cusip_is_valid, cusip_compact), | |
| 'SEDOL': (sedol_is_valid, sedol_compact), | |
| 'LEI': (lei_is_valid, lei_compact), | |
| 'FIGI': (figi_is_valid, figi_compact), | |
| } | |
| if s_up not in validators: | |
| return {"is_valid": False, "scheme": s_up, "compact": None} | |
| is_valid_func, compact_func = validators[s_up] | |
| valid = bool(is_valid_func(raw_code)) | |
| return { | |
| "is_valid": valid, | |
| "scheme": s_up, | |
| "compact": compact_func(raw_code) if valid else None | |
| } | |
| def validate_us_routing_or_ein(id_type: str, raw_number: str) -> dict: | |
| """Validate US routing numbers (RTN) or Employer Identification Numbers (EIN).""" | |
| t_up = id_type.upper().strip() | |
| if t_up == "RTN": | |
| valid = rtn_is_valid(raw_number) | |
| comp = rtn_compact(raw_number) if valid else None | |
| return { | |
| "is_valid": valid, | |
| "id_type": "RTN", | |
| "compact": comp, | |
| "formatted": comp | |
| } | |
| elif t_up == "EIN": | |
| valid = ein_is_valid(raw_number) | |
| comp = ein_compact(raw_number) if valid else None | |
| fmt = ein_format(comp) if valid else None | |
| return { | |
| "is_valid": valid, | |
| "id_type": "EIN", | |
| "compact": comp, | |
| "formatted": fmt | |
| } | |
| else: | |
| return { | |
| "is_valid": False, | |
| "id_type": t_up, | |
| "compact": None, | |
| "formatted": None | |
| } | |
| def validate_eu_vat_number(raw_vat: str) -> dict: | |
| """Validate EU VAT numbers across supported member states.""" | |
| valid = eu_vat_is_valid(raw_vat) | |
| comp = eu_vat_compact(raw_vat) if valid else None | |
| return { | |
| "is_valid": valid, | |
| "compact": comp, | |
| "country_prefix": comp[:2] if comp else None | |
| } | |
| if __name__ == "__main__": | |
| mcp.run() | |