Skip to main content

Python bindings for AnyList API via anylist_rs

Project description

pyanylist

CI PyPI Python Versions

Unofficial Python bindings for the AnyList API, built with Rust and PyO3 for performance.

Features

  • Shopping Lists: Create, read, update, and delete shopping lists and items
  • Favourites: Manage favourite/starter items
  • Recipes: Full recipe CRUD with ingredient scaling
  • Meal Planning: iCalendar integration for meal plan calendars
  • Real-time Sync: WebSocket-based live updates
  • Token Persistence: Save and restore authentication sessions

Installation

uv add pyanylist

Or with pip:

pip install pyanylist

Quick Start

from pyanylist import AnyListClient

# Login with email and password
client = AnyListClient.login("your-email@example.com", "your-password")

# Get all shopping lists
lists = client.get_lists()
for lst in lists:
    print(f"{lst.name}: {len(lst.items)} items")

# Add an item to a list
item = client.add_item(lists[0].id, "Milk")
print(f"Added: {item.name}")

# Add item with details
item = client.add_item_with_details(
    lists[0].id,
    "Apples",
    quantity="6",
    details="Honeycrisp preferred",
    category="Produce"
)

Authentication

Login with credentials

client = AnyListClient.login("email@example.com", "password")

Save and restore session

# Export tokens for persistence
tokens = client.export_tokens()

# Save to file, database, etc.
save_tokens(tokens.access_token, tokens.refresh_token, tokens.user_id)

# Later, restore from saved tokens
from pyanylist import SavedTokens

tokens = SavedTokens(
    access_token="...",
    refresh_token="...",
    user_id="...",
    is_premium_user=False
)
client = AnyListClient.from_tokens(tokens)

Shopping Lists

# Get all lists
lists = client.get_lists()

# Get a specific list
grocery_list = client.get_list_by_name("Groceries")
# or by ID
grocery_list = client.get_list_by_id("list-id-here")

# Create a new list
new_list = client.create_list("Weekly Shopping")

# Rename a list
client.rename_list(new_list.id, "Monthly Shopping")

# Delete a list
client.delete_list(new_list.id)

List Items

# Add a simple item
item = client.add_item(list_id, "Bread")

# Add item with details
item = client.add_item_with_details(
    list_id,
    "Chicken Breast",
    quantity="2 lbs",
    details="Boneless, skinless",
    category="Meat"
)

# Check/uncheck items
client.cross_off_item(list_id, item.id)
client.uncheck_item(list_id, item.id)

# Delete an item
client.delete_item(list_id, item.id)

# Clear all checked items
client.delete_all_crossed_off_items(list_id)

Favourites

# Get all favourite items
favourites = client.get_favourites()

# Get favourites organized by list
fav_lists = client.get_favourites_lists()
for fav_list in fav_lists:
    print(f"{fav_list.name}: {len(fav_list.items)} items")

# Add a favourite
fav = client.add_favourite("Coffee", category="Beverages")

# Remove a favourite
client.remove_favourite(fav_list.id, fav.id)

Recipes

from pyanylist import Ingredient

# Get all recipes
recipes = client.get_recipes()
for recipe in recipes:
    print(f"{recipe.name}: {len(recipe.ingredients)} ingredients")

# Get a specific recipe
recipe = client.get_recipe_by_name("Pasta Carbonara")

# Create a recipe
ingredients = [
    Ingredient("Spaghetti", quantity="400g"),
    Ingredient("Eggs", quantity="4"),
    Ingredient("Parmesan", quantity="100g", note="freshly grated"),
    Ingredient("Pancetta", quantity="200g"),
]
steps = [
    "Boil pasta according to package directions",
    "Fry pancetta until crispy",
    "Mix eggs and parmesan",
    "Combine everything off heat",
]
recipe = client.create_recipe("Carbonara", ingredients, steps)

# Add recipe ingredients to a shopping list
client.add_recipe_to_list(recipe.id, list_id)

# Scale recipe (e.g., double it)
client.add_recipe_to_list(recipe.id, list_id, scale_factor=2.0)

# Delete a recipe
client.delete_recipe(recipe.id)

Meal Plan Calendar (iCalendar)

# Enable iCalendar export
info = client.enable_icalendar()
print(f"Calendar URL: {info.url}")
# Use this URL in any calendar app (Google Calendar, Apple Calendar, etc.)

# Get existing calendar URL
url = client.get_icalendar_url()

# Disable iCalendar
client.disable_icalendar()

Real-time Sync

import time
from pyanylist import SyncEvent

# Start real-time sync
sync = client.start_realtime_sync()

# Poll for events
while sync.is_connected():
    events = sync.poll_events()
    for event in events:
        if event == SyncEvent.ShoppingListsChanged:
            print("Lists changed! Refreshing...")
            lists = client.get_lists()
        elif event == SyncEvent.RecipeDataChanged:
            print("Recipes changed!")
    time.sleep(1)

# Disconnect when done
sync.disconnect()

Available Sync Events

  • ShoppingListsChanged - Shopping lists modified
  • StarterListsChanged - Favourites modified
  • RecipeDataChanged - Recipes modified
  • MealPlanCalendarChanged - Meal plan modified
  • AccountDeleted - Account was deleted

Error Handling

All methods raise RuntimeError on failure:

try:
    client = AnyListClient.login("bad@email.com", "wrongpassword")
except RuntimeError as e:
    print(f"Login failed: {e}")

try:
    client.get_list_by_id("nonexistent-id")
except RuntimeError as e:
    print(f"List not found: {e}")

Development

Prerequisites

  • Python 3.12+
  • Rust 1.70+
  • uv
  • protoc (Protocol Buffers compiler)
    • Ubuntu/Debian: sudo apt-get install protobuf-compiler
    • macOS: brew install protobuf

Setup

# Clone the repository
git clone https://github.com/ozonejunkieau/pyanylist.git
cd pyanylist

# Install dependencies (includes dev dependencies)
uv sync

# Build and install in development mode
uv run maturin develop

Running Tests

# Run unit tests (no credentials needed)
uv run pytest -v -m "not integration"

# Run all tests including integration (requires credentials)
export ANYLIST_EMAIL="your-email@example.com"
export ANYLIST_PASSWORD="your-password"
uv run pytest -v

# Run with coverage
uv run pytest --cov=tests --cov-report=term-missing

Linting & Type Checking

# Check code style
uv run ruff check tests/

# Format code
uv run ruff format tests/

# Type check
uv run pyright tests/

Acknowledgements

This library is built on top of anylist_rs by Phil Denhoff, which provides the core Rust implementation for interacting with the AnyList API.

License

MIT License - see LICENSE for details.

Disclaimer

This is an unofficial library and is not affiliated with or endorsed by AnyList. Use at your own risk and in accordance with AnyList's terms of service.

Project details


Download files

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

Source Distribution

pyanylist-0.0.4.tar.gz (50.4 kB view details)

Uploaded Source

Built Distributions

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

pyanylist-0.0.4-cp313-cp313-musllinux_1_2_x86_64.whl (4.5 MB view details)

Uploaded CPython 3.13musllinux: musl 1.2+ x86-64

pyanylist-0.0.4-cp313-cp313-musllinux_1_2_aarch64.whl (4.5 MB view details)

Uploaded CPython 3.13musllinux: musl 1.2+ ARM64

