Skip to main content

pyivt

pyivt is a library for Statistics Canada Beyond 20/20 .ivt files, written in Rust. It is designed to be minimal and easily adaptable for existing codebases. Key features are:

  • Fast: Orders of magnitude faster than GUI automation for metadata
  • Python: Easily integrates into modern data workflows with a minimal API
  • Typed: Produces fully type-safe and predictable metadata
  • Interoperable: Exports .ivt file data to Apache Arrow

Installation

  • Using uv (Recommended):

    uv add pyivt
    
  • Using pip

    pip install pyivt
    

Usage

Quick Start

Open an IVT file, read its metadata, and write its data to a Parquet file:

import pyarrow.parquet as pq
import pyivt

ivt = pyivt.open("data.ivt")
print(ivt.metadata.title.en)
pq.write_table(ivt.to_arrow(), "data.parquet")

Opening IVT Files

From Path

import pyivt

ivt = pyivt.open("data.ivt")

From URL

import requests

import pyivt

url = "https://example.com/data.ivt"
res = requests.get(url)
res.raise_for_status()

ivt = pyivt.open(res.content)

Reading Metadata

ivt.metadata is a typed IvtMetadata object. Summary fields are eager; heavy fields load on first access.

Beyond 20/20 Summary pyivt Metadata
Title title.en, title.fr
Author author.en, author.fr
Category category.en, category.fr
Keywords keywords.en, keywords.fr
Notes notes.en, notes.fr
Number of Datapoints number_of_datapoints
Time Series frequency, start_date, end_date (each None if absent)
Read-Only read_only
Dimensions dimensions (name.en / name.fr, description.en / description.fr, …)
Geographies geographies
Footnotes footnotes
Missing Values missing_values

Localized fields support both attribute and language-key access:

meta = ivt.metadata
print(meta.title.en, meta.title["fr"])
for dimension in meta.dimensions:
    print(dimension.name.en, dimension.description["fr"])
    print(dimension.members.en, dimension.notes["fr"])
print(meta.geographies.geo_label.en, meta.geographies.geo_label["fr"])

Each translation is None when unavailable. Blank authors, categories, keywords, and table or dimension notes also return None. Unsupported language keys raise KeyError. Keyword strings stored separately in the file are joined with ", " in file order; meta.keywords.en and .fr remain optional strings.

dimension.type is a typed string with three possible values: "geographic", "normal", and "time_series". The DimensionType alias is available for your own annotations:

from pyivt import DimensionType

kind: DimensionType = "time_series"
time_axes = [dimension for dimension in meta.dimensions if dimension.type == kind]

meta.frequency uses the Frequency literal enum: "monthly", "quarterly", "semi_annual", or "annual". It returns None when Time Series is No or the stored rate is unknown. dimension.items gives the declared number of members on each axis; dimension.count remains an alias for the same value.

Each footnote contains both translations in description. Missing-value entries use the same field name:

for footnote in meta.footnotes:
    print(footnote.symbol, footnote.description.en, footnote.description["fr"])

for missing in meta.missing_values:
    print(missing.code, missing.symbol, missing.description.en)

Footnotes follow legend order and appear once per entry. A missing translation is None. Numbered footnotes embedded in table or dimension notes remain in those notes.

Editor Support

The package includes type stubs, read-only property definitions, and Markdown hover documentation with Python snippets. Select the Python environment where pyivt is installed to get completions for metadata fields and the allowed dimension.type and frequency values. The examples above show localized-field access and optional-value handling; see the changelog for migration notes.

Exporting Data

Use Ivt.to_arrow() to export to Apache Arrow.

The table contains the complete Cartesian product of all declared dimensions, in file dimension order (last dimension varies fastest). Each dimension has an int64 member ordinal and every declared native member field: codes and labels as strings, integer attributes as int64, floating attributes as float64, and time-series dates as date32, with the original time serial and auxiliary word retained. Codes keep their leading zeros, and both languages are retained when stored in the file.

value is float64; missing-value records determine its nulls independently of the numeric payload. status_code, symbol, status, and footnote_raw (list<uint16>) retain status and raw annotation information. A zero value is preserved when the file marks it as published. Flat and paged data directories use the same API and strict ordinal/range checks.

Apache Arrow is ready to use with your current data stack.

  • pandas:

    import pandas as pd
    import pyivt
    
    ivt = pyivt.open("example.ivt")
    
    tab = ivt.to_arrow()
    
    df = pd.DataFrame.from_arrow(tab)
    print(df)
    
  • polars:

    import polars as pl
    import pyivt
    
    ivt = pyivt.open("example.ivt")
    
    tab = ivt.to_arrow()
    
    df = pl.from_arrow(tab)
    print(df)
    
  • pyarrow:

    import pyarrow.parquet as pq
    import pyivt
    
    ivt = pyivt.open("example.ivt")
    
    tab = ivt.to_arrow()
    
    pq.write_table(tab, "example.parquet")
    

