Skip to main content

nini-datagen

CI wheels PyPI Python Polars Licença: MIT uv Ruff pyright

Dados sintéticos realistas do Brasil, em escala: CPF, CNPJ (inclusive alfanumérico), nomes com a distribuição real do IBGE, endereços do CNEFE, telefones, e-mails, textos e mais. Os geradores são kernels C++ que escrevem direto na memória do Polars (Arrow string_view), sem passar string por string pelo Python.

Guia completo em docs/guia.md, números em docs/desempenho.md, exemplos em examples/ e mudanças no CHANGELOG.

Uso

import nini_datagen as dg

dg.first_name(5, seed=42)  # pl.Series String com nomes na frequência do Censo
dg.integer(1_000_000, low=1, high=6)  # sem seed: semente nova a cada chamada

g = dg.DataGen(seed=42)  # semente, locale e threads fixos
sexo = g.sex(1_000_000)  # "F"/"M", 51,5% de mulheres
nome = g.first_name(1_000_000, sex=sexo)  # nomes coerentes com o sexo de cada linha
idade = g.age(1_000_000)  # pirâmide etária aproximada do Brasil
plano = g.choice(1_000_000, ["bronze", "prata", "ouro"], weights=[6, 3, 1], null_fraction=0.05)

Toda configuração é um modelo Pydantic imutável. Dá para passar o objeto, um dict ou kwargs; nome de parâmetro errado ou valor inválido vira ValidationError:

cfg = dg.IntegerConfig(low=18, high=90, null_fraction=0.1)
g.integer(1000, cfg)
g.integer(1000, cfg, high=65)  # kwargs sobrescrevem campos
g.integer(1000, hihg=65)  # ValidationError: Extra inputs are not permitted
gerador configuração tipo
integer IntegerConfig(low, high, dtype) Int32 / Int64
uniform UniformConfig(low, high, dtype) Float64 / Float32
normal, lognormal NormalConfig(mean, std), LognormalConfig(mean, sigma) Float64
boolean BooleanConfig(p) Boolean
date, datetime DateConfig(start, end), DatetimeConfig(start, end, unit) Date / Datetime
choice ChoiceConfig(values, weights) String, Int64, Float64 ou Boolean
sex SexConfig(p_female, labels) String
age AgeConfig(low, high, weights) Int32
first_name, last_name FirstNameConfig(sex), LastNameConfig() String
full_name FullNameConfig(sex, compound, two_surnames) String
cpf CPFConfig(formatted, unique) String
cnpj CNPJConfig(alphanumeric, branch, formatted, unique) String
pis, voter_id, rg PISConfig(formatted), VoterIDConfig(formatted), RGConfig(formatted) String
cnh, iban, ean13 CNHConfig(), IBANConfig(), EAN13Config() String
license_plate LicensePlateConfig(style) ("mercosul" ou "old") String
credit_card CreditCardConfig(brand, formatted) String
uuid, ipv6, mac, url UUIDConfig(), IPv6Config(), MACConfig(), URLConfig() String
ipv4 IPv4Config(private) String
phone PhoneConfig(style, mobile, uf) String
email, username EmailConfig(domains, domain_weights, style_weights), UsernameConfig(style_weights) String
company, occupation CompanyConfig(), OccupationConfig(zipf) String
vehicle VehicleConfig(year_low, year_high) Struct {brand, model, year}
cep CepConfig(formatted, uf, source) String
address AddressConfig(uf, complement, phone, coords, full, source) Struct {street, number, complement, neighborhood, city, state, cep, ...}
city, state CityConfig(uf, with_state), StateConfig(weighted) String
sentence, paragraph SentenceConfig(theme, templates, slots), ParagraphConfig(..., sentences) String
birthdate BirthdateConfig(on) + coluna age Date
correlated CorrelatedConfig(rho, mean, std, lognormal, center, scale) + coluna other Float64
choice_by ChoiceByConfig(options, default) + coluna by String

Todos aceitam name (nome da coluna) e null_fraction (fração de nulos).

