During the last few days, I’ve been busy writing a CalDAV client library for work. This is a requirement because we are going to integrate calendars from various sources in one of our websites.
CalDAV is clearly the way to go, but as far as libraries go, the only one I’ve been able to find was CalDAVClientLibrary, which, quite frankly, scares me. I’m already familiar with CalendarServer, and I can’t qualify that as “lightweight”, “simple” or “easily installable”.
CalDAV
In case you don’t know what CalDAV is, it’s an extension to webdav for calendaring, and is defined in rfc4791. If you don’t feel like reading all of this, it’s mostly HTTP with XML requests and responses, but not always, which is why it gets kind of weird…
Example requests
Creating a calendar:
MKCOL /calendars/pythoncaldav-test HTTP/1.1
Host: example.com
Accept-Encoding: identity
Content-Length: 249
<?xml version='1.0' encoding='utf-8'?>
<D:mkcol xmlns:C="urn:ietf:params:xml:ns:caldav" xmlns:D="DAV:">
<D:set>
<D:prop>
<D:resourcetype>
<D:collection>
<C:calendar-collection/>
</D:collection>
</D:resourcetype>
<D:displayname>Yep
</D:prop>
</D:set>
</D:mkcol>
Deleting a calendar:
DELETE /calendars/pythoncaldav-test HTTP/1.1 Host: example.com Accept-Encoding: identity
caldav
The version I just released is the very beginning of the project: it has basic functionality, but lacks many things, such as error handling and full support for the protocol. The documentation also needs a lot more work.
Example
I tried keeping the API very simple, and close to what an ORM would be used like, here’s an example:
import caldav
from caldav.lib.namespace import ns
# Principal url
url = "https://user:pass@hostname/user/Calendar"
vcal = """BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Example Corp.//CalDAV Client//EN
BEGIN:VEVENT
UID:1234567890
DTSTAMP:20100510T182145Z
DTSTART:20100512T170000Z
DTEND:20100512T180000Z
SUMMARY:This is an event
END:VEVENT
END:VCALENDAR
"""
client = caldav.DAVClient(url)
principal = caldav.Principal(url)
calendars = principal.calendars()
if len(calendars) > 0:
calendar = calendars[0]
print "Using calendar", calendar
print "Renaming"
calendar.set_properties({ns("D", "displayname"): "Test calendar",})
print calendar.get_properties([ns("D", "displayname"),])
event = caldav.Event(client, data = vcal, parent = calendar).save()
print "Event", event, "created"
print "Looking for events after 2010-05-01"
results = calendar.date_search("20100501T000000Z")
for event in results:
print "Found", event
Links
I released caldav and its documentation on pypi, and the code is on bitbucket:
- Pypi: http://pypi.python.org/pypi/caldav
- Documentation: http://packages.python.org/caldav
- Bitbucket: http://bitbucket.org/cyrilrbt/caldav
Contributions are welcome!
Subscribe
