Skip to main content

aiowebdav2

aiowebdav2 is a typed asyncio WebDAV client for Python 3.13+.

Installation

pip install aiowebdav2

Remote API

The Client API is remote-only. It exposes WebDAV resources as paths and does not read from or write to the local filesystem.

import asyncio

from aiowebdav2 import Client


async def main() -> None:
    async with Client(
        "https://webdav.example.com/remote.php/dav/files/me/",
        username="me",
        password="secret",
    ) as client:
        await client.mkdir("/docs/", parents=True, exist_ok=True)
        await client.write("/docs/readme.txt", b"hello")

        info = await client.stat("/docs/readme.txt")
        print(info.path, info.size)

        for child in await client.list("/docs/"):
            print(child.path, child.is_dir)

        data = await client.read("/docs/readme.txt")
        print(data)


asyncio.run(main())

Main remote operations:

  • exists(path) -> bool
  • stat(path) -> ResourceInfo
  • is_dir(path) -> bool
  • list(path="/", recursive=False) -> list[ResourceInfo]
  • mkdir(path, parents=False, exist_ok=False) -> None
  • delete(path) -> None
  • copy(source, target, depth=None, overwrite=True) -> None
  • move(source, target, overwrite=False) -> None
  • read(path) -> bytes
  • iter_read(path) -> AsyncIterator[bytes]
  • write(path, data, content_length=None) -> None
  • quota() -> QuotaInfo
  • get_property(path, property_request) -> Property | None
  • get_properties(path, property_requests) -> list[Property]
  • list_properties(path, properties=...) -> dict[str, list[Property]]
  • set_property(path, property) -> None
  • set_properties(path, properties) -> None
  • lock(path) -> Lock
  • unlock(path, lock_token) -> None

Filesystem Helpers

Local file transfer helpers live in aiowebdav2.filesystem. They depend on a Client, but the client does not depend on local paths. Install the optional extra before using them:

pip install "aiowebdav2[filesystem]"
from pathlib import Path
import asyncio

from aiowebdav2 import Client
from aiowebdav2.filesystem import download_file, download_tree, upload_file, upload_tree


async def main() -> None:
    async with Client(
        "https://webdav.example.com",
        username="me",
        password="secret",
    ) as client:
        await upload_file(client, Path("readme.txt"), "/docs/readme.txt", parents=True)
        await download_file(client, "/docs/readme.txt", Path("readme.txt"))
        await upload_tree(client, Path("docs"), "/docs/", concurrency=4)
        await download_tree(client, "/docs/", Path("docs"), concurrency=4)


asyncio.run(main())

Filesystem helper operations:

  • download_file(client, remote_path, local_path, progress=None) -> None
  • upload_file(client, local_path, remote_path, parents=False, progress=None) -> None
  • download_tree(client, remote_path, local_path, overwrite=False, concurrency=1, progress=None) -> None
  • upload_tree(client, local_path, remote_path, concurrency=1, progress=None) -> None

Progress callbacks receive (current_bytes, total_bytes | None) and may be sync or async callables.

Authentication

Pass username and password, or a bearer token in ClientOptions.

import asyncio

from aiowebdav2 import Client, ClientOptions


async def main() -> None:
    async with Client(
        "https://webdav.example.com",
        username="me",
        password="secret",
    ) as client:
        await client.list("/")

    async with Client(
        "https://webdav.example.com",
        options=ClientOptions(token="token"),
    ) as client:
        await client.list("/")


asyncio.run(main())

Sessions and Options

Client owns its aiohttp session unless an external session is passed.

import asyncio

from aiohttp import ClientSession, ClientTimeout

from aiowebdav2 import Client, ClientOptions


async def main() -> None:
    async with ClientSession() as session:
        client = Client(
            "https://webdav.example.com",
            options=ClientOptions(
                session=session,
                timeout=ClientTimeout(total=30),
                verify_ssl=True,
                root="/",
                chunk_size=65536,
                proxy="http://127.0.0.1:8080",
                proxy_headers={"Proxy-Authorization": "Basic ..."},
            ),
        )


asyncio.run(main())

Models

from dataclasses import dataclass
from datetime import datetime


@dataclass(frozen=True, slots=True, kw_only=True)
class ResourceInfo:
    path: str
    name: str
    is_dir: bool
    size: int | None = None
    modified: datetime | None = None
    created: datetime | None = None
    etag: str | None = None
    content_type: str | None = None

Property, PropertyRequest, and QuotaInfo are also frozen, slotted dataclasses.

Development

uv sync --group dev
uv run pytest --cov-report=term-missing
uv run ruff check .
uv run ruff format --check .
uv run mypy aiowebdav2

Metadata

Release files for aiowebdav2 1.0.0

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

Source distribution (sdist)

Source distribution for aiowebdav2 1.0.0
File Size Uploaded Provenance Actions
aiowebdav2-1.0.0.tar.gz 134.0 kB With provenance Details for aiowebdav2-1.0.0.tar.gz

Built distribution (wheel)

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

Total release size: 150.6 kB

Release files / aiowebdav2-1.0.0.tar.gz

Download URL aiowebdav2-1.0.0.tar.gz
Size 134.0 kB
Tags Source
SHA-256 checksum
How to use checksums
981c3437dfd7031ae6265b555f8c9a5badf7beb188e7f69094e64b97a46f2c31
BLAKE2b-256 checksum
How to use checksums
e2dcbc2861178071ae561d2c40705e752cb9e8fd92eb8e1c26302a068cb6c529
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 Nov 2, 2026.

Transparency log

Release files / aiowebdav2-1.0.0-py3-none-any.whl

Download URL aiowebdav2-1.0.0-py3-none-any.whl
Size 16.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a74da8d700d75adad1dc0d962f0c8bb8d9ef293fa5074eba3f1e82ec4b925704
BLAKE2b-256 checksum
How to use checksums
3bb0ad05159c80eee5deb92df615ce36b5044c976467793ac5ae49d43225293e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 Nov 2, 2026.

Transparency log

Security for aiowebdav2 1.0.0

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 aiowebdav2-1.0.0.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 Nov 2, 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