pyanylist-0.0.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (4.2 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ x86-64

pyanylist-0.0.4-cp313-cp313-macosx_11_0_arm64.whl (3.8 MB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

pyanylist-0.0.4-cp313-cp313-macosx_10_12_x86_64.whl (4.0 MB view details)

Uploaded CPython 3.13macOS 10.12+ x86-64

pyanylist-0.0.4-cp312-cp312-musllinux_1_2_x86_64.whl (4.5 MB view details)

Uploaded CPython 3.12musllinux: musl 1.2+ x86-64

pyanylist-0.0.4-cp312-cp312-musllinux_1_2_aarch64.whl (4.5 MB view details)

Uploaded CPython 3.12musllinux: musl 1.2+ ARM64

pyanylist-0.0.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (4.2 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64

pyanylist-0.0.4-cp312-cp312-macosx_11_0_arm64.whl (3.8 MB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

pyanylist-0.0.4-cp312-cp312-macosx_10_12_x86_64.whl (4.0 MB view details)

Uploaded CPython 3.12macOS 10.12+ x86-64

File details

Details for the file pyanylist-0.0.4.tar.gz.

File metadata

  • Download URL: pyanylist-0.0.4.tar.gz
  • Upload date:
  • Size: 50.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pyanylist-0.0.4.tar.gz
Algorithm Hash digest
SHA256 ca9788fdc4bb5159e3901e0bf258200e3c04ccba2a8cbdef415cf96d2cfe2766
MD5 7821670d76c168233a7d7ac69d65d2c4
BLAKE2b-256 56628c5058cac14052278a42036a5683b3e05c2eb67925e86d18389315fc47c0

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyanylist-0.0.4.tar.gz:

Publisher: release.yml on ozonejunkieau/pyanylist

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

File details

Details for the file pyanylist-0.0.4-cp313-cp313-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for pyanylist-0.0.4-cp313-cp313-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 44e8f02c96afa75f572efa0bbb6bbc150bd6290fad806d2750a8183b01df8084
MD5 ae1938c1f3da2f47022feb29288facd4
BLAKE2b-256 17710ed459e43996cb87b6450d14cf489ed1b15ee39b49da44fd4b02e685afd8

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyanylist-0.0.4-cp313-cp313-musllinux_1_2_x86_64.whl:

Publisher: release.yml on ozonejunkieau/pyanylist

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

File details

Details for the file pyanylist-0.0.4-cp313-cp313-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for pyanylist-0.0.4-cp313-cp313-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 4eda2946855116dd11124505a9ad97540649e590df8f7e3b7697d2d4f8e133bb
MD5 e3bbadf619fac0a405589c2d57a7acb4
BLAKE2b-256 b3ff624d15beecfc19e1ae680017aee83f961ba17b2c9c9ef1ede1f3669049f1

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyanylist-0.0.4-cp313-cp313-musllinux_1_2_aarch64.whl:

Publisher: release.yml on ozonejunkieau/pyanylist

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

File details

Details for the file pyanylist-0.0.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for pyanylist-0.0.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 b5c9c49e5574caed1bc3d0055d414fbdbe536d25fe62743592b5e3511d51d831
MD5 12dd83e0cdfdc385814f3502031d52e3
BLAKE2b-256 a384be2c0e2821b0c17743a9b190b5fc9e477cc0464edffda2453aad85938421

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyanylist-0.0.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on ozonejunkieau/pyanylist

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

File details

Details for the file pyanylist-0.0.4-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for pyanylist-0.0.4-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 e0d44ae872f744ac7712eb52b7af278762b0ec19ffb7cae42a48155ce01d418c
MD5 2fa5f4880cdc72adc43a42875f62190a
BLAKE2b-256 ca36d136be29b4fff4059d2e1387207716f22e21f69b15bd8cd4b5156507ba7c

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyanylist-0.0.4-cp313-cp313-macosx_11_0_arm64.whl:

Publisher: release.yml on ozonejunkieau/pyanylist

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

File details

Details for the file pyanylist-0.0.4-cp313-cp313-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for pyanylist-0.0.4-cp313-cp313-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 4e5f3d61ea20a307d0029f34fb5bc5196ad351b7f4995115e6a83fdfc823ce87
MD5 f62a5a6d36440cef9f290b49b667baa4
BLAKE2b-256 ee85098651040cd92f3c36f63256dbbd8442412477cb667720f35b5bbe14a7e3

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyanylist-0.0.4-cp313-cp313-macosx_10_12_x86_64.whl:

Publisher: release.yml on ozonejunkieau/pyanylist

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

File details

Details for the file pyanylist-0.0.4-cp312-cp312-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for pyanylist-0.0.4-cp312-cp312-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 d493b39e685f8ac270364cebd0974bd08ed3d4dd75244f5c0391477fd7faff8e
MD5 5dd5f0d424e059f78c888be901e60719
BLAKE2b-256 a023de68c2980c06fb81d86bd9005338b089d0d3e0d543fcc0a3b44ccc4a3cf2

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyanylist-0.0.4-cp312-cp312-musllinux_1_2_x86_64.whl:

Publisher: release.yml on ozonejunkieau/pyanylist

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

File details

Details for the file pyanylist-0.0.4-cp312-cp312-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for pyanylist-0.0.4-cp312-cp312-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 37634466c256b7dcfc547c7614b44018598a311f89195027d54f930e9917e9a1
MD5 d6cd2ef050d3341eda955058f06d1c3f
BLAKE2b-256 50f6e94f113d790583105b476fd27fde3318250abad449f9ca0cc0ab3b7b7d21

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyanylist-0.0.4-cp312-cp312-musllinux_1_2_aarch64.whl:

Publisher: release.yml on ozonejunkieau/pyanylist

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

File details

Details for the file pyanylist-0.0.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for pyanylist-0.0.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 e86907250ec1b7f1c79c6e7c5ad9c3d415f43f53812980a1b04e3f4cc0746f40
MD5 d3eb8c9878701ef362402c83b77e03cd
BLAKE2b-256 57bcaed95c0c67bfce7a8a349522cb9eb06655973ee0760157ce923ea895dd70

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyanylist-0.0.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on ozonejunkieau/pyanylist

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

File details

Details for the file pyanylist-0.0.4-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for pyanylist-0.0.4-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 e799760fb95d49efbde14163ee76c8bba610b6bff7acf1e309a73809885ee195
MD5 70eaedc73b5dad17d986a353bacd5a2e
BLAKE2b-256 bce479aec42159da4baaabbd349c56ab73df4414f16984cfdeae762b943a3a53

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyanylist-0.0.4-cp312-cp312-macosx_11_0_arm64.whl:

Publisher: release.yml on ozonejunkieau/pyanylist

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

File details

Details for the file pyanylist-0.0.4-cp312-cp312-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for pyanylist-0.0.4-cp312-cp312-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 3e64342c5578b69f73737a7b36a22325cbbe790aef656fdb58d739bb94dcec37
MD5 ff52d38c7138898429ace125704532ff
BLAKE2b-256 7de048c6066ebfe2680904ecb4059934ac2dca57df3ccb4814172f901048482e

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyanylist-0.0.4-cp312-cp312-macosx_10_12_x86_64.whl:

Publisher: release.yml on ozonejunkieau/pyanylist

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

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page