pyfixwidth
pyfixwidth reads fixed-width text files and converts each record into Python
values. It can be used as a command-line tool that writes delimited output or
as a small parsing library inside your own code.
The package has no runtime dependencies and is designed to stay lightweight.
Install
pip install pyfixwidth
Quickstart
The repository includes a small example layout and sample data files:
python -m fixwidth example/data.layout example/data1.txt example/data2.txt
This writes tab-separated output to standard output:
employee_id job_title salary hire_date
100001 CEO 15000.0 1995-08-23
100002 Programmer 8500.0 2002-11-10
100003 Data Scientist 10000.0 2005-07-01
100004 Sales Rep 5000.0 1999-06-01
100005 Customer Servic 4800.0 2001-12-17
If you install the package, the same command is also available as:
pyfixwidth example/data.layout example/data1.txt example/data2.txt
Layout File Format
A layout file is tab-delimited and describes how each source field should be read. The first line is a title, then each later line contains:
- field width
- converter name
- field name
Example:
employees
# records on workers and their salaries
6 int employee_id
15 str job_title
8 float salary
# negative values denote fields to skip when reading data
-3 str blank
10 date hire_date
Rules:
- Comments begin with
#and must occupy their own line. - Negative widths skip bytes in the input and do not appear in parsed rows.
- Blank field content becomes
Nonebefore type conversion. - A layout can be loaded from disk with
read_file_format()or supplied directly as a sequence of(width, datatype, name)tuples.
Supported Converters
| Type | Meaning | Accepted values |
|---|---|---|
str |
text | any decoded string |
int |
integer | values accepted by int() |
float |
floating point number | values accepted by float() |
bool |
boolean | Python truthiness via bool() |
yesno |
yes/no boolean | Y, N, Yes, No and lowercase variants |
date |
date | 1995-08-23, 19950823, 23aug1995, 1995-8-23, 122599 |
datetime |
date with time | 1995-08-23 14:30:00.000 and similar ISO-like values |
julian |
Julian date | YYYYDDD, with optional separators removed before parsing |
time |
time | 14:30:00, 14.30.00, 143000, 09:00, 0900 |
date and datetime formats are inferred with regular expressions, so if you
have unusual source formats you may want to register a custom converter.
Python API
For most code, these are the main entry points:
read_file_format(path)loads a layout file and returns(title, spec).parse_file(path, spec=...)yieldsOrderedDictrows from a file on disk.parse_lines(lines, spec=...)parses an iterable of binary lines.DictReader(fileobj, fieldinfo=...)provides acsv.DictReader-like iterator for binary file objects.register_type(name)lets you add custom converters.
Parse a Layout and a Data File
from fixwidth import read_file_format, parse_file
title, layout = read_file_format('example/data.layout')
print(title)
rows = parse_file('example/data1.txt', spec=layout, type_errors='ignore')
for row in rows:
print('Salary for {} is {}'.format(row['employee_id'], row['salary']))
Use DictReader
DictReader expects a binary file object:
import fixwidth
with open('example/data1.txt', 'rb') as fh:
reader = fixwidth.DictReader(
fh,
fieldinfo='example/data.layout',
skip_blank_lines=True,
)
first_row = next(reader)
print(first_row['job_title'])
You can also pass the layout directly:
layout = [
(6, 'int', 'employee_id'),
(15, 'str', 'job_title'),
(8, 'float', 'salary'),
(-3, 'str', 'blank'),
(10, 'date', 'hire_date'),
]
with open('example/data1.txt', 'rb') as fh:
reader = fixwidth.DictReader(fh, layout)
print(next(reader))
Custom Converters
Converters live in fixwidth.converters. To register a new one, decorate a
function that accepts a decoded string and returns the converted value.
from fixwidth.converters import register_type
@register_type('uppercase')
def convert_uppercase(value):
return value.strip().upper()
After registration, the new type name can be used in layouts just like the built-in types.
Troubleshooting
- Open files in binary mode when using
DictReader. parse_file()defaults toencoding='ascii'.parse_lines()defaults toencoding='utf-8'.- Use
type_errors='ignore'to replace invalid values withNoneand keep parsing. skip_blank_lines=Trueignores lines that are empty after removing trailing newlines. Lines that contain only spaces still produce a row ofNonevalues.
More Documentation
Additional documentation lives in docs/index.md:
Metadata
Release files for pyfixwidth 0.3.2
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 |
|---|---|---|---|---|
| pyfixwidth-0.3.2.tar.gz | 13.4 kB | Without provenance | Details for pyfixwidth-0.3.2.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| pyfixwidth-0.3.2-py3-none-any.whl | Python 3 | none | any | Details for pyfixwidth-0.3.2-py3-none-any.whl |
Total release size: 24.7 kB
Release files / pyfixwidth-0.3.2.tar.gz
| Download URL | pyfixwidth-0.3.2.tar.gz |
|---|---|
| Size | 13.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
eff4158def6bc0218f7802527eebb80f098fb239822136062f763570f213b901
|
|
BLAKE2b-256 checksum How to use checksums |
24ff97643c21b2e26fd2cbca2514c42beb37f469cf7ab9c03064265a0996df8d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.3
|
Release files / pyfixwidth-0.3.2-py3-none-any.whl
| Download URL | pyfixwidth-0.3.2-py3-none-any.whl |
|---|---|
| Size | 11.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
40ea5dc70016b49540ddf4c64dd187423a3fa2aad4677e700521459e563e3055
|
|
BLAKE2b-256 checksum How to use checksums |
9439d8bab69c713c08c13e305ce41d0e5337a40e43edab06f76b8a4ae937df8a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.3
|
Security for pyfixwidth 0.3.2
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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A 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.