Skip to content

Repository files navigation

br-utils for Python

PyPI Version PyPI Downloads Python Version Test Status Last Update Date Project License

🚀 Full support for the new alphanumeric CNPJ format.

🌎 Acessar documentação em português

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.

Python Support

Python 3.10 Python 3.11 Python 3.12 Python 3.13 Python 3.14
Passing ✔ Passing ✔ Passing ✔ Passing ✔ Passing ✔

Features

  • ✅ Unified top-level API: One BrUtils instance with cpf and cnpj domain accessors
  • ✅ Bundled domains: cpf-utils and cnpj-utils installed 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 under br_utils.cnpj
  • ✅ Typed error handling: Dedicated exception hierarchies from bundled packages (TypeError / Exception model from cpf-utils and cnpj-utils v2)

Installation

$ pip install br-utilities

This 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.

Import

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_utils

CPF 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.

Quick start

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)  # True

With 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)   # True

Usage

You can work in four equivalent ways:

  1. br_utils — pre-built BrUtils singleton with shared defaults across both CPF and CNPJ domains.
  2. BrUtils — create your own instance with custom default CPF and CNPJ settings.
  3. Domain aggregators — CpfUtils and CnpjUtils directly (same classes used internally by BrUtils).
  4. 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.

br_utils (default instance)

The module-level br_utils is a pre-built BrUtils instance. Use it for quick one-off calls:

  • cpf: Access the CPF utilities (CpfUtils). Use br_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). Use br_utils.cnpj.format(), br_utils.cnpj.generate(), br_utils.cnpj.is_valid() with the same options as in cnpj-utils.

BrUtils (class)

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-built CpfUtils / CnpjUtils instance or a configuration mapping spread into the corresponding utils constructor. Within that mapping, each resource key (formatter, generator, and validator for 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 corresponding cpf or cnpj argument is provided.
  • cpf, cnpj: Properties with getters and setters for the domain utils instances. Setters accept a utils instance, a configuration mapping, or None to 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'),
)

Instance defaults and per-call overrides

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 operations

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.

Formatting (format / cpf_fmt)

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.***.***-**'

Generation (generate / cpf_gen)

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'

Validation (is_valid / cpf_val)

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')                    # True

CNPJ operations

CNPJ methods are accessed via utils.cnpj, CnpjUtils, or the cnpj_*() helpers from br_utils.cnpj. CNPJ uses the v2 API from cnpj-utils.

Formatting (format / cnpj_fmt)

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'

Generation (generate / cnpj_gen)

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'

Validation (is_valid / cnpj_val)

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')         # False

Invalid CNPJ returns False without throwing. Wrong input types throw CnpjValidatorInputTypeError.

Domain aggregators (standalone)

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'

Accessing components

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')  # True

Mixing styles

Use 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')   # True

API

Exports

Package root (br_utils):

  • br_utils: Pre-built BrUtils instance with cpf and cnpj.
  • BrUtils: Class to create an instance with optional default CPF and CNPJ utils settings.
  • CpfUtils, cpf_utils: CPF domain aggregator and its default singleton (from cpf-utils).
  • CnpjUtils, cnpj_utils: CNPJ domain aggregator and its default singleton (from cnpj-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).

Errors & 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: CpfValidatorInputTypeError and 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.

Bundled packages

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.

Contribution & Support

We welcome contributions! Please see our Contributing Guidelines for details. If you find this project helpful, please consider:

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

About

Python utility functions and resources for Brazilian-related data.

Topics

Resources

Code of conduct

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Used by

Contributors

Languages