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

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.0
File Size Uploaded Provenance Actions
nini_datagen-0.2.0.tar.gz 74.9 MB With provenance Details for nini_datagen-0.2.0.tar.gz

Built distributions (wheels)

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

Total release size: 81.3 MB

Release files / nini_datagen-0.2.0.tar.gz

Download URL nini_datagen-0.2.0.tar.gz
Size 74.9 MB
Tags Source
SHA-256 checksum
How to use checksums
c06f4499d34e8a1d5fb60f5712f86f890c01dbd218b34e8a2e01e8109f2aa4d5
BLAKE2b-256 checksum
How to use checksums
9d27f24c8367b6982284db7cab21251a478cad3b17b8ba84d0ce091afdfafb3a
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.0-py3-none-win_amd64.whl

Download URL nini_datagen-0.2.0-py3-none-win_amd64.whl
Size 650.0 kB
Tags Python 3 Windows x86-64
SHA-256 checksum
How to use checksums
e2c479e931f3f88303cd925e2fc030cfa2f7872a35f4d4252353db0f82939dc8
BLAKE2b-256 checksum
How to use checksums
81cd6c754b665d85a770f9c897bd1fe831a72486489733b5a8741671dec63384
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.0-py3-none-musllinux_1_2_x86_64.whl

Download URL nini_datagen-0.2.0-py3-none-musllinux_1_2_x86_64.whl
Size 1.6 MB
Tags Linux musl 1.2+ x86-64 Python 3
SHA-256 checksum
How to use checksums
da7f14b5e67ac15eea0c05691d029f1c3ff4dfa782b92689901b23a76406181a
BLAKE2b-256 checksum
How to use checksums
57a92a25a54c01aeb8bd5d6ef2c952c35f5fffbbdcc4a1f4d1a238065e019b31
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.0-py3-none-musllinux_1_2_aarch64.whl

Download URL nini_datagen-0.2.0-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
fa75565d11699854689bdd76bad2795c144594f4804c7a73a883eea1bbcd67f5
BLAKE2b-256 checksum
How to use checksums
147ee9bd378eb624e4ae9533bc072eeaeda01e7c1cad4462fa7df8e5fbc5bf17
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.0-py3-none-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl

Download URL nini_datagen-0.2.0-py3-none-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
Size 613.6 kB
Tags Linux glibc 2.24+ x86-64 Linux glibc 2.28+ x86-64 Python 3
SHA-256 checksum
How to use checksums
48102c880c37c8c91488ac976b432b5efe912ff99b73437d91b6200901be5ba3
BLAKE2b-256 checksum
How to use checksums
409151e41c07fd1425485495d766584565a1191cbe200ab8ca443a9cc180b144
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.0-py3-none-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl

Download URL nini_datagen-0.2.0-py3-none-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl
Size 615.7 kB
Tags Linux glibc 2.24+ ARM64 Linux glibc 2.28+ ARM64 Python 3
SHA-256 checksum
How to use checksums
8ea0397bca30b90f5355d1cc1fdeec3565d12674d6b1cbe0d4863f853266cff0
BLAKE2b-256 checksum
How to use checksums
6e36b054e0c2d0d7f719a7aa6f5ef5c53a96e4879c9c51cc535ac901b04b4d01
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.0-py3-none-macosx_11_0_x86_64.whl

Download URL nini_datagen-0.2.0-py3-none-macosx_11_0_x86_64.whl
Size 596.7 kB
Tags Python 3 macOS 11.0+ x86-64
SHA-256 checksum
How to use checksums
e7ea37166a4dae4ab53917641af514ef57311fa2ee3338e9bf579cba72832d4a
BLAKE2b-256 checksum
How to use checksums
928ec5124571873456cae5238c8569efbb4f570d372ecd587240a65a75dce43a
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.0-py3-none-macosx_11_0_arm64.whl

Download URL nini_datagen-0.2.0-py3-none-macosx_11_0_arm64.whl
Size 596.3 kB
Tags Python 3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
9bd5133b6d4a7299f4dfb2d5a2501c8b8653414cc41116da636bc417053985f8
BLAKE2b-256 checksum
How to use checksums
5cd61077296efa25fd4253d21c0ca635669440c2800e0fb751ce257583cccc5f
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.0

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