Metadata-Version: 2.4
Name: datacheck-kit
Version: 1.0.0
Summary: Zero-dependency toolkit for validating and formatting everyday data: emails, phone numbers, URLs, IBANs, credit card numbers, postal codes and slugs.
License: MIT
Project-URL: Homepage, https://luckymisters.uk
Project-URL: Repository, https://github.com/CHANGE_ME/datacheck-kit-py
Keywords: validation,validator,formatter,email,phone,iban,postal-code,credit-card,slugify,sanitize,data-cleaning
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Text Processing
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

# datacheck-kit

A small, zero-dependency toolkit for validating and formatting the kinds of
data that show up in almost every form or import script: email addresses,
phone numbers, URLs, IBANs, credit card numbers, postal codes and slugs.

It exists because most projects end up copy-pasting the same handful of
regexes and checksum functions over and over. This package collects the
ones worth reusing into one place, with tests and no runtime dependencies.

This is a Python port of the [datacheck-kit npm package](https://www.npmjs.com/package/datacheck-kit) — same API surface, adapted to Python conventions (`snake_case`, `None` instead of `null`).

## Install

```bash
pip install datacheck-kit
```

## Usage

```python
import datacheck_kit as dk

dk.is_valid_email("user@example.com")        # True
dk.normalize_email("  User@Example.COM ")    # "user@example.com"

dk.is_valid_url("example.com")               # False (no protocol)
dk.normalize_url("example.com/path/")        # "https://example.com/path/"

dk.is_valid_phone("+44 20 7123 4567")        # True
dk.format_phone_e164("+44 20 7123 4567")     # "+442071234567"

dk.is_valid_iban("NL91ABNA0417164300")       # True
dk.format_iban("NL91ABNA0417164300")         # "NL91 ABNA 0417 1643 00"

dk.is_valid_card_number("4111 1111 1111 1111")  # True (Luhn check)
dk.mask_card_number("4111111111111111")         # "**** **** **** 1111"

dk.is_valid_postal_code("1011 AB", "NL")     # True
dk.supported_countries()                     # ["NL", "PL", "DE", ...]

dk.slugify("Café Müller & Söhne")            # "cafe-muller-sohne"
```

## API

### Email
- `is_valid_email(value: str) -> bool`
- `normalize_email(value: str) -> str | None`

### URL
- `is_valid_url(value: str) -> bool`
- `normalize_url(value: str) -> str | None`

### Phone
- `is_valid_phone(value: str) -> bool` — accepts E.164-style numbers
  (optional leading `+`, 8-15 digits, common separators allowed).
- `format_phone_e164(value: str) -> str | None`

### IBAN
- `is_valid_iban(value: str) -> bool` — validates the mod-97 (ISO 7064)
  checksum and checks length against the issuing country when known.
- `format_iban(value: str) -> str` — groups the IBAN into 4-character
  blocks for display.

### Credit card
- `is_valid_card_number(value: str) -> bool` — Luhn algorithm.
- `mask_card_number(value: str) -> str | None` — keeps only the last 4
  digits visible.

### Postal code
- `is_valid_postal_code(value: str, country_code: str) -> bool` —
  supports NL, PL, DE, FR, IT, AT, CH, GB, ES, FI, US.
- `supported_countries() -> list[str]`

### Slug
- `slugify(value: str) -> str` — lower-cases, strips common Latin
  diacritics, and collapses everything else into hyphens.

## Why not a bigger validation library?

Larger packages cover far more ground and are a better fit if you need
everything they offer. `datacheck-kit` is for the common case: you need
five or six of these checks, you don't want a dependency tree for them,
and you'd rather read the source in a couple of minutes than look up
documentation.

## Testing

```bash
python -m unittest discover -s tests
```

Uses only the standard library — no test framework dependency required.

## License

MIT — see [LICENSE](./LICENSE).
