API reference

Both classes are importable from the package root:

from action0.url import Url, Params

Url

class action0.url.base.Url(url=None, *, scheme=None, hostname=None, path=None, query=None, path_params=None, fragment=None, username=None, password=None, port=None, authority=None)[source]

Bases: object

Python presentation of a parsed URL to allow easy manipulation of its parts.

Example:

>>> url = Url("https://www.example.com/path/filename.json?foo=bar")
>>> url.query.set("foo", "baz")
>>> url.as_str()
'https://www.example.com/path/filename.json?foo=baz'
>>> url.query.add("a", "b")
>>> url.as_str()
'https://www.example.com/path/filename.json?foo=baz&a=b'
>>> # allow params with multiple values (added at the end)
>>> url.query.add("foo", "123")
>>> url.as_str()
'https://www.example.com/path/filename.json?foo=baz&a=b&foo=123'
>>> url.hostname = "action0.com"
>>> url.port = 8443
>>> url.path = "/public/index.html"
>>> url.username = "user"
>>> url.password = "pass"
>>> url.fragment = "fragment"
>>> url.as_str()
'https://user:pass@action0.com:8443/public/index.html?foo=baz&a=b&foo=123#fragment'

Based on the named tuple that urllib.parse.urlparse() returns.

Parameters:

If a url is given it will use this as base and other parameters will replace/overwrite the parts of the url string.

The parts of a parsed url are stored percent-decoded, i.e. the attributes hold the readable values (“my file.html”, not “my%20file.html”) and as_str() encodes them again; values given as keyword arguments are expected to be unencoded as well. Be aware that an encoded “/” (%2F) inside a path segment is decoded like everything else and hence becomes a segment separator when the URL is rendered again.

Example:

>>> url = Url("https://www.example.com/path/filename.json")
>>> url.as_str()
'https://www.example.com/path/filename.json'
>>> url = Url("https://www.example.com/path/filename.json", path="/hello/world.html")
>>> url.as_str()
'https://www.example.com/hello/world.html'
>>> url = Url("https://www.example.com?foo=bar", query={"bar": "baz"})
>>> url.as_str()
'https://www.example.com?bar=baz'
Parameters:
Raises:

ValueError – if authority is combined with hostname or port

property authority: str

The “hostname:port” combination (also known as netloc), just the hostname if no port is set. Assigning a string of the same form replaces hostname and port.

property parent: Url

A copy of this URL with the last path segment removed; the other parts are kept. Like in pathlib, the parent of the root is the root.

property name: str

The last path segment (usually the file name); “” if the path is empty or ends with a “/”. Assigning replaces the last segment.

property suffix: str

The file extension of name including the “.”; “” if there is none.

as_str()[source]

Assemble the (possibly modified) parts back into a URL string. The parts are percent-encoded as needed and a non-ASCII hostname is IDNA-encoded (punycode).

Return type:

str

Returns:

the string representation of the URL

Raises:

UnicodeError – if the hostname cannot be IDNA-encoded

join(other)[source]

Resolve another, possibly relative, URL against this one — like a browser resolves a link on a page — wrapping urllib.parse.urljoin().

Example:

