Typed CSVs via header-embedded types and validators
Project description
typedcsv
Typed CSVs via header-embedded types (sigils or :type) plus optional header-embedded validation — stdlib-only, Python 3.10+.
Default extensions (by convention):
.tcsvfor comma-separated typed CSV.ttsvfor tab-separated typed TSV
The core lives in a single module and is copy-pasteable into projects.
pip install typedcsv-lib
Header typing
Declare types using either suffix sigils or explicit :type (not both on the same column).
| Type | Sigil (suffix) | Explicit |
|---|---|---|
int |
# |
:int |
float |
% |
:float |
bool |
? |
:bool |
datetime |
@ |
:datetime |
str |
$ |
:str |
Untyped columns default to str.
Optional constraint sigils (suffix, after the type sigil):
| Constraint | Sigil |
|---|---|
| required | ! |
| unique | + |
Order is flexible, but the recommended style is: type + optional unique + optional required.
Examples:
id#+(unique int)email$!(required str)slug$+!(unique + required str)
Logical column names are the header names with the type marker removed:
age#becomes key"age"created:datetimebecomes key"created"
Validators
Add an optional validator clause after the type marker:
age# [min=0 max=120]
ratio% [min=0 max=1]
status$ [in=OPEN|CLOSED|PENDING]
code$ [re=^[A-Z]{3}\d{2}$]
created@ [min=2020-01-01T00:00:00 max=2030-12-31T23:59:59]
email:str [required unique]
Notes:
- Validators are space-separated
key=valuepairs inside[ ... ]. requiredanduniqueare flag-only validators (no=).re=uses Pythonre.fullmatch.in=uses|as separator.- Unknown validator keys raise an error.
Missing values (nullable by default)
- An empty cell (
"") is missing. - For
strcolumns, missing stays"". - For non-
strcolumns, missing becomesNone. - Missing values skip validation.
required(sigil!or validator) rejects missing values.uniqueignores missing values (multiple empty cells are allowed).
Reading
import typedcsv
with open("data.tcsv", newline="") as f:
for row in typedcsv.DictReader(f):
print(row)
Example CSV:
id#,name$,active?,created@
1,Alice,true,2021-05-01T12:30:00
2,Bob,false,
Produces:
{'id': 1, 'name': 'Alice', 'active': True, 'created': datetime(2021, 5, 1, 12, 30)}
{'id': 2, 'name': 'Bob', 'active': False, 'created': None}
Writing (canonical formatting)
None→ empty cellbool→true/falsedatetime→isoformat()float→repr(f)- Header preserved exactly as provided to
DictWriter(fieldnames=...)
import typedcsv
from datetime import datetime
rows = [
{"id": 1, "name": "Alice", "active": True, "created": datetime(2021, 5, 1, 12, 30)},
{"id": 2, "name": "Bob", "active": False, "created": None},
]
with open("out.tcsv", "w", newline="") as f:
w = typedcsv.DictWriter(f, fieldnames=["id#", "name$", "active?", "created@"])
w.writeheader()
w.writerows(rows)
More examples
Validators with quoted values
name$ [in="Alice Smith"|Bob]
Regex validation (fullmatch)
code$ [re=^[A-Z]{3}\d{2}$]
ABC12
Type inference for untyped columns
import typedcsv
import io
data = "a,b\n1,true\n2,false\n"
rows = list(typedcsv.DictReader(io.StringIO(data), infer_types=True))
Errors
Parsing/validation failures raise TypedCSVError with context:
row(1-based; header row is 1)col(0-based)column(logical name)header(raw header cell)value(raw cell)reason(short message)
API reference (csv-compatible)
typedcsv mirrors Python's csv module API and is designed to be a drop-in replacement where you want typed rows.
typedcsv.reader(f, ...)→ yields typed list rows (header consumed)typedcsv.DictReader(f, ...)→ yields typed dict rows keyed by logical names (header consumed)typedcsv.writer(f, ...)→ returns a standardcsv.writertypedcsv.DictWriter(f, fieldnames, ...)→ writes typed dict rows with canonical formatting
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file typedcsv_lib-0.2.0.tar.gz.
File metadata
- Download URL: typedcsv_lib-0.2.0.tar.gz
- Upload date:
- Size: 13.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
139dbfd36f64b26845d2e738dd5890cae09c76a6ed793807e0cb6ebcabee450d
|
|
| MD5 |
2da11beb00340e1f5c12c91ddc47d77c
|
|
| BLAKE2b-256 |
8fb04de1ddd8e290c0f4063be0bfbe04d3550a3b4c2c5bfe538f29894c505359
|
File details
Details for the file typedcsv_lib-0.2.0-py3-none-any.whl.
File metadata
- Download URL: typedcsv_lib-0.2.0-py3-none-any.whl
- Upload date:
- Size: 10.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a2384b1d79c6a57a3e53ff3172a5ea7896d42985732c9f5b0c5575373f289b33
|
|
| MD5 |
6d65be53f1b161a1061f68999f87ce68
|
|
| BLAKE2b-256 |
bee6bb6563193479f17826a7ccce09fbd77943911ddae925a252ea19f8079427
|