Benchmarks

Compared with canivt across 20 IVT files, pyivt achieved a median per-file speedup of 69.2× for metadata extraction and 29.1× for Arrow conversion.

Operation Library Wall time (ms) CPU time (ms) Peak memory (MiB) Memory growth (MiB)
Metadata canivt 810.0 800.0 179.5 107.8
Metadata pyivt 9.1 15.6 22.7 2.7
Arrow conversion canivt 565.0 565.0 223.6 120.0
Arrow conversion pyivt 24.5 23.4 38.0 7.6

Table values are medians across the 20 files, using each file’s median trial result. Speedups are calculated per file before taking the median.

pyivt was faster on all 20 metadata cases and 19 of 20 Arrow cases. Peak memory was lower on all metadata cases and 17 of 20 Arrow cases. In the remaining Arrow case, pyivt took 710 ms versus 360 ms for canivt.

Methodology

Each case runs three times in fresh worker processes. Timings exclude runtime startup and imports, but include the first operation’s initialization costs. Metadata extraction loads all lazy metadata fields; Arrow conversion materializes the complete grid, including missing cells, without writing to disk. The libraries produce different schemas: pyivt preserves additional member fields and raw annotations.

Memory is sampled resident memory (RSS), including native allocations. Peak memory includes the runtime; growth measures the increase above the baseline after imports. Sampling can miss brief allocation peaks. CPU time includes user and system time across threads; Windows timer resolution limits accuracy for short operations.

Running the benchmarks

Tests automatically discover IVT files under data, including subdirectories.

uv sync --group benchmark
uv run maturin develop --release --skip-install
uv run --group benchmark pytest benchmarks --ivt-report .cache/benchmarks/results.json

The canivt backend embeds R through rpy2 in each Python worker. Install R and the R packages canivt and arrow; set R_HOME if R is not discovered. Use --ivt-r-library PATH to add an R package library (the default also searches the cache created by scripts/generate_expected_parquet.py). To benchmark only Python, pass --ivt-backends pyivt.

The published results above used the previous standalone R worker. Rerun the benchmarks to compare memory usage with the embedded R runtime.

Tests

CI downloads three Census samples with committed JSON metadata references. Parquet references are generated locally and are not committed; comparisons against them are skipped when they are unavailable. Arrow export and round-trip tests still run without these references.

Mandatory offline Arrow regressions additionally compare a committed paged IVT against all 1,155 cells of an official CSV and check a hand-authored fixture's complete typed output, including dates, missing statuses and raw annotations. See fixture provenance and native format evidence.

To validate the original NAICS234 report with a complete independent Parquet export, set PYIVT_REGRESSION_NAICS234_PATH and PYIVT_REGRESSION_NAICS234_EXPECTED_PARQUET, then run pytest tests/test_arrow_regression.py. The oracle must be produced independently and use matching column names, types and row order. A requested regression with a missing file or oracle fails; otherwise this optional case is skipped.

  1. Populate data with test inputs

    Put any number of .ivt files in data, or use the default dataset using:

    uv run --no-project scripts/copy_test_inputs.py
    
  2. Generate expected test outputs

    uv run --no-project scripts/generate_expected_metadata.py
    
    uv run --no-project scripts/generate_expected_parquet.py
    
  3. Run tests

    pytest
    

To clear all files and subdirectories in data and tests/expected, including the committed JSON references, run:

uv run --no-project scripts/cleanup.py

The folders themselves are preserved. Committed references can be restored with git restore tests/expected.

License

pyivt is licensed under the MIT License.

Acknowledgements

Metadata

Release files for pyivt 0.0.5

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

Source distribution (sdist)

Source distribution for pyivt 0.0.5
File Size Uploaded Provenance Actions
pyivt-0.0.5.tar.gz 199.4 kB With provenance Details for pyivt-0.0.5.tar.gz

Built distributions (wheels)

