Skip to main content

A Python implementation of RFC 3986 including validation and authority parsing. Coming soon: Reference Resolution.

Installation

Simply use pip to install rfc3986 like so:

pip install rfc3986

License

Apache License Version 2.0

Example Usage

The following are the two most common use cases envisioned for rfc3986.

Replacing urlparse

To parse a URI and receive something very similar to the standard library’s urllib.parse.urlparse

from rfc3986 import urlparse

ssh = urlparse('ssh://user@git.openstack.org:29418/openstack/glance.git')
print(ssh.scheme)  # => ssh
print(ssh.userinfo)  # => user
print(ssh.params)  # => None
print(ssh.port)  # => 29418

To create a copy of it with new pieces you can use copy_with:

new_ssh = ssh.copy_with(
    scheme='https'
    userinfo='',
    port=443,
    path='/openstack/glance'
)
print(new_ssh.scheme)  # => https
print(new_ssh.userinfo)  # => None
# etc.

Strictly Parsing a URI and Applying Validation

To parse a URI into a convenient named tuple, you can simply:

from rfc3986 import uri_reference

example = uri_reference('http://example.com')
email = uri_reference('mailto:user@domain.com')
ssh = uri_reference('ssh://user@git.openstack.org:29418/openstack/keystone.git')

With a parsed URI you can access data about the components:

print(example.scheme)  # => http
print(email.path)  # => user@domain.com
print(ssh.userinfo)  # => user
print(ssh.host)  # => git.openstack.org
print(ssh.port)  # => 29418

It can also parse URIs with unicode present:

uni = uri_reference(b'http://httpbin.org/get?utf8=\xe2\x98\x83')  # ☃
print(uni.query)  # utf8=%E2%98%83

With a parsed URI you can also validate it:

if ssh.is_valid():
    subprocess.call(['git', 'clone', ssh.unsplit()])

You can also take a parsed URI and normalize it:

mangled = uri_reference('hTTp://exAMPLe.COM')
print(mangled.scheme)  # => hTTp
print(mangled.authority)  # => exAMPLe.COM

normal = mangled.normalize()
print(normal.scheme)  # => http
print(mangled.authority)  # => example.com

But these two URIs are (functionally) equivalent:

if normal == mangled:
    webbrowser.open(normal.unsplit())

Your paths, queries, and fragments are safe with us though:

mangled = uri_reference('hTTp://exAMPLe.COM/Some/reallY/biZZare/pAth')
normal = mangled.normalize()
assert normal == 'hTTp://exAMPLe.COM/Some/reallY/biZZare/pAth'
assert normal == 'http://example.com/Some/reallY/biZZare/pAth'
assert normal != 'http://example.com/some/really/bizzare/path'

If you do not actually need a real reference object and just want to normalize your URI:

from rfc3986 import normalize_uri

assert (normalize_uri('hTTp://exAMPLe.COM/Some/reallY/biZZare/pAth') ==
        'http://example.com/Some/reallY/biZZare/pAth')

You can also very simply validate a URI:

from rfc3986 import is_valid_uri

assert is_valid_uri('hTTp://exAMPLe.COM/Some/reallY/biZZare/pAth')

Requiring Components

You can validate that a particular string is a valid URI and require independent components:

from rfc3986 import is_valid_uri

assert is_valid_uri('http://localhost:8774/v2/resource',
                    require_scheme=True,
                    require_authority=True,
                    require_path=True)

# Assert that a mailto URI is invalid if you require an authority
# component
assert is_valid_uri('mailto:user@example.com', require_authority=True) is False

If you have an instance of a URIReference, you can pass the same arguments to URIReference#is_valid, e.g.,

from rfc3986 import uri_reference

http = uri_reference('http://localhost:8774/v2/resource')
assert uri.is_valid(require_scheme=True,
                    require_authority=True,
                    require_path=True)

# Assert that a mailto URI is invalid if you require an authority
# component
mailto = uri_reference('mailto:user@example.com')
assert uri.is_valid(require_authority=True) is False

Alternatives

  • rfc3987

    This is a direct competitor to this library, with extra features, licensed under the GPL.

  • uritools

    This can parse URIs in the manner of RFC 3986 but provides no validation and only recently added Python 3 support.

  • Standard library’s urlparse/urllib.parse

    The functions in these libraries can only split a URI (valid or not) and provide no validation.

Contributing

This project follows and enforces the Python Software Foundation’s Code of Conduct.

If you would like to contribute but do not have a bug or feature in mind, feel free to email Ian and find out how you can help.

The git repository for this project is maintained at https://github.com/sigmavirus24/rfc3986

0.4.1 – 2016-08-22

  • Normalize URIs constructed using ParseResult.from_parts and ParseResultBytes.from_parts

0.4.0 – 2016-08-20

  • Add ParseResult.from_parts and ParseResultBytes.from_parts class methods to easily create a ParseResult

  • When using regular expressions, use [0-9] instead of \d to avoid finding ports with “numerals” that are not valid in a port

0.3.1 – 2015-12-15

  • Preserve empty query strings during normalization

0.3.0 – 2015-10-20

  • Read README and HISTORY files using the appropriate codec so rfc3986 can be installed on systems with locale’s other than utf-8 (specifically C)

  • Replace the standard library’s urlparse behaviour

0.2.2 – 2015-05-27

  • Update the regular name regular expression to accept all of the characters allowed in the RFC. Closes bug #11 (Thanks Viktor Haag). Previously URIs similar to “http://http-bin.org” would be considered invalid.

0.2.1 – 2015-03-20

  • Check that the bytes of an IPv4 Host Address are within the valid range. Otherwise, URIs like “http://256.255.255.0/v1/resource” are considered valid.

  • Add 6 to the list of unreserved characters. It was previously missing. Closes bug #9

0.2.0 – 2014-06-30

  • Add support for requiring components during validation. This includes adding parameters require_scheme, require_authority, require_path, require_path, require_query, and require_fragment to rfc3986.is_valid_uri and URIReference#is_valid.

0.1.0 – 2014-06-27

  • Initial Release includes validation and normalization of URIs

Release files for rfc3986 0.4.1

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

Source distribution (sdist)

Source distribution for rfc3986 0.4.1
File Size Uploaded
rfc3986-0.4.1.tar.gz 22.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for rfc3986 0.4.1
File Interpreter ABI Platform
rfc3986-0.4.1-py2.py3-none-any.whl Python 3, Python 2 none any Details

Total release size: 44.2 kB

Release files / rfc3986-0.4.1.tar.gz

Download URL rfc3986-0.4.1.tar.gz
Size 22.4 kB
Tags Source
SHA-256 checksum
How to use checksums
5ac85eb132fae7bbd811fa48d11984ae3104be30d44d397a351d004c633a68d2
BLAKE2b-256 checksum
How to use checksums
17b6f2d5df2e369142010fb5d91b12a962643e1a2d3578b04ff22276a5c53238
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No

Release files / rfc3986-0.4.1-py2.py3-none-any.whl

Download URL rfc3986-0.4.1-py2.py3-none-any.whl
Size 21.8 kB
Tags Python 2 Python 3
SHA-256 checksum
How to use checksums
6823e63264be3da1d42b3ec0e393dc8e6d03fd5e28d4291b797c76cf33759061
BLAKE2b-256 checksum
How to use checksums
8253c3ee5a1869fdf5d1d02c344ed939769b886178ec7ba91d5200e1c779bc87
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No

Release history Release notifications | RSS feed

2.0.0

2 release files

1.5.0

2 release files

1.4.0

2 release files

1.3.2

2 release files

1.3.1

2 release files

1.3.0

2 release files

1.2.0

2 release files

1.1.0

2 release files

1.0.0

2 release files

This release

0.4.1 This release

2 release files

0.4.0

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.0

2 release files

0.0.0

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