Os documentos saem com dígitos verificadores corretos (não são documentos reais de ninguém), e dg.validators confere textos de qualquer origem:

g.cpf(1_000_000, unique=True)  # sem repetição (até 10^9)
g.cnpj(10, alphanumeric=True, formatted=True)  # "HI.EJT.HBE/0001-69", o formato novo da Receita
dg.validators.cpf("529.982.247-25")  # True

Frases saem de uma gramática com concordância (temas atendimento, saude, entrega, avaliacao, cadastro ou geral), ou de modelos próprios:

g.sentence(3, theme="saude")  # "Reembolso de R$ 964,22 liberado para pagamento."
g.paragraph(3, sentences=(2, 4))
g.sentence(3, templates=["Pedido {cod} enviado {prazo}.", ("Sem observações.", 3)], slots={"cod": ["{d}{d}{d}"]})
g.vehicle(5).struct.unnest()  # colunas brand, model, year

Endereços são reais, do CNEFE do IBGE (Censo 2022): rua, bairro, cidade, UF e CEP existem juntos, sorteados pelo número de endereços. O pacote traz uma base leve (1% dos endereços de cada município, todos os 5.570 municípios); a completa (~55 MB, com a faixa real de números de cada rua) é baixada uma vez e fica em cache:

g.address(5, full=True).struct.unnest()  # street, number, complement, neighborhood, city, state, cep, full
g.cep(5, uf="SP")
dg.datasets.download("cnefe")  # depois disso, source="auto" usa a base completa

Tabelas e LazyFrame

Um Schema descreve a tabela: cada coluna é um gerador com parâmetros, uma referência a outra coluna (dg.ref) para os geradores que dependem de dados, ou uma expressão do Polars. Ele é validado e compilado uma vez:

import polars as pl

schema = dg.Schema(
    {
        "id": ("cpf", {"unique": True, "formatted": True}),
        "sexo": "sex",
        "nome": ("full_name", {"sex": dg.ref("sexo")}),  # nome coerente com o sexo da linha
        "idade": ("age", {"low": 18, "high": 90}),
        "nascimento": ("birthdate", {"age": dg.ref("idade"), "on": "2026-01-01"}),
        "renda": ("correlated", {"other": dg.ref("idade"), "rho": 0.4, "mean": 8, "std": 0.6, "lognormal": True}),
        "area": (
            "choice_by",
            {"by": dg.ref("sexo"), "options": {"F": ["Saúde", "Educação"], "M": ["Engenharia", "Comércio"]}},
        ),
        "cliente": dg.CPFConfig(formatted=True),  # também vale o objeto de configuração
        "meses": pl.col("idade") * 12,
    }
)

df = g.table(1_000_000, schema)  # pl.DataFrame
lf = g.scan(10**9, schema)  # pl.LazyFrame: nada é gerado até o collect
lf.filter(pl.col("idade") >= 60).select("nome", "renda").head(10).collect()  # gera só o necessário

table preenche as colunas bloco a bloco (65.536 linhas), todas as colunas de um bloco de uma vez, com os blocos em paralelo: até colunas baratas, como inteiros e booleanos, entram no paralelismo. scan registra o schema como fonte do Polars: ele recebe as colunas pedidas, o filtro e o limite, e gera em lotes só o que foi pedido. Cada coluna sai igual a g.generate(tipo, n, name=coluna, ...), e scan(n, schema).collect() é igual a table(n, schema). No scan, as expressões são avaliadas lote a lote: use expressões linha a linha (sem mean(), rank() etc.).

Dados sujos, duplicatas e arquivos grandes

schema = dg.Schema(
    {
        "cpf": ("cpf", {"formatted": True, "dirty": {"unmask": 0.3, "whitespace": 0.02}}),
        "nome": ("full_name", {"dirty": {"typo": 0.02, "case": 0.01, "accents": 0.05}}),
        "valor": ("lognormal", {"mean": 5, "sigma": 1, "dirty": {"outliers": 0.001, "sentinel": [(-1, 0.01)]}}),
        "uf": "state",
    }
)
df = g.table(100_000, schema)
com_dups = g.add_duplicates(df, 0.05, dirty={"nome": {"typo": 0.5}})  # row_id e dup_of são o gabarito
g.write_parquet_dataset("saida/", 50_000_000, schema, partition_by="uf", rows_per_file=1_000_000)

