Registry / http-networking / hyperlink

hyperlink

JSON →
library21.0.0pypypi✓ verified 52d ago

hyperlink is a pure-Python library that provides a featureful, immutable, and semantically correct URL object, adhering to RFC 3986 and RFC 3987 for URIs and IRIs. It emphasizes correctness and ease of use, providing a robust model for URL parsing, construction, and transformation. The current stable version is 21.0.0, with major releases occurring approximately annually.

http-networkingserialization
pip install hyperlink
Install & Compatibility
Where this runs
tested against v21.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.925 runs
installs and imports cleanly · install 0.0s · import 0.048s · 18.9MB
glibc
py 3.103.925 runs
installs and imports cleanly · install 1.7s · import 0.043s · 19MB
17MB installed
● package 17MB
Code
Verified usage

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

URL
from hyperlink import URL
The lower-level URL class, also available as hyperlink.EncodedURL. Requires manual handling of encoding for special characters.
parse
from hyperlink import parse
The recommended top-level convenience function to parse a textual URL into a DecodedURL object.
DecodedURL
from hyperlink import DecodedURL
The recommended URL type for most operations, automatically handling encoding and decoding of components.

This quickstart demonstrates parsing a URL from a string, creating modified copies using the immutable API, navigating paths, accessing query parameters, and constructing a URL from individual components.

from hyperlink import parse # Parse a URL from text url = parse(u'http://github.com/python-hyper/hyperlink?utm_source=readthedocs') print(f"Original URL: {url.to_text()}") # Create a new URL by replacing components (URL objects are immutable) secure_url = url.replace(scheme=u'https', port=443) print(f"Secure URL: {secure_url.to_text()}") # Navigate to a child path or resolve relative paths org_url = secure_url.click(u'.') # Clicks to the root of the domain print(f"Org URL: {org_url.to_text()}") # Access query parameters utm_source = secure_url.get(u'utm_source')[0] print(f"UTM Source: {utm_source}") # Build a URL from components new_url_from_parts = URL(scheme=u'https', host=u'example.com', path=[u'api', u'v1'], query=((u'id', u'123'),)) print(f"Built from parts: {new_url_from_parts.to_text()}")
Debug
Known issues
gotchahyperlink's URL objects are immutable. All 'modifying' methods (e.g., `replace()`, `add()`, `drop()`, `set()`) return a *new* URL object with the changes, rather than modifying the object in place.
fix
Always assign the result of modifying methods to a new variable (e.g., `new_url = old_url.replace(...)`).
affects: All versions
gotchaThe `hyperlink.parse()` function, by default (since v18.0.0), returns a `DecodedURL` which automatically handles encoding/decoding of URL components. Directly instantiating `hyperlink.URL` (or `hyperlink.EncodedURL`) requires manual handling of URL-reserved characters, which can easily lead to incorrect encoding if not carefully managed.
fix
For most common use cases, prefer using `hyperlink.parse()` or `hyperlink.DecodedURL` to leverage automatic encoding/decoding. Use `hyperlink.URL` (or `hyperlink.EncodedURL`) only when explicit control over encoding is required.
affects: v18.0.0 and later
breakingIn version 19.0.0, the library changed how 'equals sign' characters are handled in query parameter *values*. Previously, they were escaped; now, they are not, aligning with standard web form encoding. This could be a breaking change if your system relied on the old escaping behavior for parsing or comparison.
fix
If existing code expects the old escaping behavior for query parameter values, it may need to be updated to account for the new standard or apply custom encoding/decoding.
affects: v19.0.0 onwards
breakingIn version 20.0.0, bug fixes related to hidden state on `URL` objects mean that constructor arguments like `rooted` and `uses_netloc` may be ignored if applying them would result in an invalid or unparseable URL. The object prioritizes validity over literal argument adherence in such cases.
fix
Be aware that the `URL` constructor may internally adjust or ignore certain arguments to maintain RFC compliance and validity. Always inspect the resulting `URL` object if relying on specific argument values.
affects: v20.0.0 onwards
gotchaThe 'URL' class, like other components of the 'hyperlink' library, must be explicitly imported (e.g., 'from hyperlink import URL') or accessed via the module namespace (e.g., 'hyperlink.URL') before it can be instantiated or used.
fix
Ensure that the 'URL' class is properly imported at the beginning of your script using 'from hyperlink import URL' or use 'hyperlink.URL(...)' after importing the module as 'import hyperlink'.
affects: All versions
gotchaThe `hyperlink.URL` class and other top-level components must be explicitly imported before use (e.g., `from hyperlink import URL`). Attempting to use them without proper import will result in a `NameError`.
fix
Ensure `from hyperlink import URL` or `import hyperlink` and then use `hyperlink.URL` (or other components) in your script.
affects: All versions
Errors
Common errors & fixes
hyperlink._url.URLParseError: port must not be empty: 'http:'
This error occurs when `hyperlink.parse()` attempts to parse a URL string that is syntactically malformed, specifically when a port is expected but not provided or is invalid within the scheme.
fix
Ensure the URL string provided to `hyperlink.parse()` adheres to valid URL syntax, especially concerning scheme, host, and port components. If the URL is external input, validate or sanitize it before parsing.
ValueError: invalid scheme: ' http'. Only alphanumeric, "+", "-", and "." allowed. Did you meant to call URL.from_text()?
This `ValueError` is raised by `hyperlink.parse()` when the URL scheme contains invalid characters, such as leading or trailing whitespace, or characters not permitted in a URL scheme.
fix
Remove any invalid characters or whitespace from the URL scheme. If you intend to parse a less strict 'text' format rather than a strict URL, consider using `URL.from_text()` if it better fits your use case, although `hyperlink.parse()` is generally more robust for standard URLs.
TypeError: expected str for text, got b''
The `hyperlink.parse()` method expects a string as input, but it received a bytes-like object or another non-string type.
fix
Convert the input to a string (e.g., by decoding a bytes object using `.decode('utf-8')`) before passing it to `hyperlink.parse()`.
AttributeError: can't set attribute
The `hyperlink.URL` object is immutable, meaning its attributes (like `host`, `scheme`, `path`) cannot be modified directly after creation. Attempts to assign new values to these attributes will result in an `AttributeError`.
fix
To modify a URL, use the provided fluent methods (e.g., `.replace()`, `.set()`, `.add()`) which return a *new* `URL` object with the desired changes, leaving the original object unchanged. For example, to change the host, use `new_url = old_url.set(host='example.com')`.
Upgrade
Version history
21.0.0latest on PyPI
Audit
Dependencies
idnarequiredUsed for Internationalized Domain Names (IDNA) processing, replacing Python's built-in facilities for stricter and more correct output.
Agent activity
10 hits · last 30 days
seranking-bot
4
ahrefsbot
3
node
2
Resources