Skip to main content

Project Status: Active — The project has reached a stable, usable state and is being actively developed. CI Status coverage pyversions MIT License

GitHub | PyPI | Documentation | Issues | Changelog

headerparser parses key-value pairs in the style of RFC 822 (e-mail) headers and converts them into case-insensitive dictionaries with the trailing message body (if any) attached. Fields can be converted to other types, marked required, or given default values using an API based on the standard library’s argparse module. (Everyone loves argparse, right?) Low-level functions for just scanning header fields (breaking them into sequences of key-value pairs without any further processing) are also included.

The Format

RFC 822-style headers are header fields that follow the general format of e-mail headers as specified by RFC 822 and friends: each field is a line of the form “Name: Value”, with long values continued onto multiple lines (“folded”) by indenting the extra lines. A blank line marks the end of the header section and the beginning of the message body.

This basic grammar has been used by numerous textual formats besides e-mail, including but not limited to:

  • HTTP request & response headers

  • Usenet messages

  • most Python packaging metadata files

  • Debian packaging control files

  • META-INF/MANIFEST.MF files in Java JARs

  • a subset of the YAML serialization format

— all of which this package can parse.

Installation

headerparser requires Python 3.8 or higher. Just use pip for Python 3 (You have pip, right?) to install headerparser:

python3 -m pip install headerparser

Examples

Define a parser:

>>> import headerparser
>>> parser = headerparser.HeaderParser()
>>> parser.add_field('Name', required=True)
>>> parser.add_field('Type', choices=['example', 'demonstration', 'prototype'], default='example')
>>> parser.add_field('Public', type=headerparser.BOOL, default=False)
>>> parser.add_field('Tag', multiple=True)
>>> parser.add_field('Data')

Parse some headers and inspect the results:

>>> msg = parser.parse('''\
... Name: Sample Input
... Public: yes
... tag: doctest, examples,
...   whatever
... TAG: README
...
... Wait, why I am using a body instead of the "Data" field?
... ''')
>>> sorted(msg.keys())
['Name', 'Public', 'Tag', 'Type']
>>> msg['Name']
'Sample Input'
>>> msg['Public']
True
>>> msg['Tag']
['doctest, examples,\n  whatever', 'README']
>>> msg['TYPE']
'example'
>>> msg['Data']
Traceback (most recent call last):
    ...
KeyError: 'data'
>>> msg.body
'Wait, why I am using a body instead of the "Data" field?\n'

Fail to parse headers that don’t meet your requirements:

>>> parser.parse('Type: demonstration')
Traceback (most recent call last):
    ...
headerparser.errors.MissingFieldError: Required header field 'Name' is not present
>>> parser.parse('Name: Bad type\nType: other')
Traceback (most recent call last):
    ...
headerparser.errors.InvalidChoiceError: 'other' is not a valid choice for 'Type'
>>> parser.parse('Name: unknown field\nField: Value')
Traceback (most recent call last):
    ...
headerparser.errors.UnknownFieldError: Unknown header field 'Field'

Allow fields you didn’t even think of:

>>> parser.add_additional()
>>> msg = parser.parse('Name: unknown field\nField: Value')
>>> msg['Field']
'Value'

Just split some headers into names & values and worry about validity later:

>>> for field in headerparser.scan('''\
... Name: Scanner Sample
... Unknown headers: no problem
... Unparsed-Boolean: yes
... CaSe-SeNsItIvE-rEsUlTs: true
... Whitespace around colons:optional
... Whitespace around colons  :  I already said it's optional.
...   That means you have the _option_ to use as much as you want!
...
... And there's a body, too, I guess.
... '''): print(field)
('Name', 'Scanner Sample')
('Unknown headers', 'no problem')
('Unparsed-Boolean', 'yes')
('CaSe-SeNsItIvE-rEsUlTs', 'true')
('Whitespace around colons', 'optional')
('Whitespace around colons', "I already said it's optional.\n  That means you have the _option_ to use as much as you want!")
(None, "And there's a body, too, I guess.\n")

Metadata

Release files for headerparser 0.5.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for headerparser 0.5.2
File Size Uploaded
headerparser-0.5.2.tar.gz 31.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for headerparser 0.5.2
File Interpreter ABI Platform
headerparser-0.5.2-py3-none-any.whl Python 3 none any Details

Total release size: 49.2 kB

Release files / headerparser-0.5.2.tar.gz

Download URL headerparser-0.5.2.tar.gz
Size 31.1 kB
Tags Source
SHA-256 checksum
How to use checksums
2e24ae218ed5d2ef5839fafeff084c40ee1e317bbbe6489cfe333385d7cb98e7
BLAKE2b-256 checksum
How to use checksums
8697ecdbe764cb2909999ca51db3a76852aaba4f938c309c41b86014c90a8d4b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/5.1.1 CPython/3.13.0

Release files / headerparser-0.5.2-py3-none-any.whl

Download URL headerparser-0.5.2-py3-none-any.whl
Size 18.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e89d35c8cfe494f7fdec6eff14b4a9d5542fc2b2b8f1b50d750b62d822d0b8d6
BLAKE2b-256 checksum
How to use checksums
0f879b5b7eb8eade5d5c5357b19ced4b719c0c0815089c5dc0e9a68cd3b8ff5c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/5.1.1 CPython/3.13.0

Release history Release notifications | RSS feed

This release

0.5.2 This release

2 release files

0.5.1

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page