Os defeitos seguem as mesmas regras de reprodutibilidade dos dados: cada um tem seu fluxo, e a coluna suja sai igual em table, scan e write_parquet_dataset. Os arquivos gravados juntos são exatamente table(n, schema), para qualquer batch_rows.

Desempenho

Os geradores são kernels C++ que escrevem direto na memória do Polars, em blocos de 65.536 linhas, em paralelo. Na máquina de desenvolvimento (Windows, 16 threads), com 1 thread: CPF ~10 ns/linha, nome ~5, e-mail ~30, frase ~60, endereço completo do CNEFE ~100; a tabela de 20 colunas do benchmark sai a ~300 ns/linha com 1 thread e ~110 com 16 (1 milhão de linhas em ~0,1 s). Detalhes, método e comparação com Faker, Mimesis e dataforge em docs/desempenho.md.

Reprodutibilidade

A partir da 0.2.0, a mesma seed dá sempre a mesma saída, em qualquer sistema e com qualquer número de threads, e n=1_000 dá exatamente as primeiras linhas de n=1_000_000. Cada coluna tem seu próprio fluxo de números aleatórios, identificado pelo nome (name, que por padrão é o tipo do gerador): colunas com nomes diferentes não saem correlacionadas, e a mesma coluna sai sempre igual (g.integer(10) duas vezes dá o mesmo resultado). Os nulos têm fluxo próprio: mudar null_fraction não muda os valores das linhas que continuam preenchidas.

Instalação

pip install nini-datagen      # ou: uv add nini-datagen

Os wheels já trazem a biblioteca C++ compilada (Linux, Windows e macOS; x86-64 e ARM64) e funcionam com qualquer Python ≥ 3.11.

Desenvolvimento

Precisa de uv e de um compilador C++17 (GCC, Clang ou MSVC). CMake e Ninja vêm sozinhos pelo scikit-build-core.

uv sync                                   # cria o ambiente e compila o C++
uv run pytest                             # testes
uv run pytest -m bench -s                 # benchmarks contra o MVP (fora da suíte padrão)
uv run python tools/bench.py              # tabela completa de ns/linha
uv run python tools/samples.py            # amostras de cada gerador
uv run python tools/profile_table.py      # onde vai o tempo da tabela e dos endereços
uv run --isolated --python 3.14 --group bench python tools/compare.py   # contra Faker, Mimesis e dataforge
uv run ruff check . && uv run pyright     # qualidade
uv run python tools/gen_bindings.py       # depois de mudar a assinatura de uma função DG_EXPORT

uv sync / uv run recompilam sozinhos quando um arquivo de cpp/ muda (ou as variáveis abaixo).

  • DG_CLANGCL=1 (Windows): compila com clang-cl em vez do MSVC, como os wheels publicados; bem mais rápido nos kernels. Precisa dos componentes "C++ Clang Compiler for Windows" e "MSBuild support for LLVM (clang-cl) toolset" do Visual Studio Installer.
  • DG_NATIVE=ON: compila para as instruções da sua CPU (-march=native), só para medir; os wheels usam x86-64-v2. O resultado não muda: o código não depende de FMA nem da biblioteca matemática do sistema.

Estrutura

