nfs-rs for Python
nfs-rs provides typed synchronous and asyncio clients for accessing NFS
exports directly from Python without a kernel mount or a C NFS library.
- NFSv3 (the default when no version is selected)
- experimental NFSv4.0, selected explicitly as
4.0 - NFSv4.1, including negotiated file-layout pNFS
- synchronous and native async APIs
- file, directory, metadata, link, and extended-attribute operations
- PEP 561 type information included
Authentication uses AUTH_SYS. Kerberos and RPCSEC_GSS are not implemented.
Select a protocol version
The Python API accepts exactly "3", "4.0", and "4.1". Select one in the
URL or pass an ordered fallback list to versions:
from nfs_rs import Client, Version
# NFSv3 is the default when the URL has no version query parameter.
with Client.connect("nfs://server.example.com/export") as client:
assert client.version is Version.NFS_V3
# Select one exact NFSv4 minor version.
with Client.connect("nfs://server.example.com/export?version=4.0") as client:
assert client.version is Version.NFS_V4_0
with Client.connect("nfs://server.example.com/export?version=4.1") as client:
assert client.version is Version.NFS_V4_1
# Try NFSv4.1 first, then NFSv4.0, then NFSv3.
with Client.connect(
"nfs://server.example.com/export",
versions=["4.1", "4.0", "3"],
) as client:
print("negotiated", client.version)
The ambiguous selector "4" and unimplemented NFSv4.2 are rejected. NFSv4.0
is experimental and requires the exact "4.0" selector.
Install
python -m pip install nfs-rs
The wheel supports CPython 3.11 or newer on Linux/glibc x86_64.
Connect and work with files
from nfs_rs import Client
url = "nfs://server.example.com/export?version=4.1&noresvport=true"
with Client.connect(url, connect_timeout=10, operation_timeout=30) as client:
client.mkdir("incoming", parents=True, exist_ok=True)
written = client.write_bytes("incoming/hello.txt", b"hello NFS")
assert written == 9
info = client.stat("incoming/hello.txt")
print(info.size, info.mode, info.uid, info.gid)
with client.open("incoming/hello.txt", "rb") as source:
assert source.read(5) == b"hello"
assert source.read_at(6, 3) == b"NFS"
for entry in client.scandir("incoming"):
print(entry.name, entry.info.size)
Paths are relative to the export root. Absolute paths, .. escapes, NUL bytes,
and byte-string paths are rejected. File modes are binary: rb, wb, ab,
r+b, w+b, and a+b.
Asyncio
import asyncio
from nfs_rs import AsyncClient
async def main() -> None:
url = "nfs://server.example.com/export?version=4.1&noresvport=true"
async with await AsyncClient.connect(url) as client:
await client.mkdir("outgoing", exist_ok=True)
await client.write_bytes("outgoing/result.bin", b"result")
async with await client.open("outgoing/result.bin", "rb") as source:
assert await source.read() == b"result"
async for entry in client.scandir("outgoing"):
print(entry.path)
asyncio.run(main())
Metadata and extended attributes
import os
from nfs_rs import Client
with Client.connect("nfs://server/export?version=4.1") as client:
client.chmod("data.bin", 0o640)
assert client.access("data.bin", os.R_OK)
if client.capabilities.named_attributes:
client.setxattr("data.bin", "user.content-type", b"application/octet-stream")
assert client.getxattr("data.bin", "user.content-type") == b"application/octet-stream"
print(client.listxattr("data.bin"))
client.removexattr("data.bin", "user.content-type")
Capability values are negotiated with the server. Check them before depending on optional behavior such as named attributes, ACL support, callbacks, or pNFS.
Errors and uncertain outcomes
from nfs_rs import Client, NfsNotFoundError, NfsUncertainOutcomeError
with Client.connect("nfs://server/export?version=4.1") as client:
try:
data = client.read_bytes("missing.bin")
except NfsNotFoundError:
data = b""
try:
client.rename("staging.bin", "committed.bin")
except NfsUncertainOutcomeError as error:
# Do not retry blindly: the server may have completed the operation.
print(error.recovery_action, error.outcome)
print(client.exists("committed.bin"))
Built-in families such as FileNotFoundError, PermissionError,
IsADirectoryError, TimeoutError, and ConnectionError also work. For
modifying operations, inspect recovery_action, outcome, and
client.recovery_events() before retrying.
Documentation
See the complete Python user guide for URL options, export discovery, all filesystem operations, streaming large files, concurrency, cancellation, recovery, and the support matrix.
License
Apache-2.0
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file nfs_rs-0.6.1.tar.gz.
File metadata
- Download URL: nfs_rs-0.6.1.tar.gz
- Upload date:
- Size: 353.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5fd567d5855bccc9e5819cde8509d86d60a43a10cd37977fb5698777549557e2
|
|
| MD5 |
6e24b4f3991ab579a0c4e89657fdf97b
|
|
| BLAKE2b-256 |
8a372630705872c227e4f4481aae29f99e82e663ace1ad72406a44e892fb733b
|
Provenance
The following attestation bundles were made for nfs_rs-0.6.1.tar.gz:
Publisher:
release.yml on JayTsu-sh/nfs-rs
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
nfs_rs-0.6.1.tar.gz -
Subject digest:
5fd567d5855bccc9e5819cde8509d86d60a43a10cd37977fb5698777549557e2 - Sigstore transparency entry: 2695793859
- Sigstore integration time:
-
Permalink:
JayTsu-sh/nfs-rs@3aa565427d4f4e3df2127e3cf5bc803b730ed962 -
Branch / Tag:
refs/tags/v0.6.1 - Owner: https://github.com/JayTsu-sh
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@3aa565427d4f4e3df2127e3cf5bc803b730ed962 -
Trigger Event:
push
-
Statement type:
File details
Details for the file nfs_rs-0.6.1-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: nfs_rs-0.6.1-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 3.2 MB
- Tags: CPython 3.11+, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
db51ff1b75d40196449d7562f53064d9a26ca036255bfdb5c8a365650d797670
|
|
| MD5 |
8e6cf43f103ac430ca44f6cd1e2bd98b
|
|
| BLAKE2b-256 |
7ec19f71cfc01b05200d8940195231abe189185c766312cc5d0a8f1fcfcb973d
|
Provenance
The following attestation bundles were made for nfs_rs-0.6.1-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:
Publisher:
release.yml on JayTsu-sh/nfs-rs
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
nfs_rs-0.6.1-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl -
Subject digest:
db51ff1b75d40196449d7562f53064d9a26ca036255bfdb5c8a365650d797670 - Sigstore transparency entry: 2695793961
- Sigstore integration time:
-
Permalink:
JayTsu-sh/nfs-rs@3aa565427d4f4e3df2127e3cf5bc803b730ed962 -
Branch / Tag:
refs/tags/v0.6.1 - Owner: https://github.com/JayTsu-sh
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@3aa565427d4f4e3df2127e3cf5bc803b730ed962 -
Trigger Event:
push
-
Statement type: