Skip to main content

aioanylist

Async-first, typed Python client for AnyList, reverse-engineered from AnyList's web and native clients and embedded protobuf schema.

Unofficial and not affiliated with AnyList.

Built to be the last AnyList client you need.

As of the September 2026 audit, no other reviewed public general-purpose AnyList client matched its combined protocol and client-behavior coverage. See the ecosystem comparison for the dated feature matrix and benchmarks.

Highlights

  • Typed async API built on aiohttp.
  • Official protobuf wire format and operation queues.
  • Access-token refresh with rotating refresh-token support.
  • Incremental synchronization plus WebSocket invalidation/reconnect handling.
  • Durable operation journals for replay after interrupted sessions.
  • Shopping lists, Favorites/Recents, folders, stores, categories, recipes, meal planning, photos, sharing, account data, native search/lookup, remote config, and auxiliary endpoints.
  • Client-side AnyList behavior including autocomplete, grocery categorization, quantity/package parsing, recipe parsing, normalization, stemming, derived totals, deterministic identifiers, and official visual/theme resolution.
  • Current AnyList icon metadata/catalog access and canonical asset URLs without bundling or redistributing AnyList artwork.
  • PEP 561 typing with schema-generated protobuf stubs.
  • Textual example application kept outside the installable SDK package.

The default test suite passes 530/530 tests. Live and offline verification status is tracked in docs/conformance.md.

Requirements

  • Python 3.11+
  • An AnyList account for authenticated API use

Install the SDK from PyPI:

python -m pip install aioanylist

For the Textual example dependencies:

python -m pip install 'aioanylist[tui]'

For the optional Model Context Protocol example dependencies:

python -m pip install 'aioanylist[mcp]'

For development/testing from a source checkout:

python -m pip install -e '.[test,tui]'

Quick start

import asyncio

from aioanylist import AnyListClient


async def main() -> None:
    async with AnyListClient() as client:
        await client.sign_in("you@example.com", "password")
        await client.load(realtime=True)

        assert client.lists is not None
        for shopping_list in client.lists.all():
            print(shopping_list.name)


asyncio.run(main())

load() performs the initial synchronized state load. Passing realtime=True also starts the WebSocket invalidation client so remote changes can trigger catch-up refreshes.

The service attributes become available after authentication, for example:

assert client.lists is not None
assert client.recipes is not None
assert client.meal_plan is not None

groceries = client.lists.get("list-id")
recipes = client.recipes.all()
events = client.meal_plan.events()

Low-level protobuf classes are available under aioanylist.proto.PB. Operation-backed services also expose operation(...) for known handlers without a dedicated convenience method.

Authentication and session reuse

Sign-in returns an AuthTokens object containing the user ID, access token, refresh token, and account metadata. Normal API calls use the access token as a bearer token. If AnyList rejects it with an authentication response, the transport refreshes it once using the refresh token and retries the original request.

AnyList rotates both tokens during refresh. Applications that persist sessions should save the newest AuthTokens value after every refresh.

The SDK does not retain the password after sign-in. logout() signs out the token session and clears local credentials. clear_session() only clears local credentials. Live tests on both AnyList hosts found that sign-out revokes the refresh token immediately while the current access token remains valid until expiry.

See docs/architecture.md for the transport, sync, operation-queue, and realtime model.

Example terminal client

examples/anylist_tui.py is a downstream example built on the SDK. It lives outside src/aioanylist, so installing the library does not also install an end-user application.

git clone https://github.com/BookCatKid/aioanylist.git
cd aioanylist
python -m pip install -e '.[tui]'
python examples/anylist_tui.py

On first run, the TUI asks for the AnyList email and password. It stores the email and current token pair under ~/.config/aioanylist/; the password is not stored. The token file uses mode 0600 where supported.

The TUI includes:

  • shopping-list creation/editing, autocomplete, categories, stores, quantities, photos, Favorites/Recents, folders, and list behavior;
  • recipe collections, full recipe viewing/editing, ingredients, directions, timing, nutrition, ratings, sources, and photos;
  • a week-based meal planner, Queue/Favorites workspace, labels, recipe scheduling, per-entry items, and editable multi-day templates.