cpp/                     kernels C++ (ABI em C, prefixo dg_), um arquivo por domínio
src/nini_datagen/
  __init__.py, api.py    funções soltas (dg.integer, dg.table...) e exportações
  generator.py           DataGen: semente, locale e threads; um método por gerador
  registry.py            registro dos geradores por nome e montagem das configurações
  config/                modelos Pydantic (um por gerador, mais DirtyConfig)
  providers/             um gerador por tipo: plan() aloca, Job.fill() preenche cada bloco, Job.finish() entrega
  schema/                Schema (colunas, ref, expressões, níveis), table e scan (fonte do Polars)
  transforms/            dados sujos e duplicatas
  io/                    write_parquet_dataset
  datasets/              download com cache (CNEFE completo)
  locales/pt_BR/         dados e regras do Brasil (data/)
  core/                  sementes e fluxos, blocos e threads, views do Arrow, tabelas alias e vocabulários
  _native.py             carrega a biblioteca C++ e confere a versão da ABI
tests/                   pytest; tests/golden/ guarda os gabaritos da v0.2.0
tools/                   bindings, benchmarks, diagnóstico, comparação, amostras, base do CNEFE
docs/, examples/         guia, desempenho e exemplos

Gerador novo: uma configuração em config/, um provider com @registry.register em providers/ e um atalho em generator.py/api.py; o resto (blocos, threads, nulos, semente) vem do roteiro comum em providers/base.py.

Licença

Código: MIT (LICENSE). Dados: fontes abertas do IBGE e do TSE, com créditos em DATA_LICENSES.md.

Metadata

Release files for nini-datagen 0.2.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for nini-datagen 0.2.1
File Size Uploaded Provenance Actions
nini_datagen-0.2.1.tar.gz 75.0 MB With provenance Details for nini_datagen-0.2.1.tar.gz

Built distributions (wheels)

Table of built distributions (wheels) for nini-datagen 0.2.1
File Actions
nini_datagen-0.2.1-py3-none-win_amd64.whl Python 3 none Windows x86-64 Details for nini_datagen-0.2.1-py3-none-win_amd64.whl
nini_datagen-0.2.1-py3-none-musllinux_1_2_x86_64.whl Python 3 none Linux musl 1.2+ x86-64 Details for nini_datagen-0.2.1-py3-none-musllinux_1_2_x86_64.whl
nini_datagen-0.2.1-py3-none-musllinux_1_2_aarch64.whl Python 3 none Linux musl 1.2+ ARM64 Details for nini_datagen-0.2.1-py3-none-musllinux_1_2_aarch64.whl
nini_datagen-0.2.1-py3-none-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl Python 3 none Linux glibc 2.28+ x86-64, Linux glibc 2.24+ x86-64 Details for nini_datagen-0.2.1-py3-none-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
nini_datagen-0.2.1-py3-none-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl Python 3 none Linux glibc 2.28+ ARM64, Linux glibc 2.24+ ARM64 Details for nini_datagen-0.2.1-py3-none-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl
nini_datagen-0.2.1-py3-none-macosx_11_0_x86_64.whl Python 3 none macOS 11.0+ x86-64 Details for nini_datagen-0.2.1-py3-none-macosx_11_0_x86_64.whl
nini_datagen-0.2.1-py3-none-macosx_11_0_arm64.whl Python 3 none macOS 11.0+ ARM64 Details for nini_datagen-0.2.1-py3-none-macosx_11_0_arm64.whl

Total release size: 81.3 MB

Release files / nini_datagen-0.2.1.tar.gz

Download URL nini_datagen-0.2.1.tar.gz
Size 75.0 MB
Tags Source
SHA-256 checksum
How to use checksums
517fbe137ac4c8e7ab8c09f4382a59694e4db3dedbeb2fe34130af6c82d507c7
BLAKE2b-256 checksum
How to use checksums
68cc7f9d5b9db5af7f87abafb8f590c1237e40fbb54fc6420c7ef5d8b3d3f9c6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 1, 2026.

Transparency log

Release files / nini_datagen-0.2.1-py3-none-win_amd64.whl

Download URL nini_datagen-0.2.1-py3-none-win_amd64.whl
Size 658.0 kB
Tags Python 3 Windows x86-64
SHA-256 checksum
How to use checksums
e87b0e4653b7221f94741a0498c11cbf438e2d2a63822f26a352c1d0298ac8f4
BLAKE2b-256 checksum
How to use checksums
4c34116247d1204b181ecb0433c6f61fad718b47d5a3c6b1fa3a2d330cd389f3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 1, 2026.

