This is the specification. The parser in this package implements it, and any other parser of the file (caldav's, for one) should follow it. When the code and this page disagree, one of them has a bug.
A JSON or YAML mapping of section names (strings) to sections. A section is a mapping. The file is read as JSON first (so tab-indented JSON works, which YAML refuses), then as YAML with a safe loader: tags that build Python objects are refused.
work:
kind: caldav
url: https://dav.example.com/
username: alice
password_command: [pass, show, dav/work]
fastmail:
kind: jmap
url: https://api.fastmail.com/jmap/session
username: alice@example.com
password_keyring: fastmail
notes:
url: ~/calendars/notes
legacy: # an old caldav section, read unchanged
caldav_url: https://old.example.com/
caldav_user: alice
everything:
contains: [work, fastmail, notes, legacy]An empty file is an empty configuration. Anything else that is not a mapping of mappings is an error.
The first of these that applies is used:
- a path given by the caller;
CALENDARING_CONFIG_FILE;CALDAV_CONFIG_FILE;- the first file that exists of
$XDG_CONFIG_HOME/pycal/calendar.yaml(XDG_CONFIG_HOMEdefaults to~/.config),~/.config/caldav/calendar.conf,~/.config/caldav/calendar.yaml,~/.config/caldav/calendar.json,~/.config/calendar.conf,/etc/calendar.conf,/etc/caldav/calendar.conf.
A path from 1–3 that does not exist is an error. When none of 4 exists, there is no configuration, which is not an error. The first file of 4 that exists is used even if it is empty; caldav moves on to the next one instead.
The paths in 4 after the first are caldav's, so that existing files keep working where they are.
The section name is the one given by the caller, else
CALENDARING_CONFIG_SECTION, else CALDAV_CONFIG_SECTION, else default.
A name that matches no section is an error, with one exception, as in
caldav: when no name was given at all and the file has no default
section, there is no configuration.
A name expands to one or more leaf sections:
- a plain name is that section;
- a section with
contains: [a, b, …]is a meta-section, and expands to the expansion of each name it lists, recursively, each leaf once, in order. A listed name may be a glob. A listed name that matches no section is skipped with a warning (caldav skips it silently); *is every section that is not a meta-section, in file order;- a name with
*,?or[is a glob, matched against the section names, each match expanded as above. A glob that matches nothing is an error.
A section with disable: true is left out of every expansion, a disabled
meta-section with all its members (caldav still expands one). Naming a
disabled section directly is an error.
inherits: other copies the keys of section other in, and the
section's own keys win. A parent may inherit in turn. A cycle is an
error, and so is inheriting from a section of another kind (see below).
contains and disable are not inherited.
After inherits is applied and the structural keys (contains,
inherits, disable) are removed, a section is the keyword arguments of
calendaring's Backend.connect(): kind, url, username, password,
token and the backend's own options.
kindnames the backend. Without it, the reader decides fromurl(calendaring'sconnect()treats a path as files andwebcal:as a feed), and this package reports the kind as unknown. calendaring cannot yet connect anhttp(s):URL withoutkind; probing it for a feed or CalDAV is planned.- A section with
caldav_*keys is an old-style caldav section and haskind: caldav. The prefix is dropped, andcaldav_userandcaldav_passbecomeusernameandpassword. Everycaldav_*key is kept, not only the ones caldav knows. Mixing prefixed and unprefixed connection keys (url,username,password,tokenand any_commandor_keyringkey) in one section is an error. Other plain keys, such asfeatures,calendar_name,priorityortesting_allowed, are kept as they are in both styles. - An explicit
kindother thancaldavbesidecaldav_*keys is an error.
Each backend checks the keys it is given, and should warn about one it does not know. Some keys are not a backend's, and a backend passes them by:
test_*is for test tooling, such as caldav'stest_allowedandtest_priority. calendaring drops these keys before it connects.x_*is for an application's own settings.extra_configis plann's, from beforex_*.
${VAR} in a string is replaced with the environment variable VAR, or
the empty string when it is unset. ${VAR:-default} uses default
instead, only when VAR is unset (not, as in the shell, when it is
empty). This applies to every string in a section, kind and nested
ones included.
A key whose value is null is left out.
password and token can each instead come from one of:
password_command/token_command: a list of the program and its arguments. It is run without a shell, and its standard output, minus one trailing newline (\nor\r\n), is the secret. Its standard error goes to the terminal. A plain string is an error, since splitting it would need shell quoting rules. A non-zero exit is an error, and so is a command still running after 60 seconds.password_keyring/token_keyring: the service name to look up in the system keyring (thekeyringextra), with the section'susername. No username, no keyring package, no entry, or a keyring that fails (locked, no backend) is an error.
The old-style spelling (caldav_password_command, …) works as well.
At most one source per secret: password together with
password_command is an error.
Before a command is run, the file it came from is checked: it is refused when it is writable by group or others, or owned by anyone but the current user or root. Unlike ssh, the directories above it are not checked. A command that is not run (another section's, or one the environment replaces) is not checked.
Error messages name the section and the key, never the secret.
Environment variables describe one connection of one kind, and win over
the file. Every variable starting with the kind's prefix, CALDAV_ or
JMAP_, is a key of that section, its name lower-cased:
CALDAV_SSL_VERIFY_CERT is ssl_verify_cert, and CALDAV_PASSWORD is
password, exactly as if it were written in the file. CALDAV_USER and
CALDAV_PASS are short for username and password; the long name wins
when both are set. Other kinds have no variables. These are not keys:
<PREFIX>CONFIG_*, such asCALDAV_CONFIG_FILE, which choose the file and the section;<PREFIX>AUTH, sinceauthis an object, not a string.
Values are strings; only timeout becomes a number, and a value that is
not a number is an error. Any other conversion is the backend's:
CALDAV_SSL_VERIFY_CERT=false reaches caldav as the string "false". A
_command from the environment is a string, which is an error (see
"Secrets"). An empty value counts (a server may need an empty password),
except for the URL. Like the keys in the file, which keys a backend
accepts is for the backend to check, not for this package.
- A
CALDAV_URLorJMAP_URLmeans the file is not read at all: the configuration is that one connection (or two, if both are set; the CalDAV one first). A reader of one kind only, such as caldav, counts only the URL of its own kind: aJMAP_URLdoes not hide caldav's sections from caldav, and sections of other kinds are not its business. - Otherwise, when the name expands to exactly one section, the variables
of that section's kind apply to it key by key:
CALDAV_PASSWORDalone replaces the password and keeps the URL. A secret, or a source of one such asCALDAV_PASSWORD_KEYRING, from the environment replaces the section's other sources of it, which are then not run. Two sources of one secret in the environment are an error, as in the file. - When the name expands to several sections, the variables without a URL are not applied.
A section whose kind is unknown (no kind, no caldav_* keys) takes no
environment variables.