Skip to main content

urlstd

PyPI PyPI - Python Version PyPI - License CI codecov

urlstd is a Python implementation of the WHATWG URL Living Standard.

This library provides URL class, URLSearchParams class, and low-level APIs that comply with the URL specification.

Supported APIs

  • URL class

    • class urlstd.parse.URL(url: str, base: Optional[str | URL] = None)
      • canParse: classmethod can_parse(url: str, base: Optional[str | URL] = None) -> bool
      • stringifier: __str__() -> str
      • href: readonly property href: str
      • origin: readonly property origin: str
      • protocol: property protocol: str
      • username: property username: str
      • password: property password: str
      • host: property host: str
      • hostname: property hostname: str
      • port: property port: str
      • pathname: property pathname: str
      • search: property search: str
      • searchParams: readonly property search_params: URLSearchParams
      • hash: property hash: str
      • URL equivalence: __eq__(other: Any) -> bool and equals(other: URL, exclude_fragments: bool = False) → bool
  • URLSearchParams class

    • class urlstd.parse.URLSearchParams(init: Optional[str | Sequence[Sequence[str | int | float]] | dict[str, str | int | float] | URLRecord | URLSearchParams] = None)
      • size: __len__() -> int
      • append: append(name: str, value: str | int | float) -> None
      • delete: delete(name: str, value: Optional[str | int | float] = None) -> None
      • get: get(name: str) -> str | None
      • getAll: get_all(name: str) -> tuple[str, ...]
      • has: has(name: str, value: Optional[str | int | float] = None) -> bool
      • set: set(name: str, value: str | int | float) -> None
      • sort: sort() -> None
      • iterable<USVString, USVString>: __iter__() -> Iterator[tuple[str, str]]
      • stringifier: __str__() -> str
  • Low-level APIs

  • Compatibility with standard library urllib

    • urlstd.parse.urlparse(urlstring: str, base: str = None, encoding: str = "utf-8", allow_fragments: bool = True) -> urllib.parse.ParseResult

      urlstd.parse.urlparse() ia an alternative to urllib.parse.urlparse(). Parses a string representation of a URL using the basic URL parser, and returns urllib.parse.ParseResult.

Basic Usage

To parse a string into a URL:

from urlstd.parse import URL
URL('http://user:pass@foo:21/bar;par?b#c')
# → <URL(href='http://user:pass@foo:21/bar;par?b#c', origin='http://foo:21', protocol='http:', username='user', password='pass', host='foo:21', hostname='foo', port='21', pathname='/bar;par', search='?b', hash='#c')>

To parse a string into a URL with using a base URL:

url = URL('?ffi&🌈', base='http://example.org')
url  # → <URL(href='http://example.org/?%EF%AC%83&%F0%9F%8C%88', origin='http://example.org', protocol='http:', username='', password='', host='example.org', hostname='example.org', port='', pathname='/', search='?%EF%AC%83&%F0%9F%8C%88', hash='')>
url.search  # → '?%EF%AC%83&%F0%9F%8C%88'
params = url.search_params
params  # → URLSearchParams([('ffi', ''), ('🌈', '')])
params.sort()
params  # → URLSearchParams([('🌈', ''), ('ffi', '')])
url.search  # → '?%F0%9F%8C%88=&%EF%AC%83='
str(url)  # → 'http://example.org/?%F0%9F%8C%88=&%EF%AC%83='

To validate a URL string:

from urlstd.parse import URL, URLValidator, ValidityState
URL.can_parse('https://user:password@example.org/')  # → True
URLValidator.is_valid('https://user:password@example.org/')  # → False
validity = ValidityState()
URLValidator.is_valid('https://user:password@example.org/', validity=validity)
validity.valid  # → False
validity.validation_errors  # → 1
validity.descriptions[0]  # → "invalid-credentials: input includes credentials: 'https://user:password@example.org/' at position 21"
URL.can_parse('file:///C|/demo')  # → True
URLValidator.is_valid('file:///C|/demo')  # → False
validity = ValidityState()
URLValidator.is_valid('file:///C|/demo', validity=validity)  # → False
validity.valid  # → False
validity.validation_errors  # → 1
validity.descriptions[0]  # → "invalid-URL-unit: code point is found that is not a URL unit: U+007C (|) in 'file:///C|/demo' at position 9"

