Skip to main content
https://travis-ci.org/mailgun/flanker.svg?branch=master https://coveralls.io/repos/github/mailgun/flanker/badge.svg?branch=master

Flanker is an open source parsing library written in Python by the Mailgun Team. Flanker currently consists of an address parsing library (flanker.addresslib) as well as a MIME parsing library (flanker.mime).

Detailed documentation is provided in the User Manual as well as the API Reference. A Quickstart Guide is provided below.

Python Versions

Flanker is heavily used by Mailgun in production with Python 2.7. The current production version is v0.8.5.

Support for Python 3 was added in v0.9.0 by popular demand from the community. We are not using Flanker with Python 3 in the house. All we know is that tests pass with Python 3.6, so use at your own risk. Feel free to report Python 3 specific issues if you see any.

Installing

You can install flanker via pip or clone the repo from GitHub.

You’ll need Python headers files before you start working with flanker, so install them first:

# ubuntu
sudo apt-get install python-dev
# fedora
sudo yum install python-devel

If you are using pip, simply type:

pip install flanker

If you are cloning from GitHub, you can type:

git clone git@github.com:mailgun/flanker.git
cd flanker
pip install -e .

Address Parsing

To parse a single mailbox (display name as well as email address):

>>> from flanker.addresslib import address
>>>
>>> address.parse('Foo foo@example.com')
Foo <foo@example.com>

An invalid address is returned as None:

>>> from flanker.addresslib import address
>>>
>>> print address.parse('@example.com')
None

To parse a single email address (no display name):

>>> from flanker.addresslib import address
>>>
>>> address.parse('foo@example.com', addr_spec_only=True)
foo@example.com

To parse an address list:

>>> from flanker.addresslib import address
>>>
>>> address.parse_list(['foo@example.com, bar@example.com, @example.com'])
[foo@example.com, bar@example.com]

To parse an address list as well as return a tuple containing the parsed addresses and the unparsable portions

>>> from flanker.addresslib import address
>>>
>>> address.parse_list(['foo@example.com, bar@example.com, @example.com'], as_tuple=True)
[foo@example.com, bar@example.com], ['@example.com']

To parse an address list in strict mode:

>>> from flanker.addresslib import address
>>>
>>> address.parse_list(['foo@example.com, bar@example.com, @example.com'], strict=True)
[foo@example.com, bar@example.com]

To validate an email address (parse as well as DNS, MX existence, and ESP grammar checks):

>>> from flanker.addresslib import address
>>>
>>> address.validate_address('foo@mailgun.com')
foo@mailgun.com

To validate an address list:

>>> from flanker.addresslib import address
>>>
>>> address.validate_list(['foo@mailgun.com, bar@mailgun.com, @mailgun.com'], as_tuple=True)
([foo@mailgun.com, bar@mailgun.com], ['@mailgun.com'])

MIME Parsing

For the following examples, message_string will be set to the following MIME message:

MIME-Version: 1.0
Content-Type: multipart/alternative; boundary=001a11c1d71697c7f004e6856996
From: Bob <bob@example.com>
To: Alice <alice@example.com>
Subject: hello, world
Date: Mon, 16 Sep 2013 12:43:03 -0700

--001a11c1d71697c7f004e6856996
Content-Type: text/plain; charset=us-ascii

Hello, *Alice*

--001a11c1d71697c7f004e6856996
Content-Type: text/html; charset=us-ascii

<p>Hello, <b>Alice</b></p>

--001a11c1d71697c7f004e6856996--

To parse a MIME message:

>>> from flanker import mime
>>>
>>> msg = mime.from_string(message_string)

MIME message headers (unicode multi-value dictionary with headers):

>>> from flanker import mime
>>>
>>> msg = mime.from_string(message_string)
>>> msg.headers.items()
[('Mime-Version', '1.0'),
 ('Content-Type',
  ('multipart/alternative', {'boundary': u'001a11c1d71697c7f004e6856996'})),
 ('From', 'Bob <bob@example.com>'),
 ('To', 'Alice <alice@example.com>'),
 ('Subject', 'hello, world'),
 ('Date', 'Mon, 16 Sep 2013 12:43:03 -0700')]

Useful content_type member with predicates:

>>> from flanker import mime
>>> msg = mime.from_string(message_string)
>>>
>>> msg.content_type.is_multipart()
True
>>>
>>> msg.content_type.is_singlepart()
False
>>>
>>> msg.content_type.is_message_container()
False

Decoded body of a message:

>>> from flanker import mime
>>> msg = mime.from_string(message_string)
>>>
>>> # None because message is multipart
>>> print msg.body
None
>>>
>>> for part in msg.parts:
       print 'Content-Type: {} Body: {}'.format(part, part.body)

Content-Type: (text/plain) Body: Hello, *Alice*
Content-Type: (text/html) Body: <p>Hello, <b>Alice</b></p>

>>> # None because no enclosed messages exist
>>> print msg.enclosed
None

Release files for flanker 0.9.11

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

Source distribution (sdist)

Source distribution for flanker 0.9.11
File Size Uploaded
flanker-0.9.11.tar.gz 105.2 kB Details

Release files / flanker-0.9.11.tar.gz

Download URL flanker-0.9.11.tar.gz
Size 105.2 kB
Tags Source
SHA-256 checksum
How to use checksums
974418e5b498fd3bcb3859c22e22d26495257f9cf98b744c17f2335aca86e001
BLAKE2b-256 checksum
How to use checksums
a644a2d77a6f2ad4d78912b549a97b915f43da3cc9e6dbfc2084520bdaa6d00e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/1.15.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/40.4.3 requests-toolbelt/0.9.1 tqdm/4.40.0 CPython/2.7.15

Release history Release notifications | RSS feed

This release

0.9.11 This release

1 release file

0.9.0

1 release file

0.8.5

1 release file

0.4.38

1 release file

0.4.37

1 release file

0.4.36

1 release file

0.4.35

1 release file

0.4.34

1 release file

0.4.33

1 release file

0.4.32

1 release file

0.4.31

1 release file

0.4.29

1 release file

0.4.28

1 release file

0.4.27

1 release file

0.4.26

1 release file

0.4.24

1 release file

0.4.23

1 release file

0.4.22

1 release file

0.4.21

1 release file

0.4.20

1 release file

0.4.15

1 release file

0.4.14

1 release file

0.4.13

1 release file

0.4.11

1 release file

0.4.10

1 release file

0.4.9

1 release file

0.4.8

1 release file

0.4.6

1 release file

0.4.5

1 release file

0.4.4

1 release file

0.3.38

1 release file

0.3.37

1 release file

0.3.36

1 release file

0.3.33

1 release file

0.3.29

1 release file

0.3.28

1 release file

0.3.27

1 release file

0.3.26

1 release file

0.3.25

1 release file

0.3.24

1 release file

0.3.23

1 release file

0.3.22

1 release file

0.3.21

1 release file

0.3.20

1 release file

0.3.15

1 release file

0.3.14

1 release file

0.3.13

1 release file

0.3.12

1 release file

0.3.11

1 release file

0.3.10

1 release file

0.3.9

1 release file

0.3.8

1 release file

0.3.6

1 release file

0.3.5

1 release file

0.3.4

1 release file

0.3.3

1 release file

0.3.2

1 release file

0.3.1

1 release file

0.3

1 release file

0.2.1

1 release file

0.2

1 release file

0.1

1 release file

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