uripath
One pathlib-style API for URIs. URIPath("https://..."), URIPath("zip:...")
and URIPath("ftp://...") return the class registered for the scheme, and each
has the method names, signatures and exception types of pathlib.Path: write
code once and it works against a local file, an archive member, an FTP or
WebDAV server, a web directory or, through repopath, a GitHub or GitLab
repository. uripath
builds on pathapi, which holds
the Path base classes, the local, in-memory, FTP and archive paths, glob and
PathSyncer.
Deliberate behavioral differences from pathlib are listed, with their
reasons, in Divergences from pathlib.
Installation
pip install pathapi-uri
It requires pathapi and netimps, which pip installs with it; its one
extra, cli, adds the uripath command
(pip install "pathapi-uri[cli]"). The schemes of this package run on the standard
library, including HTTP. sftp:, s3:, gs:, az:, repo:, github: and
gitlab: are provided by other distributions:
| Provides | Install |
|---|---|
sftp: |
pip install "sftppath[paramiko]" (or [asyncssh]) |
s3:, gs:, az: |
pip install "objpath[s3]" (or [gs], [az]) |
repo:, github:, gitlab: |
pip install repopath |
the requests HTTP transport |
pip install pathapi-requests |
Tour
URIs: URIPath returns the class registered for the scheme:
from uripath import URIPath
report = URIPath("file:data/report.txt")
report.parent.mkdir(parents=True, exist_ok=True)
report.write_text("hello")
print(type(report).__name__, report.read_text())
inline = URIPath("data:text/plain;base64,aGVsbG8=")
print(type(inline).__name__, inline.read_text())
Archives: a member inside a zip or tar, the archive itself addressed by any URI:
import zipfile
from uripath import URIPath
with zipfile.ZipFile("backup.zip", "w") as archive:
archive.writestr("etc/config.ini", "[main]\n")
member = URIPath("zip:file:backup.zip!/etc/config.ini")
print(member.read_text())
Remote schemes share the same contract (these need a reachable server):
from uripath import URIPath
for child in URIPath("https://example.com/data/").iterdir():
print(child.name, child.stat().st_size)
print(URIPath("ftp://user@host/pub/README").read_text())
exists(), is_dir(), iterdir(), glob(), walk(),
read_text()/write_text(), copy()/move() and rm() behave the same way
on every backend; what a backend cannot do (for example mkdir() over plain
HTTP, or any write to a data: path) raises NotImplementedError. The
per-scheme capabilities are in Schemes.
Where to go next
- Schemes: capability matrix and per-scheme notes (timeouts, authentication, security defaults).
- CLI: the
uripathcommand. - Extending: add a scheme by subclassing
URIPath, and verify it with the bundled contracts. - Divergences from pathlib: every deliberate behavioral
difference from
pathlib.Path. - API Reference: generated from the docstrings.
- Changelog.