Skip to main content

icaldav

CI PyPI version Documentation

A modern, local-first CalDAV client engine and embeddable ASGI server for Python, powered by ical.

icaldav transforms CalDAV from a notoriously brittle network protocol into a fast, reliable local synchronization pipeline. By pairing ical's type-safe data processing and recurrence engine with an asyncio-native sync engine and embeddable server router, icaldav completes the Python calendar ecosystem.

For a detailed breakdown of the local-first synchronization model, dual-path sync engine, and server scope, see the Design Document.


Why icaldav?

Interacting with CalDAV servers in Python has historically meant navigating fragmented RFC support, heavy server-side search bugs, and complex XML queries. icaldav redefines CalDAV integration by adopting a local-first synchronization architecture:

Rather than relying on distant servers to perform complex date filtering or recurrence expansions, icaldav efficiently streams raw .ics payloads into local storage and delegates data modeling, validation, and timeline generation to ical.

Feature icaldav python-caldav Raw WebDAV Tools
Async Native (asyncio) ✅ First-class (httpx) ⚠️ Partial wrapper module ❌ Sync only
Data Engine ical (Pydantic v2) icalendar / vobject ❌ None (raw XML/strings)
Recurrence Handling ✅ Local & exact (Timeline) ❌ Server-dependent ❌ None
Incremental Sync ✅ RFC 6578 + ETag Fallback ⚠️ Experimental ❌ Manual
Embeddable Server ✅ ASGI Router included ❌ Client only ❌ Client only
Type Safety ✅ Strict py.typed ⚠️ In progress ❌ None

Key Features

  • ⚡ Async Client (CalDavClient): Built with asyncio and httpx for high-performance HTTP/2 communication and type-safe ical Pydantic models.
  • 🔄 Resilient Sync Engine (CalDavSyncManager): Supports RFC 6578 (WebDAV Collection Synchronization) for single-request delta fetches, with automatic ETag fallback for non-RFC 6578 servers (e.g. Radicale, iCloud).
  • 🧩 Local-First Recurrence & Queries: Performs time-range slicing and recurrence expansions locally via ical's Timeline, avoiding server-side calendar-query bugs.
  • 🚀 Embeddable ASGI Server Router (CalDavRouter): Mount a minimalist CalDAV server endpoint into FastAPI, Starlette, or aiohttp applications to expose calendars to native iOS, macOS, or Thunderbird clients.

Installation

uv add icaldav

Or with pip:

pip install icaldav

Requires Python 3.12+.


Quickstart

Syncing a Remote Calendar Down to Local Storage

import asyncio
from icaldav import CalDavClient, CalDavSyncManager
from icaldav.store import SQLiteStore

async def main():
    async with CalDavClient(
        url="https://caldav.example.com",
        username="user",
        password="password",
    ) as client:
        # Discover calendar collections
        calendars = await client.get_calendars()
        calendar = calendars[0]

        # Sync events down to a local store
        store = SQLiteStore("calendar_cache.db")
        sync_manager = CalDavSyncManager(client=client, collection=calendar, store=store)
        await sync_manager.run()

        # Query locally using `ical`'s timeline
        local_calendar = await store.get_calendar()
        for event in local_calendar.timeline.today():
            print(f"{event.start}: {event.summary}")

asyncio.run(main())

Embedding a CalDAV Server Endpoint

from fastapi import FastAPI
from icaldav.server import CalDavRouter
from icaldav.provider import LocalCalendarProvider

app = FastAPI()

# Expose local calendars to native mobile & desktop clients
app.include_router(
    CalDavRouter(provider=LocalCalendarProvider()),
    prefix="/caldav",
)

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

icaldav-0.0.1.tar.gz (7.6 kB view details)

Uploaded Source

Built Distribution

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

icaldav-0.0.1-py3-none-any.whl (7.4 kB view details)

Uploaded Python 3

File details

Details for the file icaldav-0.0.1.tar.gz.

File metadata

  • Download URL: icaldav-0.0.1.tar.gz
  • Upload date:
  • Size: 7.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for icaldav-0.0.1.tar.gz
Algorithm Hash digest
SHA256 6d9d35d510c27bcd5fed6a2807b6f592f5bd3d2629d458a87a44b72a14aa2149
MD5 1ada9935776f7e5110578b1cb00b99db
BLAKE2b-256 8cecc935600828e2c9f44250d5f6cd67ad6c563d945565dfb9499b7bd13e5f7a

See more details on using hashes here.

Provenance

The following attestation bundles were made for icaldav-0.0.1.tar.gz:

Publisher: publish.yaml on allenporter/icaldav

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

File details

Details for the file icaldav-0.0.1-py3-none-any.whl.

File metadata

  • Download URL: icaldav-0.0.1-py3-none-any.whl
  • Upload date:
  • Size: 7.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for icaldav-0.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 0eda504db92f4e992e397f2e8b72f668a2356cf61a1e84f8bc9e2847b6009459
MD5 d1dbb153f7b351540fafaae225b2098c
BLAKE2b-256 8f335008f311dfa52d1ebd8a4e1e9eb35fe1ea0cf5d0f587685bd8e63f5e636c

See more details on using hashes here.

Provenance

The following attestation bundles were made for icaldav-0.0.1-py3-none-any.whl:

Publisher: publish.yaml on allenporter/icaldav

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

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page