Readers
CSVReader, ExcelReader, ParquetReader, and PDFReader all accept a string path or pathlib.Path, and share a common set of conversion methods (to_dataframe(), to_arrow_table(), to_dicts(), get_sample()). Every return value is a standard, open object — Polars DataFrame, PyArrow Table, or plain dicts — so nothing locks you in; see Polars to Pandas. Each reader also supports use as a context manager (with ... as reader:) for early, deterministic release of its DuckDB connection — this is optional; cleanup happens automatically when the reader goes out of scope either way.
CSVReader
CSVReader(filepath, engine="polars", lenient=False, normalize_columns=False)| Parameter | Type | Default | Description |
|---|---|---|---|
filepath |
str | Path |
required | Path to the CSV file. |
engine |
str |
"polars" |
"polars", "duckdb", or "pyarrow". See CSV Engines. |
lenient |
bool |
False |
Gracefully handle ragged rows instead of raising. See Handling Messy CSV. |
normalize_columns |
bool |
False |
Normalize column names at construction. See Column Name Normalization. |
Properties & Methods
| Member | Description |
|---|---|
db_table |
Attribute: the auto-generated DuckDB table name for query_data. |
get_sample(n_rows=None) |
Returns a sample (default 20 rows; n_rows must be a positive integer), streamed from the top of the file. |
to_dataframe(**kwargs) |
Converts the file to a Polars DataFrame. kwargs tunes how the CSV is parsed: any Polars read_csv option — e.g. to_dataframe(n_rows=100) to read at most 100 rows, or null_values=["NA"] to treat NA as null. Polars engine only; the duckdb and pyarrow engines parse the file themselves and ignore these keywords. |
to_arrow_table() |
Converts the file to a PyArrow Table. |
to_dicts() |
Converts the file to a list of dictionaries. |
query_data(sql_query) |
Runs a SQL query via DuckDB against the file — write it against db_table. Repeated calls reuse the imported table. See Querying with DuckDB. |
An unrecognized engine, a directory path, or a missing path all raise immediately at construction (ValueError / FileNotFoundError). See Fail-Fast Input Validation and Legacy Mac OS Carriage Returns for engine-specific caveats.
ExcelReader
ExcelReader(filepath, normalize_columns=False, **read_options)Reads the full Excel family (.xlsx, .xlsm, .xlsb, .xls, template variants) via a single canonical engine — Polars + calamine (fastexcel) — so there is no engine argument.
| Parameter | Type | Default | Description |
|---|---|---|---|
filepath |
str | Path |
required | Path to the Excel workbook. |
normalize_columns |
bool |
False |
Normalize column names at construction. See Column Name Normalization. |
**read_options |
— | — | How to read the workbook: any Polars read_excel keyword, e.g. has_header=False, skip_rows=2, n_rows=100. Applied to every read. |
Properties & Methods
| Member | Description |
|---|---|
sheets |
Property: worksheet names in workbook order. |
db_table |
Property: the auto-generated DuckDB table name for query_data. |
get_sample(sheet=None, |
Returns a sample of the selected sheet (default 20 rows; n_rows must be a positive integer). Sheet · read options. |
to_dataframe(sheet=None, |
Converts the selected sheet to a Polars DataFrame. Sheet · read options. |
to_arrow_table(sheet=None, |
Converts the selected sheet to a PyArrow Table. Sheet · read options. |
to_dicts(sheet=None, |
Converts the selected sheet to a list of dictionaries. Sheet · read options. |
query_data(sql_query, |
Runs a SQL query via DuckDB against the selected sheet, registered under db_table. Sheet · read options. |
The sheet parameter
sheet selects which worksheet to operate on — a name (str) or zero-based position (int), defaulting to the first sheet. See Selecting Worksheets.
The **read_options parameter
**read_options controls how the sheet is read: any Polars read_excel keyword — e.g. to_dataframe(has_header=False) to treat the first row as data, or to_dataframe(skip_rows=2, n_rows=100) to skip a preamble and cap the rows. Options set on the constructor apply to every read; per-call options are merged over them and win. See Polars Read-Option Passthrough.
ParquetReader
ParquetReader(filepath, normalize_columns=False, **read_options)Reads a single-table Parquet file — no sheet dimension, no engine argument. Reading is powered by a single canonical engine, Polars (pl.read_parquet).
| Parameter | Type | Default | Description |
|---|---|---|---|
filepath |
str | Path |
required | Path to the Parquet file. |
normalize_columns |
bool |
False |
Normalize column names at construction. See Column Name Normalization. |
**read_options |
— | — | How to read the file: any Polars read_parquet keyword, e.g. columns=['name', 'city'], n_rows=100. Applied to every read. |
Properties & Methods
| Member | Description |
|---|---|
db_table |
Property: the auto-generated DuckDB table name for query_data. |
get_sample(n_rows=None, |
Returns a sample as a Polars DataFrame (default 20 rows; n_rows must be a positive integer). Read options. |
to_dataframe(**read_options) |
Converts the file to a Polars DataFrame. Read options. |
to_arrow_table(**read_options) |
Converts the file to a PyArrow Table. Read options. |
to_dicts(**read_options) |
Converts the file to a list of dictionaries. Read options. |
query_data(sql_query, |
Runs a SQL query via DuckDB, registered under db_table. Read options. |
The **read_options parameter
**read_options controls how the file is read: any Polars read_parquet keyword — e.g. to_dataframe(columns=['name', 'city']) to read only those columns, or to_dataframe(n_rows=100) to cap the rows. Options set on the constructor apply to every read; per-call options are merged over them and win. See Polars Read-Option Passthrough.
A non-Parquet path or missing path raises (ValueError / FileNotFoundError) at construction. Empty/blank files return empty results rather than raising.
PDFReader
PDFReader(filepath, engine="pdfium", workers=1, native=False, *, min_image_dimension=40)Requires the pdf extra. filepath may also be a pre-parsed .json file or an in-memory document dict, for instant loading without re-parsing.
| Parameter | Type | Default | Description |
|---|---|---|---|
filepath |
str | Path | dict |
required | PDF path, .json path, or a pre-parsed document dict. |
engine |
str |
"pdfium" |
"pdfium" or "pymupdf". See Choosing a PDF Engine. |
workers |
int |
1 |
PDFium-only: per-page process-pool concurrency. See Concurrency & Environments. |
native |
bool |
False |
PDFium-only: lean schema (text + images, no table detection). |
min_image_dimension |
int |
40 |
Keyword-only. Minimum pixel size (either side) for kept embedded images; 0 keeps all. See Filtering Small Embedded Images. |
Properties & Methods
| Member | Description |
|---|---|
total_pages |
Property: number of pages in the source PDF (or pages in a pre-parsed document). |
get_sample() |
Parses and returns only the first page — a fast preview without parsing the whole document. |
to_dicts(image_output_dir=None, |
Parses into the unified document dict. Embedded images are written to disk only when image_output_dir is given; otherwise their file_path is null. |
to_dataframe(drop_layout_tables=False) |
Flattens extracted elements into a Polars DataFrame (one row per element — columns). |
to_arrow_table(drop_layout_tables=False) |
Flattens extracted elements into a PyArrow Table (same columns). |
The parse is cached per reader, so mixed calls (to_dicts() then to_dataframe()) never re-parse the PDF. Encrypted (password-protected) PDFs raise ValueError on every engine; a zero-byte PDF returns empty objects rather than raising. Image-only/scanned pages fall back to Tesseract OCR automatically — see PDF Parsing for the output schemas, OCR, tables, and error-isolation guarantees.