Skip to main content

pathapi

Version Python versions License: MIT Docs CI

A robust, extensible pathlib-like base for any resource addressable as a path. Same method names, signatures, semantics and exception types as pathlib.Path wherever a pathlib.Path equivalent exists: write code once against Path and it runs against your local disk, an in-memory tree, an FTP server or the members of a zip or tar file, and against any path class built on it. It has no dependencies. Deliberate differences from pathlib are listed in Divergences from pathlib.

pathapi was published as pathlib-next up to 0.10.0; pip install pathlib-next now installs a shim that depends on this package. See the changelog for the migration from pathlib_next.

Features

Class Read Write List Stat mkdir Delete rename
local path (LocalPath) Yes Yes Yes Yes Yes Yes Yes
in-memory (MemPath) Yes Yes Yes Yes Yes Yes No (move() copies)
FTP and FTPS (FTPPath) Yes Yes Yes (MLSD, NLST fallback) Yes Yes Yes Yes
zip members (ZipPath) Yes Local archive only Yes Yes Local archive only Local archive only Local archive only
tar members (TarPath, incl. gz/bz2/xz) Yes No Yes Yes No No No
ArchivePath As ZipPath/TarPath for the format it detects

Every class gets glob(), walk(), copy()/move(), rm() and PathSyncer from the base classes; LocalPath and the other classes replace some of them where the backend has a faster way.

  • One path interface over local files, in-memory trees, FTP servers and archive members, and over any class built on Path.
  • MemPath: a virtual filesystem for tests, mocks and transient data.
  • FTPPath, ZipPath, TarPath, ArchivePath: an FTP server and the members of a zip or tar file as paths, on the standard library alone.
  • pathapi.http: HTTPClient and a transport contract for HTTP requests on the standard library (redirects that never carry Authorization to another origin, TLS verified by default, a proxies= provider); another HTTP library plugs in as a transport through the pathapi.http_transports entry-point group. AsyncHTTPClient is the same client for an event loop, over async transports registered in pathapi.http_async_transports.
  • PathSyncer: one-way, content-compared tree sync between any two implementations, with dry runs and event hooks.
  • Extensible: subclass Path for any resource, and verify it with the bundled pytest contracts.

Paths for other places are separate distributions built on this one:

Distribution Provides
uripath URIPath: one class for any URI, with the schemes file:, data:, ftp:, zip:, tar:, http: and dav:, and the uripath command

Installation

pip install pathapi

There are no extras and no dependencies: everything above runs on the standard library. pytest is needed only to import pathapi.testing and pathapi.http.testing.

Quick start

Local filesystem, as pathlib.Path:

from pathapi import Path

p = Path("data") / "report.txt"
p.parent.mkdir(parents=True, exist_ok=True)
p.write_text("hello")
print(p.read_text())

In memory, no disk I/O:

from pathapi.mempath import MemPath

p = MemPath("/config/settings.json")
p.parent.mkdir(parents=True, exist_ok=True)
p.write_text('{"debug": true}')
print([child.name for child in p.parent.iterdir()])

Archive members: the segments are the member path and the archive is any path:

import zipfile
from pathapi import ZipPath

with zipfile.ZipFile("backup.zip", "w") as archive:
    archive.writestr("etc/config.ini", "[main]\n")

member = ZipPath("etc/config.ini", archive="backup.zip")
print(member.read_text())
print([child.name for child in member.parent.iterdir()])

FTP: nothing connects until the first operation:

from pathapi import FTPPath

for child in FTPPath("/pub", host="ftp.example.com", user="anonymous").iterdir():
    print(child.name, child.stat().st_size)

Copy and sync across classes:

from pathapi import Path
from pathapi.mempath import MemPath
from pathapi.sync import PathSyncer

source = MemPath("/site")
(source / "css").mkdir(parents=True)
(source / "index.html").write_text("<h1>hi</h1>")

PathSyncer(remove_missing=True).sync(source, Path("site-copy"))
print(sorted(p.name for p in Path("site-copy").iterdir()))

API overview

