🚀 Full support for the new alphanumeric CNPJ format.
A Python toolkit to handle the main operations with Brazilian-related data: CPF (Individual's Taxpayer ID) and CNPJ (Business Tax ID). It provides a top-level BrUtils wrapper around cpf-utils and cnpj-utils, exposing all bundled resources under a unified import path.
| Passing ✔ | Passing ✔ | Passing ✔ | Passing ✔ | Passing ✔ |
- ✅ Unified top-level API: One
BrUtilsinstance withcpfandcnpjdomain accessors - ✅ Bundled domains:
cpf-utilsandcnpj-utilsinstalled together - ✅ Alphanumeric CNPJ: Full support for the new alphanumeric CNPJ format (introduced in 2026)
- ✅ Configurable defaults: Set formatter, generator, and (for CNPJ) validator options on each domain instance
- ✅ Per-call overrides: Override any component option for a single method call
- ✅ Dual API style: Top-level façade (
BrUtils), domain aggregators (CpfUtils,CnpjUtils), standalone components, and functional helpers - ✅ Shared submodules: CPF symbols under
br_utils.cpf; CNPJ symbols underbr_utils.cnpj - ✅ Typed error handling: Dedicated exception hierarchies from bundled packages (
TypeError/Exceptionmodel from cpf-utils and cnpj-utils v2)
$ pip install br-utilitiesThis installs br-utilities together with cpf-utils and cnpj-utils (which in turn pull in the CPF and CNPJ component packages). You do not need separate pip install calls for the domain packages when using br-utilities.
Pick the API that fits your use case.
Top-level façade and domain singletons:
from br_utils import BrUtils, br_utils, CpfUtils, CnpjUtils, cpf_utils, cnpj_utilsCPF components and helpers (br_utils.cpf):
from br_utils.cpf import (
CpfFormatter,
CpfFormatterOptions,
CpfGenerator,
CpfGeneratorOptions,
CpfValidator,
cpf_fmt,
cpf_gen,
cpf_val,
)CNPJ components and helpers (br_utils.cnpj):
from br_utils.cnpj import (
CnpjFormatter,
CnpjFormatterOptions,
CnpjGenerator,
CnpjGeneratorOptions,
CnpjValidator,
CnpjValidatorOptions,
cnpj_fmt,
cnpj_gen,
cnpj_val,
)Functional helpers (cpf_fmt, cnpj_fmt, and related symbols) are not re-exported from the package root — import them from br_utils.cpf or br_utils.cnpj.
With br_utils (default singleton):
from br_utils import br_utils
cpf = '11144477735'
cnpj = '03603568000195'
br_utils.cpf.format(cpf) # '111.444.777-35'
br_utils.cpf.is_valid(cpf) # True
br_utils.cpf.generate() # e.g. '11508890048'
br_utils.cnpj.format(cnpj) # '03.603.568/0001-95'
br_utils.cnpj.is_valid(cnpj) # True
br_utils.cnpj.generate() # e.g. '1GJTR3J3XSSA96'With domain aggregators:
from br_utils import CpfUtils, CnpjUtils
cpf = '11144477735'
cnpj = '03603568000195'
CpfUtils().format(cpf) # '111.444.777-35'
CnpjUtils().format(cnpj) # '03.603.568/0001-95'
CpfUtils().is_valid(cpf) # True
CnpjUtils().is_valid(cnpj) # TrueWith functional helpers:
from br_utils.cpf import cpf_fmt, cpf_val
from br_utils.cnpj import cnpj_fmt, cnpj_val
cpf = '11144477735'
cnpj = '03603568000195'
cpf_fmt(cpf) # '111.444.777-35'
cpf_val(cpf) # True
cnpj_fmt(cnpj) # '03.603.568/0001-95'
cnpj_val(cnpj) # TrueYou can work in four equivalent ways:
br_utils— pre-builtBrUtilssingleton with shared defaults across both CPF and CNPJ domains.BrUtils— create your own instance with custom default CPF and CNPJ settings.- Domain aggregators —
CpfUtilsandCnpjUtilsdirectly (same classes used internally byBrUtils). - Component classes and functional helpers —
CpfFormatter,CnpjGenerator,cpf_fmt(),cnpj_gen(), and related symbols.
All approaches expose the same options and behavior within each domain. For full option tables and component-specific details, see the README of each bundled package.
The module-level br_utils is a pre-built BrUtils instance. Use it for quick one-off calls:
cpf: Access the CPF utilities (CpfUtils). Usebr_utils.cpf.format(),br_utils.cpf.generate(),br_utils.cpf.is_valid()with the same options as in cpf-utils.cnpj: Access the CNPJ utilities (CnpjUtils). Usebr_utils.cnpj.format(),br_utils.cnpj.generate(),br_utils.cnpj.is_valid()with the same options as in cnpj-utils.
For custom default CPF or CNPJ utils, create your own instance:
from br_utils import BrUtils
utils = BrUtils(
cpf={
'formatter': {'hidden': True, 'hidden_key': '#'},
'generator': {'format': True},
},
cnpj={
'formatter': {'hidden': True},
'generator': {'type': 'numeric', 'format': True},
'validator': {'type': 'numeric'},
},
)
utils.cpf.format('11144477735') # '111.###.###-##'
utils.cpf.generate() # e.g. '005.265.352-88'
utils.cnpj.format('03603568000195') # '03.603.***/****-**'
utils.cnpj.generate() # e.g. '73.008.535/0005-06'
# Access internal domain instances
utils.cpf # CpfUtils
utils.cnpj # CnpjUtils__init__(…): All arguments are keyword-only and optional.cpf/cnpj: A pre-builtCpfUtils/CnpjUtilsinstance or a configuration mapping spread into the corresponding utils constructor. Within that mapping, each resource key (formatter,generator, andvalidatorfor CNPJ) accepts either an options object or a mapping of option values.cpf_formatter,cpf_generator,cnpj_formatter,cnpj_generator,cnpj_validator: Flat convenience arguments when only individual components need customization. They are ignored when the correspondingcpforcnpjargument is provided.
cpf,cnpj: Properties with getters and setters for the domain utils instances. Setters accept a utils instance, a configuration mapping, orNoneto reset to defaults (replaces the entire instance; does not merge).
Flat constructor options (alternative to nested cpf / cnpj mappings):
from br_utils import BrUtils
from br_utils.cpf import CpfFormatterOptions, CpfGeneratorOptions
from br_utils.cnpj import CnpjFormatterOptions, CnpjGeneratorOptions, CnpjValidatorOptions
utils = BrUtils(
cpf_formatter=CpfFormatterOptions(hidden=True, hidden_key='#'),
cpf_generator=CpfGeneratorOptions(format=True),
cnpj_formatter=CnpjFormatterOptions(hidden=True, hidden_key='#'),
cnpj_generator=CnpjGeneratorOptions(format=True, type='numeric'),
cnpj_validator=CnpjValidatorOptions(type='numeric'),
)from br_utils import BrUtils
utils = BrUtils(
cpf={
'formatter': {'hidden': True, 'hidden_key': '#'},
'generator': {'format': True},
},
cnpj={
'formatter': {'hidden': True, 'hidden_key': '#'},
'generator': {'format': True},
'validator': {'type': 'numeric'},
},
)
cpf = '11144477735'
cnpj = '03603568000195'
utils.cpf.format(cpf) # '111.###.###-##'
utils.cpf.format(cpf, hidden=False) # '111.444.777-35'
utils.cpf.generate(format=False) # e.g. '58450042259'
utils.cnpj.format(cnpj) # '03.603.###/####-##'
utils.cnpj.format(cnpj, hidden=False) # '03.603.568/0001-95'
utils.cnpj.is_valid('1QB5UKALPYFP59') # False
utils.cnpj.is_valid( # True
'1QB5UKALPYFP59',
type='alphanumeric',
)Passing a CnpjFormatterOptions, CnpjGeneratorOptions, or CnpjValidatorOptions instance to the BrUtils constructor stores that object by reference — mutating it later affects subsequent calls with no per-call override.
CPF methods are accessed via utils.cpf, CpfUtils, or the cpf_*() helpers from br_utils.cpf. CPF uses the v2 API from cpf-utils: str or sequence input for format() / is_valid(), mapping or keyword overrides per call, and structured exceptions.
| Option | Type | Default | Description |
|---|---|---|---|
hidden |
bool |
False |
When True, mask digits in hidden_start–hidden_end with hidden_key |
hidden_key |
str |
'*' |
Character(s) used to replace masked digits |
hidden_start |
int |
3 |
Start index (0–10, inclusive) of the range to hide |
hidden_end |
int |
10 |
End index (0–10, inclusive) of the range to hide |
dot_key |
str |
'.' |
Dot delimiter (e.g. in 123.456.789) |
dash_key |
str |
'-' |
Dash delimiter (e.g. before check digits …-09) |
escape |
bool |
False |
When True, escape HTML special characters in the result |
encode |
bool |
False |
When True, URL-encode the result (similar to JavaScript encodeURIComponent) |
on_fail |
Callable |
returns '' |
Callback when sanitized input length ≠ 11; return value is used as result |
Default on_fail returns an empty string. Invalid length does not throw from format().
from br_utils import br_utils
from br_utils.cpf import cpf_fmt
cpf = '11144477735'
br_utils.cpf.format(cpf) # '111.444.777-35'
br_utils.cpf.format(cpf, hidden=True, hidden_key='#') # '111.###.###-##'
br_utils.cpf.format(cpf, dot_key='', dash_key='_') # '111444777_35'
cpf_fmt(cpf, hidden=True) # '111.***.***-**'| Option | Type | Default | Description |
|---|---|---|---|
format |
bool |
False |
When True, return the generated CPF in standard format (000.000.000-00) |
prefix |
str |
'' |
Partial start string (0–9 digits). Non-digits are stripped; missing characters are generated and check digits computed. Prefixes longer than 9 digits are truncated silently. |
Prefix rules: the base (first 9 digits) cannot be all zeros; 9 repeated digits (e.g. 999999999) are not allowed.
from br_utils import br_utils
from br_utils.cpf import cpf_gen
br_utils.cpf.generate() # e.g. '11508890048'
br_utils.cpf.generate(format=True) # e.g. '661.134.831-00'
br_utils.cpf.generate(prefix='123456789') # '12345678909'
cpf_gen(prefix='123456789', format=True) # '123.456.789-09'Accepts formatted or unformatted CPF strings (or a sequence of strings). Returns True or False without throwing for invalid CPF. No validator options exist.
from br_utils import br_utils
from br_utils.cpf import cpf_val
br_utils.cpf.is_valid('11144477735') # True
br_utils.cpf.is_valid('111.444.777-35') # True
br_utils.cpf.is_valid('11144477736') # False
cpf_val('11144477735') # TrueCNPJ methods are accessed via utils.cnpj, CnpjUtils, or the cnpj_*() helpers from br_utils.cnpj. CNPJ uses the v2 API from cnpj-utils.
| Option | Type | Default | Description |
|---|---|---|---|
hidden |
bool |
False |
When True, mask characters in hidden_start–hidden_end with hidden_key |
hidden_key |
str |
'*' |
Character(s) used to replace masked characters |
hidden_start |
int |
5 |
Start index (0–13, inclusive) of the range to hide |
hidden_end |
int |
13 |
End index (0–13, inclusive) of the range to hide |
dot_key |
str |
'.' |
Dot delimiter (e.g. in 12.345.678) |
slash_key |
str |
'/' |
Slash delimiter (e.g. before branch …/0001-90) |
dash_key |
str |
'-' |
Dash delimiter (e.g. before check digits …-90) |
escape |
bool |
False |
When True, escape HTML special characters in the result |
encode |
bool |
False |
When True, URL-encode the result (similar to JavaScript encodeURIComponent) |
on_fail |
Callable |
returns '' |
Callback when sanitized input length ≠ 14; return value is used as result |
Default on_fail returns an empty string. Wrong input types throw CnpjFormatterInputTypeError.
from br_utils import br_utils
from br_utils.cnpj import cnpj_fmt
cnpj = '03603568000195'
br_utils.cnpj.format(cnpj) # '03.603.568/0001-95'
br_utils.cnpj.format('12ABC34500DE99') # '12.ABC.345/00DE-99'
br_utils.cnpj.format( # '03.603.###/####-##'
cnpj,
hidden=True,
hidden_key='#',
)
br_utils.cnpj.format( # '03603568|0001_95'
cnpj,
dot_key='',
slash_key='|',
dash_key='_',
)
cnpj_fmt(cnpj) # '03.603.568/0001-95'| Option | Type | Default | Description |
|---|---|---|---|
format |
bool |
False |
When True, return the generated CNPJ in standard format (00.000.000/0000-00) |
prefix |
str |
'' |
Partial start string (0–12 alphanumeric chars). Missing characters are generated and check digits computed. |
type |
'numeric' | 'alphabetic' | 'alphanumeric' |
'alphanumeric' |
Character set for the randomly generated part. Check digits are always numeric. |
Prefix rules: base ID (first 8 chars) and branch ID (chars 9–12) cannot be all zeros; 12 repeated digits (e.g. 111111111111) are also not allowed.
from br_utils import br_utils
from br_utils.cnpj import cnpj_gen
br_utils.cnpj.generate() # e.g. '1GJTR3J3XSSA96'
br_utils.cnpj.generate(format=True) # e.g. 'V1.J0V.8WE/DVZ7-50'
br_utils.cnpj.generate( # e.g. '12345678855883'
prefix='12345678',
type='numeric',
)
cnpj_gen(type='numeric') # e.g. '65453043000178'| Option | Type | Default | Description |
|---|---|---|---|
case_sensitive |
bool |
True |
When False, lowercase letters are accepted for alphanumeric CNPJ (input is uppercased before validation). |
type |
'numeric' | 'alphanumeric' |
'alphanumeric' |
'numeric': only digits (0–9); 'alphanumeric': digits and letters (0–9, A–Z). |
from br_utils import br_utils
from br_utils.cnpj import cnpj_val
br_utils.cnpj.is_valid('98765432000198') # True
br_utils.cnpj.is_valid('98765432000199') # False
br_utils.cnpj.is_valid('1QB5UKALPYFP59') # True
br_utils.cnpj.is_valid('1QB5UKALpyfp59') # False
br_utils.cnpj.is_valid( # True
'1QB5UKALpyfp59',
case_sensitive=False,
)
br_utils.cnpj.is_valid( # False
'1QB5UKALPYFP59',
type='numeric',
)
cnpj_val('98765432000198') # True
cnpj_val('1QB5UKALpyfp59', case_sensitive=False) # True
cnpj_val('1QB5UKALPYFP59', type='numeric') # FalseInvalid CNPJ returns False without throwing. Wrong input types throw CnpjValidatorInputTypeError.
Use CpfUtils or CnpjUtils directly when you only need one domain:
from br_utils import CpfUtils, CnpjUtils
cpf_utils = CpfUtils(
formatter={'hidden': True},
generator={'format': True},
)
cnpj_utils = CnpjUtils(
formatter={'hidden': True},
generator={'format': True},
validator={'type': 'numeric'},
)
cpf_utils.format('11144477735') # '111.***.***-**'
cnpj_utils.format('03603568000195') # '03.603.***/****-**'The module-level cpf_utils and cnpj_utils singletons (re-exported from the dependencies) are also available from the package root:
from br_utils import cpf_utils, cnpj_utils
cpf_utils.format('11144477735') # '111.444.777-35'
cnpj_utils.format('03603568000195') # '03.603.568/0001-95'Each domain aggregator exposes its internal formatter, generator, and validator:
from br_utils import BrUtils
utils = BrUtils()
utils.cpf.formatter.format('11144477735', hidden=True) # '111.***.***-**'
utils.cpf.generator.generate(format=True) # e.g. '545.507.690-68'
utils.cpf.validator.is_valid('11144477735') # True
utils.cnpj.formatter.format('12ABC34500DE99') # '12.ABC.345/00DE-99'
utils.cnpj.generator.generate(format=True) # e.g. '8O.BE5.2KL/UI0Y-06'
utils.cnpj.validator.is_valid('03603568000195') # TrueUse BrUtils where a shared configuration helps, and standalone components or helpers elsewhere — they are the same underlying classes:
from br_utils import BrUtils
from br_utils.cnpj import CnpjFormatter
from br_utils.cpf import cpf_fmt
from br_utils.cnpj import cnpj_val
utils = BrUtils(cnpj={'validator': {'type': 'numeric'}})
# Via façade
utils.cpf.format('11144477735') # '111.444.777-35'
# Via component returned by the façade
utils.cnpj.formatter.format('12ABC34500DE99') # '12.ABC.345/00DE-99'
# Via a separate component instance
CnpjFormatter().format('03603568000195') # '03.603.568/0001-95'
# Via functional helpers
cpf_fmt('11144477735') # '111.444.777-35'
cnpj_val('98.765.432/0001-98') # TruePackage root (br_utils):
br_utils: Pre-builtBrUtilsinstance withcpfandcnpj.BrUtils: Class to create an instance with optional default CPF and CNPJ utils settings.CpfUtils,cpf_utils: CPF domain aggregator and its default singleton (fromcpf-utils).CnpjUtils,cnpj_utils: CNPJ domain aggregator and its default singleton (fromcnpj-utils).
br_utils.cpf — all exports from cpf-utils (e.g. cpf_fmt, cpf_gen, cpf_val, formatter/generator/validator classes, options, exceptions).
br_utils.cnpj — all exports from cnpj-utils (e.g. cnpj_fmt, cnpj_gen, cnpj_val, formatter/generator/validator classes, options, exceptions).
BrUtils does not define its own exception types; it propagates errors from the bundled packages:
- CPF formatting:
CpfFormatterInputTypeError,CpfFormatterOptionsTypeError,CpfFormatterOptionsHiddenRangeInvalidException,CpfFormatterOptionsForbiddenKeyCharacterException, and related classes. - CPF generation:
CpfGeneratorOptionsTypeError,CpfGeneratorOptionPrefixInvalidException, and related classes. - CPF validation:
CpfValidatorInputTypeErrorand related classes. - CNPJ formatting:
CnpjFormatterInputTypeError,CnpjFormatterOptionsTypeError,CnpjFormatterOptionsHiddenRangeInvalidException,CnpjFormatterOptionsForbiddenKeyCharacterException, and related classes. - CNPJ generation:
CnpjGeneratorOptionsTypeError,CnpjGeneratorOptionPrefixInvalidException,CnpjGeneratorOptionTypeInvalidException, and related classes. - CNPJ validation:
CnpjValidatorInputTypeError,CnpjValidatorOptionsTypeError,CnpjValidatorOptionTypeInvalidException, and related classes.
Invalid option types are TypeError subclasses; invalid option values are Exception subclasses. CPF and CNPJ validation failures return False. Formatting length failures are handled by on_fail (default: return '').
from br_utils import BrUtils
from br_utils.cnpj import CnpjFormatterInputTypeError, CnpjValidatorInputTypeError
br_utils = BrUtils()
try:
br_utils.cnpj.format(12345) # raises CnpjFormatterInputTypeError
except CnpjFormatterInputTypeError as e:
print(e)
try:
br_utils.cnpj.is_valid(12345678000198) # raises CnpjValidatorInputTypeError
except CnpjValidatorInputTypeError as e:
print(e)
cpf_out = br_utils.cpf.format( # 'invalid'
'short',
on_fail=lambda value, exception=None: 'invalid',
)
cnpj_out = br_utils.cnpj.format( # 'invalid'
'short',
on_fail=lambda value, exception=None: 'invalid',
)For exhaustive exception lists and edge-case behavior, see each bundled package README.
| Package | Main resources | README |
|---|---|---|
cpf-utils |
CpfUtils, CpfFormatter, CpfGenerator, CpfValidator, cpf_fmt(), cpf_gen(), cpf_val() |
docs |
cnpj-utils |
CnpjUtils, CnpjFormatter, CnpjGenerator, CnpjValidator, cnpj_fmt(), cnpj_gen(), cnpj_val() |
docs |
All CPF symbols are available under br_utils.cpf; all CNPJ symbols under br_utils.cnpj. Interactive demos: CPF and CNPJ.
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
This project is licensed under the MIT License - see the LICENSE file for details.
See CHANGELOG for a list of changes and version history.
Made with ❤️ by Lacus Solutions