Transparency log

Release files / nini_datagen-0.2.1-py3-none-musllinux_1_2_x86_64.whl

Download URL nini_datagen-0.2.1-py3-none-musllinux_1_2_x86_64.whl
Size 1.7 MB
Tags Linux musl 1.2+ x86-64 Python 3
SHA-256 checksum
How to use checksums
63d7d463444c6610ddf80dfc90976cecae8a6f140d6209746476f763a392f80c
BLAKE2b-256 checksum
How to use checksums
8e657a4640006d4d1a173a268f0b2b14f9c02aaab04a16f8d69a12cbc7729d65
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 1, 2026.

Transparency log

Release files / nini_datagen-0.2.1-py3-none-musllinux_1_2_aarch64.whl

Download URL nini_datagen-0.2.1-py3-none-musllinux_1_2_aarch64.whl
Size 1.6 MB
Tags Linux musl 1.2+ ARM64 Python 3
SHA-256 checksum
How to use checksums
2e3fa8a9ac7f5c3b5b0d4258326ea2f23ee1d40f03cb5b3db6cf7bd2eca1fcbd
BLAKE2b-256 checksum
How to use checksums
bfde8522555d6a67c541897f1023fcdc37f2ebb72306a12d0359e976d6715128
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 1, 2026.

Transparency log

Release files / nini_datagen-0.2.1-py3-none-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl

Download URL nini_datagen-0.2.1-py3-none-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
Size 621.3 kB
Tags Linux glibc 2.24+ x86-64 Linux glibc 2.28+ x86-64 Python 3
SHA-256 checksum
How to use checksums
7fc8f4b99c1f27450431bf005a4593addf0484385e803a682408c0813759cc79
BLAKE2b-256 checksum
How to use checksums
9016c244b59b33cb1128cfcbd4d226a45ed620edb2fce22dffc9dc148d6ba11d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 1, 2026.

Transparency log

Release files / nini_datagen-0.2.1-py3-none-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl

Download URL nini_datagen-0.2.1-py3-none-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl
Size 621.1 kB
Tags Linux glibc 2.24+ ARM64 Linux glibc 2.28+ ARM64 Python 3
SHA-256 checksum
How to use checksums
56bd353a6b350cd562a2d46588801cf98c18098502ece175c3e9a7a65dae0cac
BLAKE2b-256 checksum
How to use checksums
944d70a79032bda0e2d3a03c309875a61ee813a5dc31623aeb3b045b22fa9232
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 1, 2026.

Transparency log

Release files / nini_datagen-0.2.1-py3-none-macosx_11_0_x86_64.whl

Download URL nini_datagen-0.2.1-py3-none-macosx_11_0_x86_64.whl
Size 603.6 kB
Tags Python 3 macOS 11.0+ x86-64
SHA-256 checksum
How to use checksums
79d23f29fd0ca7443bc2c4dace611ca3487832d6ecd03a96985722203245ab8c
BLAKE2b-256 checksum
How to use checksums
18c3140c775eb6a4d888676803a1fc9d81299d4d393b08de713f5028454de1ea
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 1, 2026.

Transparency log

Release files / nini_datagen-0.2.1-py3-none-macosx_11_0_arm64.whl

Download URL nini_datagen-0.2.1-py3-none-macosx_11_0_arm64.whl
Size 601.8 kB
Tags Python 3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
4f9d05203c36f9fcb1d2c1343725a4b3bf421536684ef6cacdb2c2a8e5fecb8f
BLAKE2b-256 checksum
How to use checksums
6ad338999e534dc517f27987b3811c7b0ef6f17603dc77179cdef84bb84087d3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 1, 2026.

Transparency log

Security for nini-datagen 0.2.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 8 files in this release have been uploaded with provenance metadata.

Select from 8 files

Attestation for nini_datagen-0.2.1.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 1, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page