Table of built distributions (wheels) for pyivt 0.0.5
File Actions
pyivt-0.0.5-cp310-abi3-win_amd64.whl CPython 3.10 abi3 Windows x86-64 Details for pyivt-0.0.5-cp310-abi3-win_amd64.whl
pyivt-0.0.5-cp310-abi3-manylinux_2_28_x86_64.whl CPython 3.10 abi3 Linux glibc 2.28+ x86-64 Details for pyivt-0.0.5-cp310-abi3-manylinux_2_28_x86_64.whl
pyivt-0.0.5-cp310-abi3-manylinux_2_28_aarch64.whl CPython 3.10 abi3 Linux glibc 2.28+ ARM64 Details for pyivt-0.0.5-cp310-abi3-manylinux_2_28_aarch64.whl
pyivt-0.0.5-cp310-abi3-macosx_11_0_arm64.whl CPython 3.10 abi3 macOS 11.0+ ARM64 Details for pyivt-0.0.5-cp310-abi3-macosx_11_0_arm64.whl
pyivt-0.0.5-cp310-abi3-macosx_10_12_x86_64.whl CPython 3.10 abi3 macOS 10.12+ x86-64 Details for pyivt-0.0.5-cp310-abi3-macosx_10_12_x86_64.whl

Total release size: 7.0 MB

Release files / pyivt-0.0.5.tar.gz

Download URL pyivt-0.0.5.tar.gz
Size 199.4 kB
Tags Source
SHA-256 checksum
How to use checksums
e03d47a5c1f9fa878021580cb564aadb103e41375fa9a6e200a42deb7bf2a3b9
BLAKE2b-256 checksum
How to use checksums
06a1ac57e1c826be411d3f93adba2dd3ddaaaef366898c6fa67a1f2fb193b086
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 Oct 29, 2026.

Transparency log

Release files / pyivt-0.0.5-cp310-abi3-win_amd64.whl

Download URL pyivt-0.0.5-cp310-abi3-win_amd64.whl
Size 1.2 MB
Tags CPython 3.10 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
9669c203bab155cdacb34840af04af69cf106e58c1d4eec12e0f74ac1ac84351
BLAKE2b-256 checksum
How to use checksums
97c962279831016dd472e52d042c3ee777a0e7e19510343606955d41ea4544bf
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 Oct 29, 2026.

Transparency log

Release files / pyivt-0.0.5-cp310-abi3-manylinux_2_28_x86_64.whl

Download URL pyivt-0.0.5-cp310-abi3-manylinux_2_28_x86_64.whl
Size 1.5 MB
Tags CPython 3.10 Linux glibc 2.28+ x86-64 abi3
SHA-256 checksum
How to use checksums
9bb6bdc45042c02b833b74b0c19f0f63be6c27b5722fc02a771ca06ca73b9e86
BLAKE2b-256 checksum
How to use checksums
61e91ac72af0a01bcff0e418a0a29d5f324575f8d9b2b0848b61c3703e02c1de
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 Oct 29, 2026.

Transparency log

Release files / pyivt-0.0.5-cp310-abi3-manylinux_2_28_aarch64.whl

Download URL pyivt-0.0.5-cp310-abi3-manylinux_2_28_aarch64.whl
Size 1.5 MB
Tags CPython 3.10 Linux glibc 2.28+ ARM64 abi3
SHA-256 checksum
How to use checksums
26cfbc4e91e41124d377ea30c5050eef155340ce03a6d2e3359e7e2590b83ec9
BLAKE2b-256 checksum
How to use checksums
1bcb62b0dbff29361407d5461aa13a246314b31cff9d38592a437c63bec4e7dc
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 Oct 29, 2026.

Transparency log

Release files / pyivt-0.0.5-cp310-abi3-macosx_11_0_arm64.whl

Download URL pyivt-0.0.5-cp310-abi3-macosx_11_0_arm64.whl
Size 1.3 MB
Tags CPython 3.10 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
8cedffb1879a32f156afcaa3075541086582e763b85fd70a16d1e8249d2b0702
BLAKE2b-256 checksum
How to use checksums
8e8c5b9a29cc52af7c7738bc6aadd73cc43bc3d18fe99aab3f9f588fe11eed0a
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 Oct 29, 2026.

Transparency log

Release files / pyivt-0.0.5-cp310-abi3-macosx_10_12_x86_64.whl

Download URL pyivt-0.0.5-cp310-abi3-macosx_10_12_x86_64.whl
Size 1.3 MB
Tags CPython 3.10 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
5c8d262e313f8b0d87a42b639d34e2d66658d878a2980bb272ad334ce39b12ac
BLAKE2b-256 checksum
How to use checksums
22466956bf7863b05b8918c6f097e04558282ef79db27f10ddffd9b3fd2b6a37
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 Oct 29, 2026.

Transparency log

Security for pyivt 0.0.5

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 6 files in this release have been uploaded with provenance metadata.

Select from 6 files

Attestation for pyivt-0.0.5.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 Oct 29, 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