URL Utilities¶
The url
module in escudeiro
provides a modern, object-oriented interface for parsing, constructing, and manipulating URLs. It supports all standard URL components and offers a fluent, immutable API for safe and expressive URL handling.
Why?¶
Manipulating URLs with the Python standard library can be verbose and error-prone:
from urllib.parse import urlparse, urlunparse
parsed = urlparse("https://user:pass@host:8080/path?query=1#frag")
new_url = urlunparse(parsed._replace(path="/newpath"))
With escudeiro.url
, you get a high-level, immutable URL
object with convenient accessors and modifiers:
from escudeiro.url import URL
url = URL("https://user:pass@host:8080/path?query=1#frag")
print(url.path) # "/path"
new_url = url.add(path="newpath")
print(str(new_url)) # "https://user:pass@host:8080/path/newpath?query=1#frag"
Features¶
- Full URL parsing and construction (scheme, userinfo, host, port, path, query, fragment)
- Immutable, chainable API for safe modifications
- Component-wise access and modification via
.add()
and properties - Convenient helpers for query, path, fragment, and netloc manipulation
- Type-safe and dataclass-friendly
Usage¶
Adding Query Parameters¶
from escudeiro.url import URL
url = URL("https://www.example.com/path?key1=value1").add(
query={"key2": "value2", "key3": "value3"}
)
print(url.query) # "key1=value1&key2=value2&key3=value3"
print(str(url)) # "https://www.example.com/path?key1=value1&key2=value2&key3=value3"
Adding Path Segments¶
url = URL("https://www.example.com/path").add(path="subpath")
print(url.path) # "/path/subpath"
print(str(url)) # "https://www.example.com/path/subpath"
Adding a Fragment¶
url = URL("https://www.example.com/path").add(fragment="section1")
print(url.fragment) # "section1"
print(str(url)) # "https://www.example.com/path#section1"
Modifying Netloc (Host, Userinfo, Port)¶
from escudeiro.url import Netloc
url = URL("https://www.example.com/path").add(netloc="www.example2.com")
print(url.netloc) # "www.example2.com"
print(str(url)) # "https://www.example2.com/path"
url = URL("https://www.example.com/path").add(
netloc_obj=Netloc.from_args(
host="www.example2.com",
username="username",
password="password",
)
)
print(url.netloc) # "username:password@www.example2.com"
print(str(url)) # "https://username:password@www.example2.com/path"
url = URL("https://www.example.com/path").add(
netloc_obj=Netloc.from_args(host="www.example2.com", port=8080)
)
print(url.netloc) # "www.example2.com:8080"
print(str(url)) # "https://www.example2.com:8080/path"
Composing Multiple Components¶
url = URL("https://www.example.com/path?key1=value1").add(
path="subpath",
query={"key2": "value2", "key3": "value3"},
fragment="section1",
netloc_obj=Netloc.from_args(
host="www.example2.com",
username="username",
password="password",
port=8080,
)
)
print(url.path) # "/path/subpath"
print(url.query) # "key1=value1&key2=value2&key3=value3"
print(url.fragment) # "section1"
print(url.netloc) # "username:password@www.example2.com:8080"
print(str(url))
# "https://username:password@www.example2.com:8080/path/subpath?key1=value1&key2=value2&key3=value3#section1"
Immutability and Copying¶
All operations on URL
objects return new instances. You can safely copy and compare URLs:
url = URL("https://www.example.com/path?key1=value1").add(
query={"key2": "value2", "key3": "value3"}
)
url2 = url.copy()
assert url2 is not url
assert url2 == url
API Reference¶
URL
class¶
- Construction:
URL(str_or_url)
- Properties:
.scheme
,.netloc
,.path
,.query
,.fragment
- Methods:
.add(...)
: Return a new URL with updated components (path
,query
,fragment
,netloc
,netloc_obj
).copy()
: Return a new identical URL instance.encode()
: Return the URL as a string
Netloc
, Path
, Query
, Fragment
¶
- Helper classes for manipulating respective URL components.
Netloc.from_args(host, username=None, password=None, port=None)
: Construct a netloc string from components.Path
,Query
, andFragment
can be used similarly for their respective components.
Notes¶
- All modifications are immutable and chainable.
- Query parameters can be provided as dicts or strings.
- Use
netloc_obj
for advanced netloc construction (user, password, port). - The API is type-safe and works well with dataclasses.