Skip to main content

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

nfs_rs-0.6.0.tar.gz (351.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

nfs_rs-0.6.0-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (3.0 MB view details)

Uploaded CPython 3.11+manylinux: glibc 2.17+ x86-64

File details

Details for the file nfs_rs-0.6.0.tar.gz.

File metadata

  • Download URL: nfs_rs-0.6.0.tar.gz
  • Upload date:
  • Size: 351.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for nfs_rs-0.6.0.tar.gz
Algorithm Hash digest
SHA256 3d1238605c70e78dc9e10b529add0917a1ecf7090a13e9a001fadddbfe02c91d
MD5 8af4f5fa4687ae854184c50d2b0ee1b7
BLAKE2b-256 66e20a7cefa2095647ec1df649503d142ed0f3aa24301adb00ee9895cee73261

See more details on using hashes here.

Provenance

The following attestation bundles were made for nfs_rs-0.6.0.tar.gz:

Publisher: release.yml on JayTsu-sh/nfs-rs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file nfs_rs-0.6.0-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for nfs_rs-0.6.0-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 cbc24befcccdf96270562761f61a7c38673959b6542b685dbf03bc1ea2990d4f
MD5 d1429f756d90719c9974521de9c1162f
BLAKE2b-256 236f948f21d0e6350c9c137c473d3da7455c240eb2d28cafd8070c74719511c9

See more details on using hashes here.

Provenance

The following attestation bundles were made for nfs_rs-0.6.0-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on JayTsu-sh/nfs-rs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.8.4

2 files

0.8.3

2 files

0.8.2

2 files

0.8.1

2 files

0.7.1

2 files

0.7.0

2 files

0.6.1

2 files

This release

0.6.0 This release

2 files

0.5.8

2 files

0.5.7

2 files

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