>>> Url("https://example.com/a/b").join("c")
Url(https://example.com/a/c)
>>> Url("https://example.com/a/b").join("/x")
Url(https://example.com/x)
Parameters:

other (str | Url) – the URL to resolve against this one

Return type:

Url

Returns:

a new Url, this instance is not modified

__truediv__(segment)[source]

Return a copy with the segment(s) appended to the path, always joined with exactly one “/”.

Example:

>>> Url("https://example.com") / "api" / "v2"
Url(https://example.com/api/v2)
Parameters:

segment (str) – the path segment(s) to append

Return type:

Url

Returns:

a new Url, this instance is not modified

copy(**overrides)[source]

An independent copy of this URL, optionally with parts replaced.

Example:

>>> url = Url("https://example.com:8443/index.html")
>>> url.copy(scheme="http", port=None)
Url(http://example.com/index.html)
Parameters:

overrides (Any) – any URL part accepted by the constructor

Return type:

Url

Returns:

a new Url, this instance is not modified

Raises:
  • TypeError – on part names the constructor does not know

  • ValueError – if authority is combined with hostname or port

origin()[source]

The origin — scheme, hostname and port only — e.g. for same-origin comparisons or as a base to build new URLs on.

Return type:

Url

Returns:

a new Url with only scheme, hostname and port set

normalize()[source]

A normalized copy of this URL (RFC 3986 style): scheme and hostname lowercased, the scheme’s default port removed, “.” and “..” path segments resolved, and an empty path becomes “/” if there is a hostname.

Example:

>>> Url("https://example.com:443/a/./b/../c").normalize()
Url(https://example.com/a/c)
Return type:

Url

Returns:

a new Url, this instance is not modified

as_dict()[source]

The URL parts as a plain dictionary (query and path params as dictionaries of value lists), e.g. for debugging or serialization. Contains the real password — use repr() for a redacted view.

Return type:

dict[str, Any]

Returns:

a dictionary of all URL parts

as_parse_result()[source]

The URL as the named tuple urllib.parse.urlparse() returns, for interoperability with stdlib-based code. The parts are percent-encoded like in as_str().

Return type:

ParseResult

Returns:

the ParseResult of the assembled URL string

is_absolute()[source]
Return type:

bool

Returns:

whether the URL has a hostname

is_relative()[source]
Return type:

bool

Returns:

whether the URL has no hostname

__eq__(other)[source]

Two Urls are equal if all their parts are equal. The order of query parameter names doesn’t matter (?a=1&b=2 equals ?b=2&a=1), the order of multiple values of the same name does.

Parameters:

other (object) – the Url to compare with

Return type:

bool

Returns:

whether the URLs are equal

__str__()[source]

Return str(self).

Return type:

str

__repr__()[source]

Return repr(self).

Return type:

str

Params

action0.url.params.ParamValue = str | int | float | bool

A single parameter value; non-strings are coerced to strings on the way in (bools become the web-style "true" / "false").

action0.url.params.ParamTypes = typing.Iterable[tuple[str, str | int | float | bool | typing.Iterable[str | int | float | bool]]] | typing.Mapping[str, str | int | float | bool | typing.Iterable[str | int | float | bool]] | str

Everything that can initialize a Params instance: a query string, a mapping, or an iterable of name/value(s) tuples.

class action0.url.params.Params(params=None, separator='&')[source]

Bases: MutableMapping[str, str]

Allows easy manipulation of URL query parameters and URL path parameters, it supports single and multiple values for a key.

Internally the parameters are an ordered list of (key, value) pairs, so the full representation order — including values of one key interleaved with other keys — round-trips losslessly: Params("a=1&b=2&a=3").as_str() is "a=1&b=2&a=3" again. The grouped views (as_dict(), as_tuples()) collect the values per key instead.

Params implements typing.MutableMapping: the mapping view (params[key], get(), items(), values(), …) works with a single value per key — the last one, like singles(). Multi-value access is available through get_all(), add(), as_dict() and as_tuples().

Example:

>>> params = Params("b=2&a=1")
>>> params["a"]
'1'
>>> params.add("a", 3)
>>> params.get_all("a")
['1', '3']
>>> params.as_str()
'b=2&a=1&a=3'
>>> params.as_str(sort=True)
'a=1&a=3&b=2'
Parameters:
  • params (Iterable[tuple[str, str | int | float | bool | Iterable[str | int | float | bool]]] | Mapping[str, str | int | float | bool | Iterable[str | int | float | bool]] | str | None, default: None)

  • separator (Literal['&', ';'], default: '&')

  • params – the initial key-value(s) to set, either as a string which will be parsed using parse_qsl, another Params instance whose pairs are copied, or as a list of tuples or a dictionary. The values can be single values or lists of values; non-string values are coerced to strings (bools become “true” / “false”). Unlike parse_qsl’s default, blank values are kept (“a=&b=1” keeps “a”), so parsing and re-rendering is lossless.

  • separator – either a ‘&’ or a ‘;’ to separate the key-value pairs in the string representation (also used when copying another Params instance)

__getitem__(key)[source]

The single value of the parameter; if the parameter has multiple values, the last one — like singles(). Use get_all() for all values.

Parameters:

key (str) – the parameter name

Return type:

str

Returns:

the (last) value of the parameter

Raises:

KeyError – if the parameter does not exist

__setitem__(key, value)[source]

Replace all values of the parameter, same as set().

Parameters:
Return type:

None

__delitem__(key)[source]

Remove the parameter with all its values.

Parameters:

key (str) – the parameter name

Raises:

KeyError – if the parameter does not exist

Return type:

None

__iter__()[source]
Return type:

Iterator[str]

Returns:

an iterator over the distinct parameter names in the order of their first pair

__len__()[source]
Return type:

int

Returns:

the number of distinct parameter names

__contains__(key)[source]
Parameters:

key (object) – the parameter name

Return type:

bool

Returns:

whether a parameter with this name exists

get_all(key)[source]

All values of the parameter in representation order; use params[key] or get() for the single-value view.

Parameters:

key (str) – the parameter name

Return type:

list[str]

Returns:

the values as a list, an empty list if the parameter does not exist

add(key, value)[source]

Add a parameter with a single value or multiple values, appended at the end of the representation. If it is a single value, the query string equivalent would be something like “foo=bar”. If it is a list of values, the query string equivalent would be something like “foo=bar&foo=baz&foo=abc”. Existing values are kept (in place).

Parameters:
Return type:

None

remove(key, value=None)[source]

If only a key is given all values with this name are removed. If a value or a list of values is given only the matching values are removed.

Parameters:
  • key (str) – the name of the parameter to remove (or from which values are to be removed)

  • value (str | int | float | bool | Iterable[str | int | float | bool] | None, default: None) – if given, only matching value(s) are to be removed not the entire parameter

Return type:

list[str]

Returns:

a list of removed values

set(key, value)[source]

Replace all value(s) of the key with the value(s) given, at the position of the key’s first pair (new keys are appended at the end). Setting an empty list of values removes the key.

Parameters:
Return type:

None

update(params=None, **kwargs)[source]

Merge the given parameters into this instance: values of keys that already exist are replaced (like dict.update, at the position of the key’s first pair), other keys are appended. Accepts the same forms as the constructor (query string, mapping, iterable of tuples, Params instance) plus keyword arguments.

Parameters:
Return type:

None

clear()[source]

Remove all parameters, returns a dictionary of the cleared parameters (unlike MutableMapping.clear which returns None).

Return type:

dict[str, list[str]]

Returns:

a dictionary of removed keys and values

sort()[source]

Sort the pairs in place by their name and then by their values — the persistent equivalent of as_str(sort=True), which only sorts the rendered output.

Return type:

None

as_str(sort=False)[source]

A string representation of the parameters, url encoded.

Parameters:

sort (bool, default: False) – sort the parameters by their name and then by their value, otherwise they’ll be returned in the order of the representation

Return type:

str

Returns:

the url encoded query / file parameter string, e.g. “foo=bar&bar=baz&bar=abc”

as_tuples()[source]
Return type:

Iterator[tuple[str, list[str]]]

Returns:

the parameters grouped per key as an iterator of tuples with the values being lists of strings

as_single_tuples()[source]
Return type:

Iterator[tuple[str, str]]

Returns:

the parameter representation as an iterator of tuples of the key and a single value, in representation order. This means keys with multiple values will appear more than once.

as_dict()[source]
Return type:

dict[str, list[str]]

Returns:

the parameters grouped per key as a dictionary with the parameter names as key and the values as lists of strings

singles()[source]

For those who are really sure that each parameter has only one value and do not want to bother with the lists for the values, this method will return only the last value for each key.

WARNING: be aware, if the key has multiple values, only one of those will be returned for the key!

Return type:

dict[str, str]

Returns:

a dictionary with the parameters with a single value for each key

uniq_tuples()[source]

Same as singles() but returning tuples.

WARNING: be aware, if the key has multiple values, only one of those will be returned for the key!

Return type:

Iterator[tuple[str, str]]

Returns:

an iterable of tuples with a key and a single value

__eq__(other)[source]

Params are equal when they hold the same keys with the same values in the same per-key order; the order of the keys and the separator don’t matter. Plain mappings are converted to Params before comparing.

Parameters:

other (object) – the Params instance or mapping to compare with

Return type:

bool

Returns:

whether the parameters are equal

__str__()[source]

Return str(self).

Return type:

str

__repr__()[source]

Return repr(self).

Return type:

str