Skip to main content

kuvert

The python client for kuvert, the Arkitekt mail service: the mailboxes you linked, their folders and conversations, tasks over those conversations, and sending mail.

Installation

pip install kuvert

Usage

Every kuvert operation is a method of the Kuvert client, in a blocking and an a-prefixed async flavour.

In an arkitekt app

The client is injected by annotation. Add the service to your app and ask for kuvert: Kuvert:

from arkitekt import App, run
from kuvert import Kuvert, kuvert_service

app = App("mail-digest", "0.1.0", services=[kuvert_service])


@app.action
async def unread_subjects(kuvert: Kuvert) -> list[str]:
    """The subjects of the unread conversations in my inboxes."""
    threads = await kuvert.alist_threads(filter={"unread": True, "folderRole": "INBOX"})
    return [thread.subject for thread in threads]


if __name__ == "__main__":
    run(app)

Messages, threads, outgoing mail, mailboxes, tasks and task lists travel between actions by id (@kuvert/message, @kuvert/thread, @kuvert/outgoingmessage, @kuvert/mailaccount, @kuvert/task, @kuvert/tasklist), so an action can take and return them directly, and a trigger on a kuvert signal hands them over.

From a script

from arkitekt import easy
from kuvert import kuvert_service

with easy("my-script", kuvert_service) as kuvert:
    for account in kuvert.list_mail_accounts():
        print(account.email_address, account.unread_count)

Standalone

Without arkitekt, build the client over a rath link of your own:

from kuvert import Kuvert
from kuvert.rath import KuvertRath

kuvert = Kuvert(rath=KuvertRath(link=...))

with kuvert:
    for account in kuvert.list_mail_accounts():
        print(account.email_address, account.unread_count)

    kuvert.send_message(
        account=account.id,
        to=[{"address": "someone@example.org"}],
        subject="Hello",
        text="From kuvert.",
    )

Arguments the server defaults (cc, bcc, attachments of send_message, notes/pinned of create_task, …) are optional: leave them out rather than passing None. An explicit None is sent as null, which the server rejects for those fields.

Changes to mail (flags, moves, deletes, categories) are local-first: they apply at once and reach the mail server when the mailbox next pushes. list_mail_changes shows what is still pending and undo_mail_changes takes a change back while it is.

Development

The generated API (kuvert/api/schema.py) comes from the checked-in schema.graphql and the documents in graphql/. The config comment in graphql.config.yaml has the command that refreshes the schema from a kuvert-server checkout. Then run turms to regenerate the API.

uv run pytest -m "not integration"   # no server needed
uv run pytest -m integration          # a real kuvert + mail server via dokker

See RELEASING.md for how versions are cut.

Metadata

Release files for kuvert 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 kuvert 1.0.0
File Size Uploaded
kuvert-1.0.0.tar.gz 51.9 kB Details

Built distribution (wheel)

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

Total release size: 104.9 kB

Release files / kuvert-1.0.0.tar.gz

Download URL kuvert-1.0.0.tar.gz
Size 51.9 kB
Tags Source
SHA-256 checksum
How to use checksums
dbf71e29c4f26dfc584e95ad31eda4fb58c1d7ae994a44a774572949ff093552
BLAKE2b-256 checksum
How to use checksums
e6598cf6b04ffa11db746aa087f851568fd9d9f2547266b12eb9210912c10c0c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.20 {"installer":{"name":"uv","version":"0.12.20","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

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

Download URL kuvert-1.0.0-py3-none-any.whl
Size 53.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c544e2f489bea0a34ceebe5c0b009d30e85a10f0fb2c6ee4aff1de362b2a9679
BLAKE2b-256 checksum
How to use checksums
18cb0e5e7fbb4dc9994b9621c78d0829d3d5c5f9b14e94358599150e3eda397e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.20 {"installer":{"name":"uv","version":"0.12.20","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 release files

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