repopath
pathlib for the repository trees of GitHub and GitLab, read-only.
GitHubPath("src/mod.py", owner="acme", repo="widgets", ref="v1.2") has the method
names, signatures and exception types of pathlib.Path, and GitLabPath does the same
for GitLab; RepoPath is the class that returns either. None needs a URI, and all
build on pathapi alone; with
uripath installed the same package also
provides the repo:, github: and gitlab: schemes. It is documented at
https://jose-pr.github.io/repopath/.
The classes are clients of the hosting services' REST APIs. They speak no git
protocol: there is no clone, no commit and no git: URL, and the tree is read-only.
Features
| Kind | Class | type= |
Detected for | API |
|---|---|---|---|---|
| GitHub and GitHub Enterprise | GitHubPath |
"github" |
github.com |
contents API at api.github.com, or https://<instance>/api/v3 |
| GitLab and self-hosted GitLab | GitLabPath |
"gitlab" |
gitlab.com |
REST API v4 at https://<instance>/api/v4 |
- A
pathlibpath in a repository:open,read_text,iterdir,glob,statand the rest, pluswalk,copyout of the tree andPathSynceras a source, frompathapi. Nothing connects until the first request. - One class for the kind:
RepoPath("f", owner="acme", repo="widgets", instance="github.com")is aGitHubPath; another instance needstype=, andRepoPath.kinds()lists the kinds. A kind is a subclass that registers itself. - Cheap listings: a directory is one request and each child carries the size and
type the listing gave, so
walk()andglob()cost one request per directory;stat()of a file is aHEAD. Listings past GitHub's 1,000-entry cap and GitLab's pages are read to the end. - Authentication that stays out of sight:
token=is sent as a bearer token to the API's own origin only, and shown by nostr(),repr(), pickle or error message. A token over plainhttp://to another host warns. - No library to install: requests go through
pathapi.http, on the standard library, with a replaceable transport. Errors are theOSErrortypespathlibraises,RateLimitError(aBlockingIOError) for a rate limit andBadReplyErrorfor a reply that is not the shape the API documents. - The
repo:,github:andgitlab:schemes foruripath:URIPath("github://github.com/acme/widgets/src/mod.py?ref=v1.2")is aGitHubURIPaththat delegates to aGitHubPath.
Installation
pip install repopath
Requires pathapi, which pip installs with it, and Python 3.9 or newer.
| Install | Adds |
|---|---|
pip install repopath |
the paths and the backends; no other library |
pip install "repopath[uri]" |
uripath and with it the repo:, github: and gitlab: schemes |
pip install "repopath[all]" |
all of the above |
Quick start
A path in a repository: the owner and repository are keywords, the segments are the
path inside it, and ref is a branch, a tag or a commit:
from repopath import GitHubPath
readme = GitHubPath("README.md", owner="psf", repo="requests")
print(readme.read_text()[:200])
for child in readme.parent.iterdir():
print(child.name, child.is_dir())
Another kind, or another instance: instance names the server, type the kind when
the instance does not tell, and token is the credential:
from repopath import GitLabPath, RepoPath
doc = RepoPath("doc", owner="gitlab-org", repo="gitlab", instance="gitlab.com")
private = RepoPath(
"src", owner="team/tools", repo="app", instance="git.example.org",
type="gitlab", token="glpat-...",
)
assert isinstance(doc, GitLabPath)
Copy a tree out of a repository with pathapi:
from pathapi import LocalPath
from repopath import GitHubPath
GitHubPath("docs", owner="psf", repo="requests", ref="main").copy(
LocalPath("docs-copy"), recursive=True
)
The schemes, with uripath installed:
from uripath import URIPath
print(URIPath("repo://github.com/psf/requests/README.md?ref=main").read_text()[:200])
API overview
| Module | Purpose |
|---|---|
repopath |
RepoPath, GitHubPath, GitLabPath, the backends RepoBackend and BaseRepoBackend, the exceptions RepoPathError, RateLimitError and BadReplyError, the warning InsecureTransportWarning and __version__ |
repopath.exceptions |
The exceptions and the warning |
repopath.uri |
RepoURIPath, GitHubURIPath and GitLabURIPath, the schemes of uripath (needs the uri extra) |
The full reference is on the documentation site;
an agent-oriented API summary ships inside the package as repopath/AGENTS.md.
Development
pip install -e ".[dev,all]"
python -m pytest -q -rs
The tests send every request to a fake of the API on the loopback interface; none
reaches another host. A test that needs uripath is skipped without it, so check the
skip list (-rs). Contributor notes (virtual environments, formatting, CI, releases) are
in the repository's AGENTS.md.
To preview the documentation: pip install -e ".[all,docs]" then mkdocs serve.
Changes are recorded in the changelog.
Releasing
This project follows Semantic Versioning and keeps a
CHANGELOG.md. Pushing a tag matching v* triggers the release
workflow: test gate → build (checking the tag names the version built) → a strict
docs build as a gate → GitHub release → publish. The release workflow never deploys
the docs site itself: for a final release its last job dispatches the docs workflow
at the tag, which owns every Pages deploy.
License
MIT — see LICENSE.
Metadata
Release files for repopath 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| repopath-0.1.0.tar.gz | 102.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| repopath-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 142.0 kB
Release files / repopath-0.1.0.tar.gz
| Download URL | repopath-0.1.0.tar.gz |
|---|---|
| Size | 102.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
260dade033271471fc787ad5f7e5d294b4ac76d9bec5b5493ed74f320a28ae56
|
|
BLAKE2b-256 checksum How to use checksums |
4e009ec508b4a84a3ea5656d9820e1949161221881765ea4ee64b11e053b9fa0
|
| 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 15, 2026.
Transparency logRelease files / repopath-0.1.0-py3-none-any.whl
| Download URL | repopath-0.1.0-py3-none-any.whl |
|---|---|
| Size | 39.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
5fc67de4f7a8a95a010c17ac6f5d19115d0cf4dc112039efd31bef8458a6a8bd
|
|
BLAKE2b-256 checksum How to use checksums |
a05a9f0a949bcfcb1b69ad1fc989e7ffd9aa82ee19e226c702f72abb55c541b0
|
| 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 15, 2026.
Transparency log