Authenticate#
get_jmap_client() reads configuration from explicit keyword arguments, environment variables, then a YAML config file, checked in that order. If none of the three sources supplies a url, it returns None.
The first source that supplies a url wins outright for that call: passing url explicitly, even with no other arguments, uses only the explicit arguments, and doesn’t fall back to environment variables or the config file for username/password/auth_type/timeout. If you mix sources, supply url from the lowest-priority source you want to use; a source that doesn’t supply url still has its other fields merged in underneath whichever source does.
Resolve configuration without building a client#
get_connection_params() runs the same resolution get_jmap_client() does, but returns the resolved dict instead of a client, or None if nothing was found. Useful if you want to inspect or adjust the result before constructing a client yourself, or you’re building your own thin wrapper around this project’s config sources (for example, a CLI tool that passes every flag through unconditionally, whether or not the user set it, without wiping out an environment variable for the flags they left off):
from calendaring_jmap import get_connection_params
params = get_connection_params(url=cli_args.url, username=cli_args.username)
if params is None:
raise SystemExit("No JMAP configuration found")
Use environment variables or a config file#
Environment variables:
export JMAP_URL=https://jmap.example.com/.well-known/jmap
export JMAP_USERNAME=alice
export JMAP_PASSWORD=secret
export JMAP_AUTH_TYPE=basic
export JMAP_TIMEOUT=30
JMAP_URL, JMAP_USERNAME, and JMAP_PASSWORD map directly to get_jmap_client()’s own url/username/password arguments. JMAP_AUTH_TYPE (basic or bearer) forces the auth type instead of inferring it; JMAP_TIMEOUT sets the request timeout in seconds. Both are optional.
Or a YAML config file, at ~/.config/calendaring-jmap/calendar.yaml by default:
url: https://jmap.example.com/.well-known/jmap
username: alice
password: secret
Override the config file’s location with the JMAP_CONFIG_FILE environment variable, or by passing config_file directly to get_jmap_client().
With either in place, no arguments are needed:
client = get_jmap_client()
Use Basic or Bearer auth explicitly#
Supplying a username alongside a password uses HTTP Basic auth. Supplying only a password (token), with no username, uses Bearer token auth.
# Basic auth
client = get_jmap_client(
url="https://jmap.example.com/.well-known/jmap",
username="alice",
password="secret",
)
# Bearer token (password argument holds the token, no username supplied)
client = get_jmap_client(
url="https://jmap.example.com/.well-known/jmap",
password="my-bearer-token",
)
Use a pre-built auth object#
Pass any requests-compatible auth object directly via the auth parameter (niquests is API-compatible with requests):
try:
from niquests.auth import HTTPBasicAuth
except ImportError:
from requests.auth import HTTPBasicAuth
client = get_jmap_client(
url="https://jmap.example.com/.well-known/jmap",
auth=HTTPBasicAuth("alice", "secret"),
)
JMAP doesn’t use a 401 challenge and retry. Credentials are sent on every request, and a 401 or 403 is a hard JMAPAuthError.
Release the connection without a context manager#
If you don’t use with/async with, call close() (or aclose() on the async client) when you’re done, to release the underlying HTTP session and its connection pool:
client = get_jmap_client()
try:
calendars = client.get_calendars()
finally:
client.close()
Calling it is optional. Forgetting isn’t harmful: the session is recreated automatically on the next request.