Use python examples/anylist_tui.py --login to ignore a cached session and sign in again, or python examples/anylist_tui.py --logout to remove the cached local session.

See docs/tui.md for navigation, shortcuts, session behavior, and troubleshooting.

Model Context Protocol

The core package has no MCP dependency. examples/anylist_mcp.py shows how to expose the SDK through the official MCP Python SDK while keeping one synchronized AnyListClient alive for the server lifespan.

See examples/anylist_mcp.py and docs/mcp.md.

Typing

The normal client/service/state surface is fully annotated and the package ships a py.typed marker.

The protobuf classes are built dynamically at runtime from AnyList's embedded official schema, while aioanylist.proto ships a generated .pyi from that same schema. Editors and type checkers therefore see concrete message fields such as ShoppingList.items, PBRecipe.ingredients, and PBCalendarEvent.eventListItems rather than generic protobuf Message values.

The checked-in stub is deterministic. tools/generate_proto_stubs.py --check fails if it drifts from the embedded schema, and the default suite runs strict mypy checks against both the SDK and an external consumer fixture.

Project layout

src/aioanylist/        installable SDK, protocol runtime, and services
tests/                  offline/local regression suite
live_tests/             explicitly opt-in real-service conformance tests
research/               official-client reverse-engineering evidence and inventories
docs/                   architecture, TUI guide, and conformance evidence
tools/                  schema/surface extraction and generated-stub tooling
examples/               downstream example applications

Conformance and safety

Shared/web behavior is matched against AnyList Web. Native-only behavior comes from official Android source and iOS captures. Unofficial clients are not used as protocol references.

docs/conformance.md records verification status, source contradictions, known divergences, and live-test boundaries.

The default test suite is fully offline/local:

python -m pytest -q

Real-service tests live in live_tests/ and require explicit environment opt-in. They are not collected by the default pytest configuration.

Development checks

python -m pytest -q
python -m mypy --strict --disable-error-code attr-defined src/aioanylist
python tools/generate_proto_stubs.py --check
python -m ruff format --check .

src/aioanylist/proto/__init__.pyi is generated deterministically and excluded from standalone Ruff formatting. tools/generate_proto_stubs.py --check validates it.

Documentation

Scope

The SDK includes reconstructed external/account operations where available. The terminal example leaves out workflows with external or hard-to-reverse effects, including sharing/email, Alexa linking, recipe web import, and account-name changes.

Because this is a reverse-engineered client for a service that can change independently, future AnyList web/protocol updates may require corresponding SDK updates.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

aioanylist-1.0.0.tar.gz (154.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

aioanylist-1.0.0-py3-none-any.whl (165.5 kB view details)

Uploaded Python 3

File details

Details for the file aioanylist-1.0.0.tar.gz.

File metadata

  • Download URL: aioanylist-1.0.0.tar.gz
  • Upload date:
  • Size: 154.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for aioanylist-1.0.0.tar.gz
Algorithm Hash digest
SHA256 83a14e1888a67cd13c9fde8e2acf48ea837c9409ceb2ec98c49dd024b08abe81
MD5 50d30f15bc0e5fee18c0cf87084f644a
BLAKE2b-256 902e2e863c0c52d4c5af140e8d1e827aa25e2eef52294ff86362cadc18671b05

See more details on using hashes here.

Provenance

The following attestation bundles were made for aioanylist-1.0.0.tar.gz:

Publisher: release.yml on BookCatKid/aioanylist

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file aioanylist-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: aioanylist-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 165.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for aioanylist-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0f03900924fadf1c7707cad827e9dc3a975a163ef0dfa2bd5d264c182cb5dcfe
MD5 258452d2a39b7a703548e264fcdf6b0f
BLAKE2b-256 1666ee89d75e56d09b568dedf5c968aa86b324ab76ea9111d1c169d493b9b20b

See more details on using hashes here.

Provenance

The following attestation bundles were made for aioanylist-1.0.0-py3-none-any.whl:

Publisher: release.yml on BookCatKid/aioanylist

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

1.0.2

2 files

1.0.1

2 files

This release

1.0.0 This release

2 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