Module Purpose
pathapi.path Pathname/Path base classes and the derived operations
pathapi.fspath LocalPath, PosixPathname, WindowsPathname
pathapi.mempath MemPath in-memory filesystem
pathapi.ftp FTPPath, FTPBackend (FTP and FTPS on ftplib)
pathapi.archive ZipPath, TarPath, ArchivePath (members of a zip or tar file), make_archive, unpack_archive
pathapi.http HTTPClient, HTTPTransport, HTTPResponse, AsyncHTTPClient, ThreadedTransport (HTTP requests on http.client, and from an event loop)
pathapi.protocols Stat, Chmod, BinaryOpen, NativeChecksum
pathapi.sync PathSyncer, SyncEvent, PathAndStat
pathapi.glob the glob engine behind Path.glob()
pathapi.checksum md5, sha256, stream, native
pathapi.providers the helpers a class built on Path calls
pathapi.exceptions PathError, NonRelativePatternError
pathapi.testing pytest contracts for custom implementations
pathapi.http.testing testing support (not stable API): the pytest suite that holds an HTTP transport to the promises of the built-in one

The full reference is on the documentation site; an agent-oriented API summary ships inside the package as pathapi/AGENTS.md.

Async

AsyncPath(path) wraps any pathapi path for use inside an event loop: the pure members stay plain, every method that does I/O is a coroutine of the same name, listings are async iterators and open() gives an AsyncFile. Each call runs the sync method on a worker thread, so every backend works at once and the loop is never blocked; it is not a native async client.

import asyncio
from pathapi import AsyncPath, LocalPath

async def main():
    root = AsyncPath(LocalPath("."))
    async for entry in root.iterdir():
        print(entry.name, await entry.is_dir())

asyncio.run(main())

Extending

Subclass Path for a resource of your own (MemPath is the reference), as worked through in Extending. pathapi.testing provides the pytest contracts (PurePathContract, ReadPathContract, PathContract, AsyncPathContract) and populate_fixture_tree() that every class of the package and of the distributions above is verified with.

Supported Python versions

Python 3.9 through 3.14. CI runs the full suite on Ubuntu for every version from 3.9 to 3.14, on Windows and macOS for 3.9 and 3.14, and with nothing but pytest and pyftpdlib installed on 3.9 and 3.14.

Development

pip install -e ".[dev]"
python -m pytest -q -rs

Tests that need an optional package are skipped when it is missing, so check the skip list (-rs). Contributor notes (virtual environments, formatting, CI, releases) are in the repository's AGENTS.md; benchmarks are described in Benchmarks. To preview the documentation: pip install -e ".[docs]" then mkdocs serve.

Changes are recorded in the changelog.

Releasing

  1. Move the [Unreleased] entries of CHANGELOG.md under a new ## [x.y.z] - <date> heading and add its link definition at the bottom.
  2. Bump version in pyproject.toml in the same commit.
  3. Before 1.0 the minor version changes only when the documented API breaks; new methods, new optional arguments and fixes are patch releases.
  4. Run the full suite on the oldest and the newest supported Python, mkdocs build --strict and python -m build.
  5. Push main, then the v* tag: the release workflow tests, builds and publishes to PyPI and creates the GitHub release.

License

MIT; see LICENSE.

Metadata

Release files for pathapi 0.1.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pathapi 0.1.2
File Size Uploaded Provenance
pathapi-0.1.2.tar.gz 664.2 kB With provenance Details

Built distribution (wheel)

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

Total release size: 1.0 MB

Release files / pathapi-0.1.2.tar.gz

Download URL pathapi-0.1.2.tar.gz
Size 664.2 kB
Tags Source
SHA-256 checksum
How to use checksums
195ccfbd34b9100466fc0dd0605a948c71968bdcf332200d86bf2fbbc73ab1ac
BLAKE2b-256 checksum
How to use checksums
7fa3d191cb9e57a4d6f8a7f12b11a6f2adc89be17dc3ab736dd5c3c1fd1e9cee
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 17, 2026.

Transparency log

Release files / pathapi-0.1.2-py3-none-any.whl

Download URL pathapi-0.1.2-py3-none-any.whl
Size 340.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d211da618c491666d30a148c8c5dda9bf74057f6a86fe20164950630acd224a5
BLAKE2b-256 checksum
How to use checksums
84b294aa028401bb1a38ee3f7854ffc4e2f3f31876bb8cf5aec2a559c744d5eb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 17, 2026.

Transparency log

Security for pathapi 0.1.2

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.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for pathapi-0.1.2.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 17, 2026.

Transparency log

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