To parse a string into a urllib.parse.ParseResult with using a base URL:

import html
from urllib.parse import unquote
from urlstd.parse import urlparse
pr = urlparse('?aÿb', base='http://example.org/foo/', encoding='utf-8')
pr  # → ParseResult(scheme='http', netloc='example.org', path='/foo/', params='', query='a%C3%BFb', fragment='')
unquote(pr.query)  # → 'aÿb'
pr = urlparse('?aÿb', base='http://example.org/foo/', encoding='windows-1251')
pr  # → ParseResult(scheme='http', netloc='example.org', path='/foo/', params='', query='a%26%23255%3Bb', fragment='')
unquote(pr.query, encoding='windows-1251')  # → 'a&#255;b'
html.unescape('a&#255;b')  # → 'aÿb'
pr = urlparse('?aÿb', base='http://example.org/foo/', encoding='windows-1252')
pr  # → ParseResult(scheme='http', netloc='example.org', path='/foo/', params='', query='a%FFb', fragment='')
unquote(pr.query, encoding='windows-1252')  # → 'aÿb'

Logging

urlstd uses standard library logging for validation error. Change the logger log level of urlstd if needed:

logging.getLogger('urlstd').setLevel(logging.ERROR)

Dependencies

Installation

  1. Configuring environment variables for icupy (ICU):

    • Windows:

      • Set the ICU_ROOT environment variable to the root of the ICU installation (default is C:\icu). For example, if the ICU is located in C:\icu4c:

        set ICU_ROOT=C:\icu4c
        

        or in PowerShell:

        $env:ICU_ROOT = "C:\icu4c"
        
      • To verify settings using icuinfo (64 bit):

        %ICU_ROOT%\bin64\icuinfo
        

        or in PowerShell:

        & $env:ICU_ROOT\bin64\icuinfo
        
    • Linux/POSIX:

      • If the ICU is located in a non-regular place, set the PKG_CONFIG_PATH and LD_LIBRARY_PATH environment variables. For example, if the ICU is located in /usr/local:

        export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH
        export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
        
      • To verify settings using pkg-config:

        $ pkg-config --cflags --libs icu-uc
        -I/usr/local/include -L/usr/local/lib -licuuc -licudata
        
  2. Installing from PyPI:

    pip install urlstd
    

Running Tests

Install dependencies:

pipx install tox
# or
pip install --user tox

To run tests and generate a report:

git clone https://github.com/miute/urlstd.git
cd urlstd
tox -e wpt

See result: tests/wpt/report.html

License

MIT License.

Metadata

Release files for urlstd 2023.7.26.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 urlstd 2023.7.26.1
File Size Uploaded Provenance
urlstd-2023.7.26.1.tar.gz 105.7 kB Without provenance Details

Built distribution (wheel)

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

Total release size: 143.0 kB

Release files / urlstd-2023.7.26.1.tar.gz

Download URL urlstd-2023.7.26.1.tar.gz
Size 105.7 kB
Tags Source
SHA-256 checksum
How to use checksums
8064d7a2034d3836cec844533b108af14429244d6119cfa6f268ef2bfc711358
BLAKE2b-256 checksum
How to use checksums
d534ccc954ae7638071e312069250e4de8fc6925ce36f7f7c97e946ad21d7a61
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.11.4

Release files / urlstd-2023.7.26.1-py3-none-any.whl

Download URL urlstd-2023.7.26.1-py3-none-any.whl
Size 37.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f0174403e956b3937038440e0da01742982b6e9711a2191b4ee79f84ae607b6f
BLAKE2b-256 checksum
How to use checksums
e2d216bd0ec40523996e527a3c948da40faee91682005ec932cfb7f955aa315c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.11.4

Security for urlstd 2023.7.26.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

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