readstat-arrow
Read and write SPSS (.sav) and Stata (.dta) files as Apache
Arrow tables, using the excellent
ReadStat C library:
import readstat_arrow
table, metadata = readstat_arrow.read_sav("survey.sav") # -> (pyarrow.Table, Metadata)
readstat_arrow.write_dta("survey.dta", table, metadata) # the same pair back out, as Stata
Motivation
There are several options in this space. readstat-arrow relies on the ReadStat
library for reading and writing since it is mature and battle-tested, and on
Apache Arrow for in-memory representation in Python since it provides
zero-copy interoperability with libraries like Pandas, Polars, and DuckDB.
Much of the inspiration for readstat-arrow comes from the great
pyreadstat library.
Status
Early development. The library works and is tested, but the API is not stable: names, signatures and return shapes may change in any release, without a deprecation period. Pin an exact version if you depend on it. There is currently support for reading and writing SPSS and Stata files. More file formats can be added on request.
Examples
Reading files
import readstat_arrow
# SPSS
table, metadata = readstat_arrow.read_sav("survey.sav")
# Stata:
table, metadata = readstat_arrow.read_dta("survey.dta")
Every read_* function returns the same pair: a pyarrow.Table, and a
Metadata object.
Metadata is a set of mappings from variable name to one attribute —
variable_labels, value_labels, formats, storage_widths,
display_widths, measures, alignments, missing_values — plus the
file-level file_label, notes and multiple_response_sets. Which columns
exist, and in what order, is the Arrow schema's business, not the metadata's.
Nothing is required: a name absent from a mapping simply declares nothing.
Metadata(
file_label="2026 satisfaction survey",
variable_labels={
"id": "Respondent id",
"q1": "How satisfied are you ...?",
"q2": "How many hours ...?",
},
value_labels={
"q1": [
{"value": 1, "label": "Very unsatisfied"},
{"value": 5, "label": "Very satisfied"},
{"value": 9, "label": "No answer"},
]
},
formats={"q1": "F1.0", "q2": "F2.0"},
measures={"q1": "ordinal", "q2": "scale"},
)
Use with Pandas or Polars
import readstat_arrow
table, metadata = readstat_arrow.read_sav("survey.sav")
# pandas:
df = table.to_pandas()
# polars:
import polars as pl
df = pl.from_arrow(table)
Writing files:
import pyarrow as pa
import readstat_arrow
from readstat_arrow import Metadata
table = pa.table({"id": [1, 2, 3], "q1": [1, 5, 4], "q2": [10, 11, 2]})
metadata = Metadata(
file_label="2026 satisfaction survey",
variable_labels={
"id": "Respondent id",
"q1": "How satisfied are you ...?",
"q2": "How many hours ...?",
},
value_labels={
"q1": [
{"value": 1, "label": "Very unsatisfied"},
{"value": 5, "label": "Very satisfied"},
]
},
formats={"q1": "F1.0", "q2": "F2.0"},
measures={"q1": "ordinal", "q2": "scale"},
)
# SPSS:
readstat_arrow.write_sav("survey.sav", table, metadata)
# Stata:
readstat_arrow.write_dta("survey.dta", table, metadata)
Writing in batches
To avoid holding an entire table in memory at once, it is possible to write files in batches
import pyarrow as pa
import readstat_arrow
from readstat_arrow import Metadata
def my_data_source():
# Let's pretend this comes from some external source
for _ in range(10):
yield pa.table(
{
"q1": pa.array([1, 2, 3, 4, 5], pa.int8()),
"q2": pa.array([10, 20, 30, 40, 50], pa.int32()),
"q3": pa.array([100, 200, 300, 400, 500], pa.int32()),
}
)
# we need to know these up front:
schema = pa.schema({"q1": pa.int8(), "q2": pa.int32(), "q3": pa.int32()})
num_rows = 50
metadata = Metadata()
# SPSS:
with readstat_arrow.SavWriter("survey.sav", schema, num_rows, metadata) as writer:
for table in my_data_source():
writer.write_table(table)
# Stata:
with readstat_arrow.DtaWriter("survey.dta", schema, num_rows, metadata) as writer:
for table in my_data_source():
writer.write_table(table)
Handling missing values
By default every kind of missing — system-missing, a Stata tagged missing, an
SPSS value the file declares missing — reads as an Arrow null. With
preserve_user_missing=True the user-level ones survive, in the way each format
has of saying them.
Stata tags its missings .a to .z, so every numeric column becomes a
struct<value, tag> to carry both:
import readstat_arrow
table, metadata = readstat_arrow.read_dta("panel.dta", preserve_user_missing=True)
table.schema.field("income").type # -> struct<value: double, tag: dictionary<int8, string>>
table.column("income")[0].as_py() # -> {"value": None, "tag": "a"}, Stata's .a
table.column("income")[1].as_py() # -> {"value": 42.0, "tag": None}, a real number
table.column("income")[2].as_py() # -> None, a plain .
SPSS instead declares ordinary values missing, so those values simply stay in
the column — the type is unchanged, and Metadata.missing_values says which
values were the missing ones:
import readstat_arrow
default, metadata = readstat_arrow.read_sav("survey.sav")
kept, _ = readstat_arrow.read_sav("survey.sav", preserve_user_missing=True)
metadata.missing_values["q1"] # -> {"values": [9.0]}, declared by MISSING VALUES q1 (9)
default.column("q1")[0].as_py() # -> None, the 9 collapsed to null
kept.column("q1")[0].as_py() # -> 9.0, the declared missing value itself
System-missing is null either way, and the writers accept both shapes back.
An SPSS declaration takes one of two shapes in Metadata.missing_values:
Metadata(
missing_values={
# up to three discrete values: MISSING VALUES q1 (7, 8, 9)
"q1": {"values": [7, 8, 9]},
# an inclusive range: MISSING VALUES q2 (90 THRU 99)
"q2": {"lo": 90, "hi": 99},
# a range and one value beside it: MISSING VALUES q3 (LO THRU 0, 999)
"q3": {"lo": float("-inf"), "hi": 0, "value": 999},
}
)
-inf and inf are SPSS's LO and HI, and more than three discrete values
is an error — SPSS itself allows no more.
Reading the metadata without the data
read_sav_metadata and read_dta_metadata stop before reading the actual data.
What comes back is the schema a full read would have given, the row count, and
the Metadata object.
import readstat_arrow
schema, num_rows, metadata = readstat_arrow.read_dta_metadata("panel.dta")
schema.names # -> ["id", "year", "income", ...], the variables in file order
schema.field("income").type # -> the type a full read would give that column
num_rows # -> 4_000_000, from the header
metadata.variable_labels["income"] # -> "Annual income, NOK"
The row count is None where the file does not record one — Stata files always
do, some non-SPSS writers of .sav do not. The schema describes a
preserve_user_missing=False read, so it does not show the struct<value, tag>
columns that option gives a .dta.
Reading only part of a file
Use columns, row_offset and row_limit to read parts of a file:
import readstat_arrow
table, metadata = readstat_arrow.read_dta(
"panel.dta",
columns=["id", "income"], # only these two; they come back in file order
row_offset=1_000, # skip the first 1_000 rows
row_limit=1_000, # then read at most 1_000
)
row_limit=0 means no limit, and the returned Metadata covers the columns
that were read, not the whole file.
Narrowing types to reduce memory usage
In memory-constrained environments, it can be difficult to hold the whole table in
memory at once — especially since the type a column is stored as is often wider
than its values need. A .sav is the worst of it: every numeric column is a
64-bit double whatever it holds, so a even survey of one-digit codes costs 8 bytes a
cell. A .dta has narrow types of its own — byte, int, long, float —
but a variable is only as narrow as whoever wrote the file declared it.
scan_and_narrow_types=True reads each column at the width its values actually
need instead:
import readstat_arrow
table, metadata = readstat_arrow.read_sav("big.sav", scan_and_narrow_types=True)
table.schema.field("q1").type # -> DataType(int8), where the file says double
The file is parsed twice — once to measure the values, keeping none of them, then once to read them at the widths that fit — so the trade is time for memory.
Only a type that holds the column exactly is ever chosen: integer types when
every value was a whole number, float32 when every value round-trips through
it, else float64. The ladder is int8, int16, int32, int64,
float32, float64 — int64 saves nothing over the stored double, but it is
the cleaner type for a column of whole numbers. Strings are untouched.
Reading in batches
Read a fixed number of rows at a time and hand each one over as a
pyarrow.RecordBatch,
import pyarrow.parquet as pq
import readstat_arrow
reader = readstat_arrow.open_sav("big.sav")
with pq.ParquetWriter("big.parquet", reader.schema) as writer:
reader.read_batches(writer.write_batch)
open_sav and open_dta return a SavStreamingReader / DtaStreamingReader.
Opening reads the metadata and nothing else, so schema, num_rows and
metadata are all there before the data itself is read:
reader = readstat_arrow.open_sav("panel.sav")
reader.schema # the schema every batch has
reader.num_rows # rows the header declares, or None
reader.metadata.variable_labels["income"]
read_batches(callback) then reads the file, calling callback with each batch
and returning the rows read.
The writers in readstat-arrow take a batch at a time too, so converting between the two
formats can be done on the fly:
reader = readstat_arrow.open_sav("panel.sav")
with readstat_arrow.DtaWriter(
"survey.dta", reader.schema, reader.num_rows, reader.metadata
) as writer:
reader.read_batches(writer.write_batch)
A reader takes the same arguments the matching read_* takes: columns,
row_offset, row_limit, encoding, preserve_user_missing, and
scan_and_narrow_types.
Making a pyarrow.RecordBatchReader
read_batches pushes: it drives the parse and calls you. Some consumers want to
pull instead — DuckDB, pyarrow.dataset.write_dataset, anything that takes a
pyarrow.RecordBatchReader. Turning one around into the other needs a thread,
and can be done like this:
import queue
import threading
import pyarrow as pa
def record_batch_reader(reader, *, batch_rows=65_536, ahead=2):
"""A pyarrow.RecordBatchReader over a readstat-arrow streaming reader."""
queued: queue.Queue = queue.Queue(maxsize=ahead)
done = object()
def run():
try:
reader.read_batches(queued.put, batch_rows=batch_rows)
except BaseException as exc: # comes back out of the consumer
queued.put(exc)
else:
queued.put(done)
threading.Thread(target=run, daemon=True).start()
def batches():
while True:
item = queued.get()
if item is done:
return
if isinstance(item, BaseException):
raise item
yield item
return pa.RecordBatchReader.from_batches(reader.schema, batches())
maxsize is the backpressure: the parse runs at most ahead batches in front
of whoever is reading and then waits, so the file is never held. What comes back
is an ordinary pyarrow.RecordBatchReader, which DuckDB will query in place:
import duckdb
import readstat_arrow
survey = record_batch_reader(readstat_arrow.open_sav("big.sav"))
duckdb.sql("select region, avg(income) from survey group by region").show()
or pyarrow.dataset will write out partitioned:
import pyarrow.dataset as ds
ds.write_dataset(
record_batch_reader(readstat_arrow.open_dta("panel.dta")),
"panel/",
format="parquet",
)
One thing to know: a consumer that stops reading part way leaves the worker thread parked on a full queue until the process ends. Read it to the end, or add a flag the callback checks if that matters.
Read from something other than a path
Every read_* function also takes a binary file object, so a file that arrives
over the network or out of an archive never has to be written to disk first.
import io, zipfile
import readstat_arrow
# straight out of a zip archive, without extracting it
with zipfile.ZipFile("survey.zip") as archive, archive.open("survey.sav") as member:
table, metadata = readstat_arrow.read_sav(member)
# or from bytes you already have in hand
table, metadata = readstat_arrow.read_sav(io.BytesIO(downloaded))
# an open file works too, and is left open where reading stopped
with open("survey.sav", "rb") as file:
schema, num_rows, metadata = readstat_arrow.read_sav_metadata(file)
The file object must be seekable, and is read from wherever it currently is - so
a .sav embedded in a larger stream can be read by seeking to its first byte.
The writers have taken a file object all along.
Development
Requires uv and a C compiler.
git clone <repo-url>
cd readstat-arrow
uv sync # builds the Cython extension into .venv
uv run coverage run -m pytest && uv run coverage report || uv run coverage html
uv run ruff check . && uv run ruff format --check . && uv run mypy
uv run pre-commit install # optional: run those same checks on every commit
uv run mypy checks src/ and tests/ in strict mode. The Cython sources in
src/readstat_arrow/_cython/ are excluded — they are typed for Cython's C type
system, which mypy cannot follow, and Cython checks them at compile time.
ReadStat is vendored as a git submodule at vendor/ReadStat; bump it with git submodule update --remote vendor/ReadStat.
uv sync rebuilds the extension whenever _cython/, setup.py or the ReadStat
sources change (see [tool.uv] cache-keys in pyproject.toml).
Layout
pyproject.toml project metadata, deps, tool config (uv/ruff/mypy/pytest)
setup.py Cython extension definition (compiles ReadStat in)
vendor/ReadStat/ git submodule
src/readstat_arrow/
__init__.py public API re-exports
reader.py read_*, read_*_metadata, open_* (streaming), table assembly, type narrowing
writer.py SavWriter / DtaWriter, write_* functions, type planning
metadata.py the Metadata dataclass and its per-variable mappings
errors.py ReadstatError, ReadstatWarning
_formats.py FileFormat literal type
_dates.py display-format -> temporal type conversion
_cython/ everything Cython compiles (private)
parser.py pure-Python-mode Cython: ReadStat callbacks -> Arrow buffers
writer.py pure-Python-mode Cython: Arrow buffers -> readstat_insert_*
readstat.pxd C declarations for readstat.h
tests/ pytest suite; sample files under tests/data/
Versioning
Releases use CalVer in the form YYYY.MM.DD.INC0 (e.g.
2026.9.1.0, then 2026.9.1.1 for a fix on the same day). There are no
compatibility promises encoded in the number. The version is set once in
pyproject.toml and exposed as readstat_arrow.__version__.
Licence
MIT. ReadStat is MIT-licensed; the sample files under tests/data/ come from
pyreadstat (Apache 2.0) — see tests/data/README.md.
Release files for readstat-arrow 2026.9.24.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| readstat_arrow-2026.9.24.1.tar.gz | 235.4 kB | Details |
Built distributions (wheels)
Total release size: 41.3 MB
Release files / readstat_arrow-2026.9.24.1.tar.gz
| Download URL | readstat_arrow-2026.9.24.1.tar.gz |
|---|---|
| Size | 235.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
cb0ab80e41e07ece017c97cb42214c5ee041032b375f4b0b5aef7670d104a972
|
|
BLAKE2b-256 checksum How to use checksums |
26d577637a780a75c6db28eb030b8d33f34bf076dfa01107996c0abee6805e26
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Sep 24, 2026.
Transparency logRelease files / readstat_arrow-2026.9.24.1-cp314-cp314-win_amd64.whl
| Download URL | readstat_arrow-2026.9.24.1-cp314-cp314-win_amd64.whl |
|---|---|
| Size | 358.8 kB |
| Tags | CPython 3.14 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
d098942afd4b6f2d3bf6923544b1e983e5fbf162827c0e3d799ab2a0f49689ad
|
|
BLAKE2b-256 checksum How to use checksums |
db8b1c9b580baba7a85a3663cb9a54c26b01d2731143bb3a807fb888abf39433
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Sep 24, 2026.
Transparency logRelease files / readstat_arrow-2026.9.24.1-cp314-cp314-musllinux_1_2_x86_64.whl
| Download URL | readstat_arrow-2026.9.24.1-cp314-cp314-musllinux_1_2_x86_64.whl |
|---|---|
| Size | 2.3 MB |
| Tags | CPython 3.14 Linux musl 1.2+ x86-64 |
|
SHA-256 checksum How to use checksums |
63c19052afefec5a6c6dea13f31c900cb4ca7ae00838177c72ffdd990e341a30
|
|
BLAKE2b-256 checksum How to use checksums |
fc0e51f9aa5acbea8395fbdc93cf74e07dbf2575ffea5c91f49693af38a62b9c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Sep 24, 2026.
Transparency logRelease files / readstat_arrow-2026.9.24.1-cp314-cp314-musllinux_1_2_aarch64.whl
| Download URL | readstat_arrow-2026.9.24.1-cp314-cp314-musllinux_1_2_aarch64.whl |
|---|---|
| Size | 2.2 MB |
| Tags | CPython 3.14 Linux musl 1.2+ ARM64 |
|
SHA-256 checksum How to use checksums |
850a36aa488779bf77b20ad445a6a28a220f4d3eecc3166ca746abf1f607705b
|
|
BLAKE2b-256 checksum How to use checksums |
c522f14666794f5dd632ed774f5c64e1cf8a2e6e874182231b41400734ba5e9d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Sep 24, 2026.
Transparency logRelease files / readstat_arrow-2026.9.24.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
| Download URL | readstat_arrow-2026.9.24.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 2.3 MB |
| Tags | CPython 3.14 Linux glibc 2.17+ x86-64 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
6773dbf1acbb1221cf528c5a9ec2d7676d9c6da9e4a5dacbbfd5a478def382b3
|
|
BLAKE2b-256 checksum How to use checksums |
6225583dc63d92899009191979ca2d3b1a89cef1d3f151daa8c50a84da8d7cd3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Sep 24, 2026.
Transparency logRelease files / readstat_arrow-2026.9.24.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
| Download URL | readstat_arrow-2026.9.24.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl |
|---|---|
| Size | 2.2 MB |
| Tags | CPython 3.14 Linux glibc 2.17+ ARM64 Linux glibc 2.28+ ARM64 |
|
SHA-256 checksum How to use checksums |
2c75ce6ab8cd87e985ef7958503b9fb1e8f23fd79a9a1742f57a67b420121656
|
|
BLAKE2b-256 checksum How to use checksums |
5c437324afe59e642e4e7d50c40ff8af47deb4b8d7e94f789c3d7fc8a4b95849
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Sep 24, 2026.
Transparency logRelease files / readstat_arrow-2026.9.24.1-cp314-cp314-macosx_11_0_arm64.whl
| Download URL | readstat_arrow-2026.9.24.1-cp314-cp314-macosx_11_0_arm64.whl |
|---|---|
| Size | 431.3 kB |
| Tags | CPython 3.14 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
62002fea42c152b77645e8a2032e1b47ee9b5999b6f5cd540ba7c5d1a47debe2
|
|
BLAKE2b-256 checksum How to use checksums |
e5a7b3daa64228677ee11990d8075fda0f00401163096787e74029602b6bd8d1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Sep 24, 2026.
Transparency logRelease files / readstat_arrow-2026.9.24.1-cp314-cp314-macosx_10_15_x86_64.whl
| Download URL | readstat_arrow-2026.9.24.1-cp314-cp314-macosx_10_15_x86_64.whl |
|---|---|
| Size | 443.2 kB |
| Tags | CPython 3.14 macOS 10.15+ x86-64 |
|
SHA-256 checksum How to use checksums |
104b883771fb0097f848cea888a3118b2f01ea44dc14e582c7741690cb395fd2
|
|
BLAKE2b-256 checksum How to use checksums |
53fa91c6c2650eb2c2b5b35c0238f487312b7a8471fac6990abcdf2239689f92
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Sep 24, 2026.
Transparency logRelease files / readstat_arrow-2026.9.24.1-cp313-cp313-win_amd64.whl
| Download URL | readstat_arrow-2026.9.24.1-cp313-cp313-win_amd64.whl |
|---|---|
| Size | 348.7 kB |
| Tags | CPython 3.13 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
4838ee8440801120609ab8d8f952dfad553f46775b14a938661007134bb1139d
|
|
BLAKE2b-256 checksum How to use checksums |
d133122b3b683940ba11f17fa2b437208228f84c4ec7c1ab29b1a4b7de617ed8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Sep 24, 2026.
Transparency logRelease files / readstat_arrow-2026.9.24.1-cp313-cp313-musllinux_1_2_x86_64.whl
| Download URL | readstat_arrow-2026.9.24.1-cp313-cp313-musllinux_1_2_x86_64.whl |
|---|---|
| Size | 2.3 MB |
| Tags | CPython 3.13 Linux musl 1.2+ x86-64 |
|
SHA-256 checksum How to use checksums |
088791d54461855749e8cf2b7ec15e65c6e9f77c2abcb11bf45d5ebfbf3aa69f
|
|
BLAKE2b-256 checksum How to use checksums |
eedcf8b26bbea5d8a05dc0d067946e2ad9f24bbd0f51bccff0fc23f32fc86665
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Sep 24, 2026.
Transparency logRelease files / readstat_arrow-2026.9.24.1-cp313-cp313-musllinux_1_2_aarch64.whl
| Download URL | readstat_arrow-2026.9.24.1-cp313-cp313-musllinux_1_2_aarch64.whl |
|---|---|
| Size | 2.2 MB |
| Tags | CPython 3.13 Linux musl 1.2+ ARM64 |
|
SHA-256 checksum How to use checksums |
93deb87b69ad498e35d762de63849624422c1bb3df3e09556b78bb67e536c729
|
|
BLAKE2b-256 checksum How to use checksums |
137ba3fc9435f0ee80918be7c6459ae1ca9924c8eca6ca3a08a4ade2094152cf
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Sep 24, 2026.
Transparency logRelease files / readstat_arrow-2026.9.24.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
| Download URL | readstat_arrow-2026.9.24.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 2.3 MB |
| Tags | CPython 3.13 Linux glibc 2.17+ x86-64 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
9d0c96a336f842506c7af083861ea6cccd3cb8481f1d2b05642cdb6c2c5d1626
|
|
BLAKE2b-256 checksum How to use checksums |
5fdd9f6b6269d009338fc0ece840fe9f8e97b47da9a51e2956637e738f04beb8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Sep 24, 2026.
Transparency logRelease files / readstat_arrow-2026.9.24.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
| Download URL | readstat_arrow-2026.9.24.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl |
|---|---|
| Size | 2.2 MB |
| Tags | CPython 3.13 Linux glibc 2.17+ ARM64 Linux glibc 2.28+ ARM64 |
|
SHA-256 checksum How to use checksums |
ea2accfa9a6a4067960338c1ea73b520d5b36eff3e0d563cb06e5690d82ce25a
|
|
BLAKE2b-256 checksum How to use checksums |
e2ed39ee17fc52d13db462e87a61a5a7affd2d1a18db0cae1b40361e02fca056
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Sep 24, 2026.
Transparency logRelease files / readstat_arrow-2026.9.24.1-cp313-cp313-macosx_11_0_arm64.whl
| Download URL | readstat_arrow-2026.9.24.1-cp313-cp313-macosx_11_0_arm64.whl |
|---|---|
| Size | 428.3 kB |
| Tags | CPython 3.13 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
40c183918bd6762d99c21a5bc19fff05e5a34747e49f4406a87432d8845e2f41
|
|
BLAKE2b-256 checksum How to use checksums |
a05feabb426b93a71c4ad94c6cb74eac574bdbc3c95aa1657dc0d9a4485cf5dd
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Sep 24, 2026.
Transparency logRelease files / readstat_arrow-2026.9.24.1-cp313-cp313-macosx_10_13_x86_64.whl
| Download URL | readstat_arrow-2026.9.24.1-cp313-cp313-macosx_10_13_x86_64.whl |
|---|---|
| Size | 442.0 kB |
| Tags | CPython 3.13 macOS 10.13+ x86-64 |
|
SHA-256 checksum How to use checksums |
c801970e220dc0cb067785ae4ea7064756bb062cd768f6de25e816a6efb8f3dc
|
|
BLAKE2b-256 checksum How to use checksums |
d93e660aedfff69831c77817a7c8144c8a82ca40870228d4f33ddcf6a29e6837
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Sep 24, 2026.
Transparency logRelease files / readstat_arrow-2026.9.24.1-cp312-cp312-win_amd64.whl
| Download URL | readstat_arrow-2026.9.24.1-cp312-cp312-win_amd64.whl |
|---|---|
| Size | 348.9 kB |
| Tags | CPython 3.12 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
74730153dd2ef2ee3e9a953252462184fc1d2b28fe877af77bcf516d7230abf7
|
|
BLAKE2b-256 checksum How to use checksums |
c2c4d94135f097c322e52c2eadf3bffbfe18a8ed4254b8512574e0882ac2e9cc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Sep 24, 2026.
Transparency logRelease files / readstat_arrow-2026.9.24.1-cp312-cp312-musllinux_1_2_x86_64.whl
| Download URL | readstat_arrow-2026.9.24.1-cp312-cp312-musllinux_1_2_x86_64.whl |
|---|---|
| Size | 2.3 MB |
| Tags | CPython 3.12 Linux musl 1.2+ x86-64 |
|
SHA-256 checksum How to use checksums |
2e826cbe3da6286ef6d3d77e1a53e83f9e2588c2e2553816e3d63626d89b078e
|
|
BLAKE2b-256 checksum How to use checksums |
03dc3b6cd1503790c8f0895349f371f6417f19767aa453dfbeb84a5203f3a2fb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Sep 24, 2026.
Transparency logRelease files / readstat_arrow-2026.9.24.1-cp312-cp312-musllinux_1_2_aarch64.whl
| Download URL | readstat_arrow-2026.9.24.1-cp312-cp312-musllinux_1_2_aarch64.whl |
|---|---|
| Size | 2.2 MB |
| Tags | CPython 3.12 Linux musl 1.2+ ARM64 |
|
SHA-256 checksum How to use checksums |
7a85e882e061a763d90b6ea488a880b1d1524e151e8f93553b5c3424bbbf45c1
|
|
BLAKE2b-256 checksum How to use checksums |
7b69a27bda33da215fcbca4e002391f94eedf6166b5156d13b7d875585e8bcde
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Sep 24, 2026.
Transparency logRelease files / readstat_arrow-2026.9.24.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
| Download URL | readstat_arrow-2026.9.24.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 2.3 MB |
| Tags | CPython 3.12 Linux glibc 2.17+ x86-64 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
348ff3ad838c63a787d35f6a4879495c0e02dfbebfb593eb1a444f3aa97ba997
|
|
BLAKE2b-256 checksum How to use checksums |
a486d7c5086f02d49bd68e5e9fd3d1028c303dd95d9a5ea4ef698ce8a6daedb2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Sep 24, 2026.
Transparency logRelease files / readstat_arrow-2026.9.24.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
| Download URL | readstat_arrow-2026.9.24.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl |
|---|---|
| Size | 2.3 MB |
| Tags | CPython 3.12 Linux glibc 2.17+ ARM64 Linux glibc 2.28+ ARM64 |
|
SHA-256 checksum How to use checksums |
887b480ee6cb7e5594ee3b25b0422af7723da39821193111a8ed307a5e247148
|
|
BLAKE2b-256 checksum How to use checksums |
d6c98908dc0fcfb670682d828b2bf387cfa057ddd3bd8295395e041801be4711
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Sep 24, 2026.
Transparency logRelease files / readstat_arrow-2026.9.24.1-cp312-cp312-macosx_11_0_arm64.whl
| Download URL | readstat_arrow-2026.9.24.1-cp312-cp312-macosx_11_0_arm64.whl |
|---|---|
| Size | 427.2 kB |
| Tags | CPython 3.12 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
5da41931600cfd6ce05f9859701597fda9e44736686215cd2e0dd866e6199084
|
|
BLAKE2b-256 checksum How to use checksums |
7f572bda69b8fa69ca763929631da295eb492c7c61c0b172df240d544f82d658
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Sep 24, 2026.
Transparency logRelease files / readstat_arrow-2026.9.24.1-cp312-cp312-macosx_10_13_x86_64.whl
| Download URL | readstat_arrow-2026.9.24.1-cp312-cp312-macosx_10_13_x86_64.whl |
|---|---|
| Size | 441.1 kB |
| Tags | CPython 3.12 macOS 10.13+ x86-64 |
|
SHA-256 checksum How to use checksums |
881066ac8e88881cb2a92596b51477df86dce3fa0c84c37fbafc2f018a16b667
|
|
BLAKE2b-256 checksum How to use checksums |
abc3177460f857270b56ec3df1446dcec2ddcae3a64cbde52432134ff8a46068
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Sep 24, 2026.
Transparency logRelease files / readstat_arrow-2026.9.24.1-cp311-cp311-win_amd64.whl
| Download URL | readstat_arrow-2026.9.24.1-cp311-cp311-win_amd64.whl |
|---|---|
| Size | 349.5 kB |
| Tags | CPython 3.11 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
d213c203a7e1955ee7ad0090b150028ec5e8203acf43a647b58b961d20677ca4
|
|
BLAKE2b-256 checksum How to use checksums |
8e8ce67ce65527ac524fc6537d81f7daa845401f5e16654fae8de57312dd906a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Sep 24, 2026.
Transparency logRelease files / readstat_arrow-2026.9.24.1-cp311-cp311-musllinux_1_2_x86_64.whl
| Download URL | readstat_arrow-2026.9.24.1-cp311-cp311-musllinux_1_2_x86_64.whl |
|---|---|
| Size | 2.3 MB |
| Tags | CPython 3.11 Linux musl 1.2+ x86-64 |
|
SHA-256 checksum How to use checksums |
66639bc41a164caa19c581fc060dec3bb09925043294cf2a2a49e0ff99e034e6
|
|
BLAKE2b-256 checksum How to use checksums |
5ff86271d5bd8d7f5e59637dd5026c3333f25878215d7e76c24b26bb07a10420
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Sep 24, 2026.
Transparency logRelease files / readstat_arrow-2026.9.24.1-cp311-cp311-musllinux_1_2_aarch64.whl
| Download URL | readstat_arrow-2026.9.24.1-cp311-cp311-musllinux_1_2_aarch64.whl |
|---|---|
| Size | 2.2 MB |
| Tags | CPython 3.11 Linux musl 1.2+ ARM64 |
|
SHA-256 checksum How to use checksums |
8d70a0e6a2171e858e9424cc56a1e43e743006515a835b31b02ab038ef805033
|
|
BLAKE2b-256 checksum How to use checksums |
1c560a9c57ba31defe568c02a82e79a5402d755104ecb1e09f0738f4ba0c84da
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Sep 24, 2026.
Transparency logRelease files / readstat_arrow-2026.9.24.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
| Download URL | readstat_arrow-2026.9.24.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 2.3 MB |
| Tags | CPython 3.11 Linux glibc 2.17+ x86-64 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
699327d426146ebe13bf1d8ecbcf52148f90e5488f70ba338c7c5a6e67b3948d
|
|
BLAKE2b-256 checksum How to use checksums |
c92dd6b9db70c49c9493b11f1dc8670cd377af736cc0041620e3e47ded4b43ec
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Sep 24, 2026.
Transparency logRelease files / readstat_arrow-2026.9.24.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
| Download URL | readstat_arrow-2026.9.24.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl |
|---|---|
| Size | 2.3 MB |
| Tags | CPython 3.11 Linux glibc 2.17+ ARM64 Linux glibc 2.28+ ARM64 |
|
SHA-256 checksum How to use checksums |
e8bfff0cbe81d1bfbb28a7b8e9b564633ac4468fcc2f8284129d02c5e76d5681
|
|
BLAKE2b-256 checksum How to use checksums |
32f7f30df718a3dde7ec5b35dce9fda301ca34f61c3bf25f621fe20d1b253651
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Sep 24, 2026.
Transparency logRelease files / readstat_arrow-2026.9.24.1-cp311-cp311-macosx_11_0_arm64.whl
| Download URL | readstat_arrow-2026.9.24.1-cp311-cp311-macosx_11_0_arm64.whl |
|---|---|
| Size | 428.5 kB |
| Tags | CPython 3.11 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
d9664741521c39a885df5652534363ea7e6ed2f5434532c46c8f0b890ab5c026
|
|
BLAKE2b-256 checksum How to use checksums |
678bc844d016cee2e92be43d3231dfe33d65ff2381b29220d137cedc07f6ee1e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Sep 24, 2026.
Transparency logRelease files / readstat_arrow-2026.9.24.1-cp311-cp311-macosx_10_9_x86_64.whl
| Download URL | readstat_arrow-2026.9.24.1-cp311-cp311-macosx_10_9_x86_64.whl |
|---|---|
| Size | 440.6 kB |
| Tags | CPython 3.11 macOS 10.9+ x86-64 |
|
SHA-256 checksum How to use checksums |
43a3689c74edfbf96017bf1d51ee208b46f11793e120fac009469afabfa609a9
|
|
BLAKE2b-256 checksum How to use checksums |
7e47756663b11b7e3f297d61af659509270d94760b13315b3d677ccd0f0945a6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Sep 24, 2026.
Transparency log