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.5.8.tar.gz (342.3 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.5.8-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.5.8.tar.gz.

File metadata

  • Download URL: nfs_rs-0.5.8.tar.gz
  • Upload date:
  • Size: 342.3 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.5.8.tar.gz
Algorithm Hash digest
SHA256 7ce47c6920a45d480c73c02c0551122e3ea4389e2d75f557165d0771f5980df8
MD5 7dd3abb5989aa02670a5dffac918d6d9
BLAKE2b-256 aafaf34fed3200c4b850f889153ac1a711839c4996cd5e801572034facc6e0cd

See more details on using hashes here.

Provenance

The following attestation bundles were made for nfs_rs-0.5.8.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.5.8-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for nfs_rs-0.5.8-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 aa499c9e9d06b9d08b4ff3bb934d4cd0db9e2b7e3608f65c20533b095ddca9d4
MD5 b71d6ddcf3ebb990367e7d4762d2e1dd
BLAKE2b-256 ecbb588d55011d2cc970c9172bf589d6c7b1ccc6b0e554177303e5382384e3f0

See more details on using hashes here.

Provenance

The following attestation bundles were made for nfs_rs-0.5.8-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

0.6.0

2 files

This release

0.5.8 This release

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