Utility to validate CNPJ (Brazilian Business Tax ID)
Project description
🚀 Full support for the new alphanumeric CNPJ format.
A Python utility to validate CNPJ (Brazilian Business Tax ID).
Python Support
| Passing ✔ | Passing ✔ | Passing ✔ | Passing ✔ | Passing ✔ |
Features
- ✅ Alphanumeric CNPJ: Validates 14-character CNPJ in numeric or alphanumeric format
- ✅ Flexible input: Accepts
stror a sequence ofstr; sequence elements are concatenated in order - ✅ Format agnostic: Strips non-alphanumeric characters (or non-digits when
typeisnumeric) and optionally uppercases before validation - ✅ Optional case sensitivity: When
case_sensitiveisFalse, lowercase letters are accepted for alphanumeric CNPJ - ✅ Per-call override model: Instance defaults can be overridden for one
is_valid()call only - ✅ Typed option validation: Dedicated
TypeError/Exceptionsubclasses for invalid option or input usage - ✅ Minimal dependencies:
cnpj-dvfor check-digit calculation andlacus.utilsfor type descriptions in error messages - ✅ Dual API style: Object-oriented (
CnpjValidator) and functional (cnpj_val())
Installation
$ pip install cnpj-val
Import
from cnpj_val import CnpjValidator, CnpjValidatorOptions, cnpj_val
Quick start
from cnpj_val import CnpjValidator
validator = CnpjValidator()
validator.is_valid('98765432000198') # True
validator.is_valid('98.765.432/0001-98') # True
validator.is_valid('98765432000199') # False
validator.is_valid('1QB5UKALPYFP59') # True (alphanumeric)
validator.is_valid('1QB5UKALpyfp59') # False (default is case-sensitive)
validator.is_valid('1QB5UKALpyfp59', case_sensitive=False) # True
validator.is_valid('96206256120884') # True (numeric)
validator.is_valid('1QB5UKALPYFP59', type='numeric') # False (letters stripped → length ≠ 14)
Functional helper:
from cnpj_val import cnpj_val
cnpj_val('98765432000198') # True
cnpj_val('98.765.432/0001-98') # True
cnpj_val('98765432000199') # False
Usage
The main entry points are the class CnpjValidator, the options class CnpjValidatorOptions, and the helper cnpj_val().
CnpjValidator
-
__init__: Optional default validation options. The first parameter may beNone, a mapping of option keys, or aCnpjValidatorOptionsinstance (that exact instance is stored; mutating it later affects subsequentis_valid()calls that do not pass per-call options). You may also pass option fields as keyword-only arguments (case_sensitive,type). Example:CnpjValidator(type='numeric', case_sensitive=False). -
options: Property returning the instance’sCnpjValidatorOptions(same object used internally). -
is_valid(cnpj_input, options=None, *, case_sensitive=None, type=None): Validates a CNPJ value.Input is normalized to a string (sequences of strings are concatenated). When
case_sensitiveisFalse, the string is uppercased before sanitization. Characters are stripped according totype. If the sanitized length is not exactly 14, the last two characters are not digits, or check digits do not match (CnpjCheckDigitsfromcnpj-dv), the method returnsFalse— no exception is thrown for validation failure.If the input is not a
stror a sequence ofstr,CnpjValidatorInputTypeErroris raised.Per-call options are merged over the instance defaults for that call only (instance defaults are unchanged). Pass a
CnpjValidatorOptionsinstance or a mapping as the second argument, in addition to keyword-only arguments; when both are provided, theoptionsargument wins.
from cnpj_val import CnpjValidator
validator = CnpjValidator(type='numeric')
validator.is_valid('98.765.432/0001-98') # True
validator.is_valid('1QB5UKALPYFP59') # False (letters stripped → length ≠ 14)
validator.is_valid('1QB5UKALpyfp59', type='alphanumeric', case_sensitive=False) # True
Default options on the instance; per-call overrides:
validator = CnpjValidator(case_sensitive=False)
validator.is_valid('1qb5ukalpyfp59') # True (instance defaults)
validator.is_valid('1qb5ukalpyfp59', case_sensitive=True) # this call only: False
validator.is_valid('1qb5ukalpyfp59') # True again
CnpjValidatorOptions
Holds validator settings (case_sensitive, type). Construct with an optional options mapping or CnpjValidatorOptions instance, optional extra override objects (merged in order), and/or keyword-only arguments. Exposes properties: case_sensitive, type.
all: Returns an immutable shallow snapshot of all current options (MappingProxyType).set(options): Updates multiple fields at once; returnsself. Accepts a mapping or anotherCnpjValidatorOptionsinstance.
from cnpj_val import CnpjValidatorOptions
options = CnpjValidatorOptions(case_sensitive=False, type='numeric')
options.case_sensitive # False
options.type # 'numeric'
options.set({'type': 'alphanumeric'}) # merge and return self
options.all # immutable snapshot of current options
Functional helper
cnpj_val() builds a new CnpjValidator from the same constructor parameters and calls is_valid(cnpj_input) once. Use keyword-only arguments, a mapping, or a CnpjValidatorOptions instance for options:
from cnpj_val import cnpj_val
cnpj_val('98765432000198') # True
cnpj_val('1QB5UKALpyfp59', case_sensitive=False) # True
cnpj_val('1QB5UKALPYFP59', type='numeric') # False
cnpj_val('1QB5UKALpyfp59', { # mapping form
'type': 'alphanumeric',
'case_sensitive': False,
}) # True
Input formats
String: Raw digits and/or letters, or formatted CNPJ (e.g. 98.765.432/0001-98, 1Q.B5U.KAL/PYFP-59). Characters are stripped according to type; when case_sensitive is False, letters are uppercased before alphanumeric validation.
Sequence of strings: Each element must be a str; values are concatenated (e.g. per digit, grouped segments, or mixed with punctuation). Non-string elements raise CnpjValidatorInputTypeError.
from cnpj_val import cnpj_val
cnpj_val(['1', 'Q', 'B', '5', 'U', 'K', 'A', 'L', 'P', 'Y', 'F', 'P', '5', '9']) # True
cnpj_val(['1Q.B5U', 'KAL', 'PYFP-59']) # True
Validation options
| Parameter | Type | Default | Description |
|---|---|---|---|
type |
'alphanumeric' | 'numeric' | None |
'alphanumeric' |
Character set after sanitization: alphanumeric (0–9, A–Z, a–z) or numeric-only (0–9) |
case_sensitive |
bool | None |
True |
When False, lowercase letters are uppercased before alphanumeric validation |
Invalid CNPJ (wrong length after sanitization, invalid check digits, ineligible base/branch 00000000 / 0000, repeated digits, non-numeric verifier digits) returns False — no exception is thrown for validation failure.
Example with all options:
from cnpj_val import cnpj_val
cnpj_val(
'1QB5UKALpyfp59',
type='alphanumeric',
case_sensitive=False,
)
Errors & exceptions
This package uses TypeError for invalid option/input types and Exception for invalid option values. Validation failures return False.
- Wrong input type (not
stror a sequence ofstr):CnpjValidatorInputTypeError— extendsCnpjValidatorTypeError(extends built-inTypeError). - Invalid option types when constructing or merging options:
CnpjValidatorOptionsTypeError. - Invalid
typevalue (notalphanumeric/numeric):CnpjValidatorOptionTypeInvalidException— extendsCnpjValidatorException.
from cnpj_val import (
CnpjValidator,
CnpjValidatorException,
CnpjValidatorInputTypeError,
CnpjValidatorOptionsTypeError,
CnpjValidatorOptionTypeInvalidException,
cnpj_val,
)
# Input type (e.g. integer not allowed)
try:
cnpj_val(12345678000198)
except CnpjValidatorInputTypeError as e:
print(e) # CNPJ input must be of type string or string[]. Got integer number.
# Option type (e.g. `type` must be string)
try:
cnpj_val('98765432000198', type=123)
except CnpjValidatorOptionsTypeError as e:
print(e.option_name, e.expected_type, e.actual_type)
# Invalid type value
try:
cnpj_val('98765432000198', type='invalid')
except CnpjValidatorOptionTypeInvalidException as e:
print(e.expected_values, e.actual_input)
# Any exception from the package
try:
CnpjValidator(type='invalid')
except CnpjValidatorException as e:
pass # handle
API
Exports
All public symbols are available from the cnpj_val package:
cnpj_val:(cnpj_input: CnpjInput, options=None, *, case_sensitive=None, type=None) -> bool— convenience helper.CnpjValidator: Class to validate CNPJ with optional default options; acceptsCnpjInputinis_valid().CnpjValidatorOptions: Class holding options; supports merge via constructor,set(), and keyword-only arguments.CNPJ_LENGTH:14(constant).CnpjInput: Type alias —str | Sequence[str].CnpjType: Type alias —Literal["alphanumeric", "numeric"].CnpjValidatorOptionsInput,CnpjValidatorOptionsType: Options typing helpers.- Exceptions:
CnpjValidatorTypeError,CnpjValidatorInputTypeError,CnpjValidatorOptionsTypeError,CnpjValidatorException,CnpjValidatorOptionTypeInvalidException.
Other available resources
CnpjValidatorOptions.DEFAULT_CASE_SENSITIVE:True.CnpjValidatorOptions.DEFAULT_TYPE:'alphanumeric'.
Contribution & Support
We welcome contributions! Please see our Contributing Guidelines for details. If you find this project helpful, please consider:
- ⭐ Starring the repository
- 🤝 Contributing to the codebase
- 💡 Suggesting new features
- 🐛 Reporting bugs
License
This project is licensed under the MIT License — see the LICENSE file for details.
Changelog
See CHANGELOG for a list of changes and version history.
Made with ❤️ by Lacus Solutions
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file cnpj_val-2.0.0.tar.gz.
File metadata
- Download URL: cnpj_val-2.0.0.tar.gz
- Upload date:
- Size: 15.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b8b2848500aa28b075598c604e067e4258afb6414f90850d8079b2768be1a610
|
|
| MD5 |
9aaf75d37bbe1db4d9b4235e25a2987c
|
|
| BLAKE2b-256 |
cdd382702be1548d4e9307db4d0f5d288b5504bfe48c0a6247bb66074d97ff6d
|
File details
Details for the file cnpj_val-2.0.0-py3-none-any.whl.
File metadata
- Download URL: cnpj_val-2.0.0-py3-none-any.whl
- Upload date:
- Size: 13.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b361a85199358513e08f6a9950628b105cabfffc8488e589a3976a4ee79ddd35
|
|
| MD5 |
9132f9a3784506c8625c912d581089ce
|
|
| BLAKE2b-256 |
9bde79c31b376f8b0be4269e082c49780cc1a8728bb8afb85f682e6a8357ebc5
|