Registry / http-networking / rfc3986

rfc3986

JSON →
library2.0.0pypypi✓ verified 27d ago

rfc3986 is a Python implementation of RFC 3986 including validation and authority parsing. This module also supports RFC 6874, which adds support for zone identifiers to IPv6 Addresses. It provides APIs for parsing, validating, and building URIs, with convenience methods for `urllib.parse` compatibility. The current version is 2.0.0, released in January 2022, and the project appears to be actively maintained.

pip install rfc3986
INSTALL
IMPORT
SIG · RFC3986
R
rfc3986
http-networkingpythonv2.0.0
Install
1.6s avg
Import
187ms
Disk
16MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.93.13
musl
3.93.13
Install & Compatibility
Where this runs
tested against v2.0.0 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.103.95 runs
installs and imports cleanly · install 0.0s · import 0.186s · 18MB
glibc
py 3.103.95 runs
installs and imports cleanly · install 1.6s · import 0.188s · 19MB
16MB installed
● package 16MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

uri_reference
from rfc3986 import uri_reference
Use this for strict RFC 3986 compliant URI parsing and validation.
urlparse
from rfc3986 import urlparse
Use this for API compatibility with Python's standard library `urllib.parse.urlparse`, but be aware of parsing differences for malformed URIs due to `rfc3986`'s strictness.
validators
from rfc3986 import validators
Import the validators module to create custom URI validation rules.

This quickstart demonstrates how to parse a URI string into a `URIReference` object, access its components, validate it using a `Validator` instance with custom rules, and construct a new URI using `URIBuilder`.

from rfc3986 import uri_reference, validators # Parsing a URI Reference uri_str = 'https://user:pass@example.com:8080/path/to/resource?key=value#fragment' uri = uri_reference(uri_str) print(f"Scheme: {uri.scheme}") # Output: https print(f"Host: {uri.host}") # Output: example.com print(f"Path: {uri.path}") # Output: /path/to/resource print(f"Query: {uri.query}") # Output: key=value # Validating a URI validator = validators.Validator().allow_schemes(['https']).allow_hosts(['example.com']) if validator.validate(uri): print("URI is valid according to custom rules.") else: print("URI is NOT valid according to custom rules.") # Building a URI from rfc3986 import URIBuilder builder = (URIBuilder() .add_scheme('mailto') .add_path('user@domain.com')) mailto_uri = builder.finalize() print(f"Built URI: {mailto_uri.unsplit()}") # Output: mailto:user@domain.com
Debug
Known issues
gotcharfc3986 strictly adheres to RFC 3986, which can result in different parsing behavior for malformed or non-standard URIs compared to `urllib.parse`. Specifically, an authority component must be preceded by `//`, otherwise, `rfc3986` may interpret it as part of the path.
fix
Always ensure URIs conform strictly to RFC 3986, especially by including `//` before the authority. For compatibility with `urllib.parse`'s looser parsing, use `rfc3986.urlparse()` but be aware of its limitations and the stricter RFC 3986 interpretation.
affects: All versions
gotchaThe library does not support Internationalized Resource Identifiers (IRIs) as defined in RFC 3987. It focuses solely on RFC 3986.
fix
If IRI support is required, consider using a different library (e.g., `rfc3987` or `uritools` with caution) or pre-process IRIs to ensure they are RFC 3986 compatible before passing them to `rfc3986`.
affects: All versions
gotchaThe `uri_reference.is_valid()` method might, in some edge cases, accept invalid hostnames or out-of-range port numbers (according to open GitHub issues).
fix
For critical security-sensitive URI validation, do not solely rely on `is_valid()`. Implement additional checks for hostname formats and port number ranges, or combine with a custom `Validator` instance that explicitly defines allowed components.
affects: 2.0.0
gotchaThe `copy_with` method on parsed URI objects (from `uri_reference` or `urlparse`) replaces existing components rather than extending them. For example, adding a path segment replaces the entire path.
fix
If you need to extend path components or append to query parameters, retrieve the existing components, manipulate them as strings or lists, and then pass the complete new value to `copy_with`. Alternatively, use `URIBuilder` and its methods for more controlled incremental building.
affects: All versions
gotchaThe `allow_schemes()` method in `rfc3986.validators.Validator` expects individual scheme strings or an unpacked iterable as arguments. Passing a list object directly (e.g., `allow_schemes(['https'])`) results in an `AttributeError` when the library attempts to call `.lower()` on the list object instead of a string.
fix
To specify schemes for validation, pass each scheme as a separate argument (e.g., `validator.allow_schemes('https', 'http')`). If you have a list of schemes, unpack it using the `*` operator: `validator.allow_schemes(*['https', 'http'])`.
affects: All versions
gotchaThe `Validator.allow_schemes()` method expects scheme names as individual string arguments (e.g., `allow_schemes('https', 'http')`), not as a single list argument. Passing a list (e.g., `allow_schemes(['https'])`) will lead to an `AttributeError: 'list' object has no attribute 'lower'` when the method attempts to normalize the scheme.
fix
When using `Validator.allow_schemes()`, provide each scheme as a separate string argument. If you have a list of schemes, unpack it using the `*` operator (e.g., `validator.allow_schemes(*my_schemes)` or `validator.allow_schemes('https')` for a single scheme).
affects: All versions
Errors
Common errors & fixes
rfc3986.exceptions.InvalidURIError: Invalid scheme component: 'http://'
The input string provided to `URIReference.from_string` does not conform to RFC 3986 standards for a valid URI, or a specific component is malformed.
fix
from rfc3986 import URIReference
try:
    uri = URIReference.from_string('https://example.com/path') # Correct URI
except URIReference.InvalidURIError as e:
    print(f"Error: {e}")
ImportError: cannot import name 'parse_uri' from 'rfc3986'
The function or class `parse_uri` does not exist at the top level of the `rfc3986` module; the primary method for parsing URIs is the `from_string` class method of `URIReference` (or `URI`).
fix
from rfc3986 import URIReference
uri = URIReference.from_string('https://example.com')
AttributeError: 'NoneType' object has no attribute 'host'
This error occurs when attempting to access a sub-component (like `host`) on an optional URI part (like `authority`) that is `None` because it's not present in the parsed URI reference (e.g., for relative URIs).
fix
from rfc3986 import URIReference
uri = URIReference.from_string('/path/to/resource') # A relative URI without authority
if uri.authority:
    print(uri.authority.host)
else:
    print("No authority component for this URI")
Upgrade
Version history
2.0.0latest on PyPI · released Jan 10, 2022
Audit
Dependencies
pythonrequiredRequires Python 3.7 or later.
Agent activity
18 hits · last 30 days
node
14
OpenAI (training)
2
Resources
rfc3986 — pip install rfc3986 · libregistry