Export
export casts and types TOSSD activity records, then writes the result to a compressed parquet file with an export manifest. Exports retain all columns (columns="all") and original units (units="usd_thousand" in USD thousands).
Write the normalised, typed get_tossd pipeline output to parquet.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str | Path
|
A directory (created if missing), in which case the parquet
file is written as |
required |
years
|
int | Iterable[int] | None
|
Same semantics as |
None
|
refresh
|
bool
|
Same semantics as |
False
|
max_rows
|
int | None
|
Opt-in guard: once the table is built, raise |
None
|
Returns:
| Type | Description |
|---|---|
Path
|
The path the parquet file was written to. A sidecar |
Path
|
|
Path
|
package version, a schema hash, a sha256 of the written parquet's |
Path
|
own bytes ( |
Path
|
exported years, per-year vintage provenance (etag/retrieved_at), |
Path
|
the total row count, and the export's creation timestamp. |
Note
years=None (the default) materialises the full packaged
known-years set as one arrow table, all in memory, before it's
ever written to disk (columns="all", per this function's own
contract) -- measured at roughly 4.4GB peak resident for the full
set (the finished table alone is ~2.1GB; per-year tables are
transiently alive alongside it).
Pass an explicit years= (or max_rows= to fail fast instead) to
export a smaller slice if that's a concern.
Raises:
| Type | Description |
|---|---|
ValueError
|
|
TossdNetworkError
|
Same conditions as |
SchemaDriftError
|
Same conditions as |
Example
import tossd_reader path = tossd_reader.export( # doctest: +SKIP ... "tossd_2024.parquet", years=2024 ... ) df = tossd_reader.load_export(path) # doctest: +SKIP
Generated filenames
When path specifies a directory, export creates the directory if needed and writes tossd_<years>.parquet inside it. When path ends in .parquet, export writes directly to that file path, creating parent directories as needed.
The <years> segment reflects the resolved, sorted list of years:
- Single year:
tossd_2019.parquet - Contiguous range:
tossd_2019-2024.parquet - Non-contiguous set:
tossd_2019_2021_2024.parquet
Manifest fields
Each export writes a companion <stem>.manifest.json file beside the parquet file.
{
"created_at": "2026-09-02T08:24:37.680642+00:00",
"payload_sha256": "8a6eed10875a87fcd5faedece760bc461aa5926113ba1686613728c8c27d30bf",
"row_count": 290914,
"schema_hash": "0a95f2c54852817a9db1a2174cffa5bd371d601e5d137a37cb27491182367df9",
"tossd_reader_version": "0.1.0",
"vintages": {
"2019": {
"etag": "\"69e6ac86-347a653\"",
"retrieved_at": "2026-08-28T21:14:14.414671+00:00"
}
},
"years": [
2019
]
}
| Field | Type | Description |
|---|---|---|
tossd_reader_version |
string | Package version that created the export file. |
schema_hash |
string | SHA-256 hash of packaged schema.csv, CRLF-normalised. |
payload_sha256 |
string | SHA-256 hash of the exported parquet file's own bytes. Checked by verify_export. |
years |
list of int |
Sorted list of reporting years included in the export. |
row_count |
int | Total row count across all exported reporting years. Checked by verify_export. |
created_at |
string | Export timestamp in ISO 8601 format (UTC). |
vintages |
object | Mapping of reporting year to source metadata (etag and retrieved_at). |
payload_sha256 and row_count make an export file self-checking. verify_export re-hashes the parquet payload and compares both fields against the manifest. load_export runs that check by default before reading the file back.
import tossd_reader as tossd
tossd.export("tossd_2024.parquet", years=2024)
tossd.verify_export("tossd_2024.parquet")
df = tossd.load_export("tossd_2024.parquet")
print(df.shape)
print(sorted(df.attrs["tossd_reader"]))
load_export sets df.attrs["tossd_reader"] to this same three-key shape on every call. An export is an unfiltered snapshot, so it carries no query key the way a get_tossd() or get_tossd_raw() result does. tossd.get_provenance(df) returns the payload as a deep copy, ensuring mutations to the returned dictionary do not affect df.attrs. See Verbs for get_provenance and its df.tossd.provenance() accessor equivalent.
verify_export checks only payload_sha256 and row_count. An export written by an older or newer package version can carry a different schema_hash without being corrupted, so that field sits outside the check.
Verify a parquet file previously written by export() against its manifest sidecar.
Two checks, both against <stem>.manifest.json beside path: the
payload's sha256 hash (payload_sha256) and its row count (row_count).
A schema_hash mismatch is deliberately not checked here -- an export
written by an older or newer package version is not a corrupted file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str | Path
|
Path to a |
required |
Returns:
| Type | Description |
|---|---|
None
|
|
Raises:
| Type | Description |
|---|---|
ExportIntegrityError
|
The manifest sidecar is missing or cannot be
parsed as a JSON object; the payload's sha256 hash doesn't match
the manifest's |
Load a parquet file previously written by export(), with its provenance attached.
Reads the file directly (pq.read_table + to_pandas, reusing
query's own types_mapper) rather than through get_tossd's pipeline:
an exported parquet already carries snake_case column names and final
arrow types (export() wrote it that way), so re-running
_schema.apply_schema would be redundant at best and wrong if the
installed package's schema has since drifted from the one that produced
the file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str | Path
|
Path to a |
required |
verify
|
bool
|
Run |
True
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
A |
DataFrame
|
|
DataFrame
|
"years"} |
DataFrame
|
|
Raises:
| Type | Description |
|---|---|
ExportIntegrityError
|
|
Example
import tossd_reader df = tossd_reader.load_export("tossd_2024.parquet") # doctest: +SKIP
Manifest validation when verify=False
verify=False skips the payload-hash and row-count checks. load_export still reads <stem>.manifest.json for df.attrs provenance, so a missing or unreadable manifest raises ExportIntegrityError either way.
A tampered or truncated file fails at the hash check. Flipping a single byte mid-file is enough.
with open("tossd_2024.parquet", "r+b") as f:
f.seek(1_000_000)
original_byte = f.read(1)
f.seek(1_000_000)
f.write(bytes([original_byte[0] ^ 0xFF]))
tossd.verify_export("tossd_2024.parquet")
ExportIntegrityError: tossd_2024.parquet does not match its manifest: sha256 86f01b27506eeaba3f4fb71fd98ffa2e910bb6fb663e8d6d88a48c219ade1c3e but the manifest recorded cbc990069898161335701299e172cd6ae39bbfef2d2543ec7044e914384b13e8. The file may have been modified or corrupted since export.
Bases: TossdReaderError
Raised when a previously exported parquet file fails verify_export's checks.
Covers a missing or unreadable manifest sidecar, a payload whose sha256
hash no longer matches the manifest's payload_sha256, and a payload
whose row count no longer matches the manifest's row_count. A
schema_hash difference (an export written by a different package
version) is deliberately not one of these checks -- it doesn't mean the
file was modified.
Performance and memory
Exporting the default full dataset (years=None, covering 2019 through 2024) materialises approximately 2.4 million rows in memory as an Apache Arrow table before writing to disk. Peak resident memory reaches roughly 4.4 GB. The finished table itself accounts for about 2.1 GB of that. Per-year tables stay alive alongside it until concatenation completes. Pass specific years to years= when working in memory-constrained environments, or pass max_rows= to enforce a maximum row threshold before writing to disk.
ValueError: export() would write 290914 rows, exceeding max_rows=100000. Pass a larger max_rows=, or narrow years= to export a smaller slice.
The check runs after the table is built, so the error names the actual row count. It also runs before anything is written, so a rejected export leaves no partial file, and a pre-existing file at the target path is untouched.
Next
- Configuration, warnings, and errors. Cache settings, provenance handling, and error types.
- Query. Interactive querying with
get_tossd.