Async Python client for the Amazing Marvin API
Project description
amazing-marvin
Async Python client library for the Amazing Marvin API.
Async-first, fully typed, no global state, no blocking I/O. Suitable for any Python application — CLIs, web services, MCP servers, Home Assistant integrations, sync bridges, scheduled scripts.
Installation
pip install amazing-marvin
Requires Python 3.12+ and aiohttp>=3.9.
Quick Start
import asyncio
from amazing_marvin import MarvinClient
async def main():
async with MarvinClient(api_token="your_token") as client:
tasks = await client.get_today_items()
for task in tasks:
print(task.title, task.done)
asyncio.run(main())
When embedding inside a host that already manages an aiohttp.ClientSession (FastAPI, Home Assistant, an MCP server runtime), pass the existing session at construction so the client never owns or closes it:
client = MarvinClient(
api_token=token,
full_access_token=full_token, # optional
tz_offset=600, # AEST
throttle=True,
session=existing_session, # borrowed; not closed by client
)
tasks = await client.get_today_items()
task = await client.mark_done(item_id)
Use Cases
The library is intentionally framework-agnostic. Common embeddings:
- MCP servers — wrap each
MarvinClientmethod as a tool; the typed dataclasses serialise cleanly to JSON. - Home Assistant integrations — use the borrowed-session pattern with
async_get_clientsession(hass). - CLIs — pair with Typer or Click for terminal-driven task entry.
- FastAPI / web dashboards — share the app's
aiohttpsession via lifespan. - Sync bridges — Notion, Todoist, Linear, calendar providers.
- Scheduled scripts — cron, GitHub Actions, weekly reviews, exports.
Auth Setup
Amazing Marvin exposes two separate tokens, both found under Profile > Integrations > API in the Marvin app:
| Token | Constructor arg | Required for |
|---|---|---|
| API Token | api_token |
Read and write operations (most methods) |
| Full Access Token | full_access_token |
Raw document access, reminders, admin ops |
Methods that need a token you have not supplied will raise MarvinAuthError before making any HTTP request.
Rate Limits
The Amazing Marvin API enforces:
- Burst: 1 request per 3 seconds
- Daily cap: 1440 requests per calendar day (resets at midnight in your local timezone)
Pass throttle=True to have the client enforce these limits automatically using an internal asyncio lock. When the daily cap is hit, MarvinRateLimitError is raised with daily_cap_exceeded=True. When the server itself returns 429, MarvinRateLimitError is raised with the retry_after value from the response header (if present).
Timezone Handling
Marvin uses integer minutes east of UTC for timezone offsets. For example:
tz_offset=600— AEST (UTC+10)tz_offset=0— UTCtz_offset=-300— EST (UTC-5)
Pass tz_offset at client construction for a default, or override it per-call on methods that accept tz_offset=. The offset affects which calendar day is considered "today" for scheduling and daily cap resets.
Licence
MIT — see LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file amazing_marvin-0.1.0.tar.gz.
File metadata
- Download URL: amazing_marvin-0.1.0.tar.gz
- Upload date:
- Size: 122.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a37aa605344386fb72d73aa05cd70372b20bc54d57d86985142e321169b368cc
|
|
| MD5 |
1094a2864de7263d5e8992cd1b378d56
|
|
| BLAKE2b-256 |
95bee8cd109ce6952739251441968dc1f8a7f1057b9903b0eecf7b354f7b5aa2
|
Provenance
The following attestation bundles were made for amazing_marvin-0.1.0.tar.gz:
Publisher:
release.yml on jjsmackay/py-amazing-marvin
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
amazing_marvin-0.1.0.tar.gz -
Subject digest:
a37aa605344386fb72d73aa05cd70372b20bc54d57d86985142e321169b368cc - Sigstore transparency entry: 1382453048
- Sigstore integration time:
-
Permalink:
jjsmackay/py-amazing-marvin@304c4d6dfaf8cbb0fab7f80cc7986f458ec95f28 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/jjsmackay
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@304c4d6dfaf8cbb0fab7f80cc7986f458ec95f28 -
Trigger Event:
push
-
Statement type:
File details
Details for the file amazing_marvin-0.1.0-py3-none-any.whl.
File metadata
- Download URL: amazing_marvin-0.1.0-py3-none-any.whl
- Upload date:
- Size: 14.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c371d08c86f1165f29bb0d49296604f69e05d8973dcf6e0db439e93356f2e8b4
|
|
| MD5 |
f378c683574dbcb8f8f91fc7113e629a
|
|
| BLAKE2b-256 |
7a437f0c429da22ff8293649733d4593f493153a3920c571d086218bed0435bc
|
Provenance
The following attestation bundles were made for amazing_marvin-0.1.0-py3-none-any.whl:
Publisher:
release.yml on jjsmackay/py-amazing-marvin
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
amazing_marvin-0.1.0-py3-none-any.whl -
Subject digest:
c371d08c86f1165f29bb0d49296604f69e05d8973dcf6e0db439e93356f2e8b4 - Sigstore transparency entry: 1382453079
- Sigstore integration time:
-
Permalink:
jjsmackay/py-amazing-marvin@304c4d6dfaf8cbb0fab7f80cc7986f458ec95f28 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/jjsmackay
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@304c4d6dfaf8cbb0fab7f80cc7986f458ec95f28 -
Trigger Event:
push
-
Statement type: