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
.ivtfile data to Apache Arrow
Installation
-
Using
uv(Recommended):uv add pyivt
-
Using
pippip 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. Unsupported language keys raise
KeyError. Dimension name, description, members, and notes replace the
previous _en / _fr fields; geographies.geo_label now holds both languages.
Exporting Data
Use Ivt.to_arrow() to export to Apache Arrow.
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.
-
Populate
datawith test inputsPut any number of
.ivtfiles indata, or use the default dataset using:uv run --no-project scripts/copy_test_inputs.py
-
Generate expected test outputs
uv run --no-project scripts/generate_expected_metadata.py
uv run --no-project scripts/generate_expected_parquet.py
-
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.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| pyivt-0.0.3.tar.gz | 154.9 kB | With provenance | Details for pyivt-0.0.3.tar.gz |
Built distributions (wheels)
| File | Actions Reset | |||
|---|---|---|---|---|
| pyivt-0.0.3-cp310-abi3-win_amd64.whl | CPython 3.10 | abi3 | Windows x86-64 | Details for pyivt-0.0.3-cp310-abi3-win_amd64.whl |
| pyivt-0.0.3-cp310-abi3-manylinux_2_28_x86_64.whl | CPython 3.10 | abi3 | Linux glibc 2.28+ x86-64 | Details for pyivt-0.0.3-cp310-abi3-manylinux_2_28_x86_64.whl |
| pyivt-0.0.3-cp310-abi3-manylinux_2_28_aarch64.whl | CPython 3.10 | abi3 | Linux glibc 2.28+ ARM64 | Details for pyivt-0.0.3-cp310-abi3-manylinux_2_28_aarch64.whl |
| pyivt-0.0.3-cp310-abi3-macosx_11_0_arm64.whl | CPython 3.10 | abi3 | macOS 11.0+ ARM64 | Details for pyivt-0.0.3-cp310-abi3-macosx_11_0_arm64.whl |
| pyivt-0.0.3-cp310-abi3-macosx_10_12_x86_64.whl | CPython 3.10 | abi3 | macOS 10.12+ x86-64 | Details for pyivt-0.0.3-cp310-abi3-macosx_10_12_x86_64.whl |
Total release size: 7.0 MB
Release files / pyivt-0.0.3.tar.gz
| Download URL | pyivt-0.0.3.tar.gz |
|---|---|
| Size | 154.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c5113fcb9ae6c5339170ab31421add5e4f852e5f212cc84987116a0c96b1d8ed
|
|
BLAKE2b-256 checksum How to use checksums |
f426ed2f46a154182f699507173c4afe89c8cebcaad9ae93e2dd94973944ba9a
|
| 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 26, 2026.
Transparency logRelease files / pyivt-0.0.3-cp310-abi3-win_amd64.whl
| Download URL | pyivt-0.0.3-cp310-abi3-win_amd64.whl |
|---|---|
| Size | 1.2 MB |
| Tags | CPython 3.10 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
b1c13bbc44ac4fee1755aabf45b97a0064cb779639c207870ff9fdfb322df6cd
|
|
BLAKE2b-256 checksum How to use checksums |
06ae16666112e538adc7db5805aa41452ec8c81d94064ba5daed80d9f3615875
|
| 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 26, 2026.
Transparency logRelease files / pyivt-0.0.3-cp310-abi3-manylinux_2_28_x86_64.whl
| Download URL | pyivt-0.0.3-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 |
befccc6d824cfb7f21edb98b5c8ddf6b20a739e03bb1e0943a359095afaec9c2
|
|
BLAKE2b-256 checksum How to use checksums |
f1b412769980f8f80c6fe545fd5a60abfa3e32b16d55e8042bdf896e8f4f04e3
|
| 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 26, 2026.
Transparency logRelease files / pyivt-0.0.3-cp310-abi3-manylinux_2_28_aarch64.whl
| Download URL | pyivt-0.0.3-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 |
521decc1f881c73b495b738d07b8e039b8eae105a5491808870656bcaedb8399
|
|
BLAKE2b-256 checksum How to use checksums |
674fab65cf98b8df3449117b7956873f6ae0522dc865ac0adc1c76c3d9a229ed
|
| 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 26, 2026.
Transparency logRelease files / pyivt-0.0.3-cp310-abi3-macosx_11_0_arm64.whl
| Download URL | pyivt-0.0.3-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 |
085ef87a96e05abad4d56a20fc2b0bf7851348a09d7d2e6289004325d1bc33d8
|
|
BLAKE2b-256 checksum How to use checksums |
e667d5141eaa02716b4eb9f3d44bd366d62364ded6c4f90e93ce207c6ce2db2a
|
| 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 26, 2026.
Transparency logRelease files / pyivt-0.0.3-cp310-abi3-macosx_10_12_x86_64.whl
| Download URL | pyivt-0.0.3-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 |
e1a5ce31e11495b9d3d661dcf0c56f6d22aa48e9eff2858610bd4d4fb7921db5
|
|
BLAKE2b-256 checksum How to use checksums |
01673f639431a4e539d728762a308a4ebbc5e4863ad2ba27203ed9197029e63b
|
| 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 26, 2026.
Transparency logSecurity for pyivt 0.0.3
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.
Attestation for pyivt-0.0.3.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 26, 2026.
Transparency logA 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.