Skip to main content

Unofficial Python SDK for Mealie - a self-hosted recipe manager and meal planner

Project description

Mealie Client

PyPI version Python Support License: MIT Code style: black Ruff

An unofficial Python SDK for Mealie - a self-hosted recipe manager and meal planner with a RestAPI backend.

🚀 Features

  • Asynchronous API Client: Built with httpx for high-performance async operations
  • Type Safety: Full type hints with pydantic models for all API responses
  • Core Endpoints Supported: Recipes, Users, Groups, Meal Plans, and Shopping Lists
  • Authentication: Secure token-based authentication and username/password login
  • Recipe Management: Full CRUD operations, search, filtering, and image management
  • Meal Planning: Create and manage meal plans with date filtering
  • Shopping Lists: Complete shopping list and item management
  • Error Handling: Comprehensive error handling with custom exceptions
  • Modern Python: Support for Python 3.8+ with modern async/await patterns

📈 Current API Coverage

This SDK currently covers the following Mealie API endpoints:

Recipes - Create, read, update, delete, search, image upload, import from URL
Users - User management and current user info
Groups - Basic group operations
Meal Plans - Meal planning with date filtering
Shopping Lists - Shopping lists and item management
Units - Unit management ✅ Foods - Food management ✅ Households - Household management

🔄 Planned for Future Releases:

  • Categories, Tags, and Tools endpoints
  • Recipe Extras (custom metadata)
  • Webhooks and Event Subscriptions
  • Timeline Events
  • Advanced search features

📦 Installation

Using pip

pip install mealie-client

Using PDM (recommended for development)

pdm add mealie-client

Using Poetry

poetry add mealie-client

🏁 Quick Start

Basic Usage

import asyncio
from mealie_client import MealieClient

async def main():
    # Initialize the client
    async with MealieClient(
        base_url="https://your-mealie-instance.com",
        api_token="your-api-token"
    ) as client:
        
        # Get all recipes
        recipes = await client.recipes.get_all()
        print(f"Found {len(recipes)} recipes")
        
        # Get a specific recipe
        recipe = await client.recipes.get("recipe-slug-or-id")
        if recipe:
            print(f"Recipe: {recipe.name}")
            print(f"Description: {recipe.description}")
        
        # Create a new recipe
        new_recipe = await client.recipes.create({
            "name": "Test Recipe",
            "description": "A test recipe created via SDK",
            "recipe_ingredient": [
                {"note": "2 cups flour"},
                {"note": "1 cup sugar"}
            ],
            "recipe_instructions": [
                {"text": "Mix flour and sugar"},
                {"text": "Bake at 350°F for 30 minutes"}
            ]
        })
        
        print(f"Created recipe: {new_recipe.name}")

# Run the async function
asyncio.run(main())

Authentication

The SDK supports both API token and username/password authentication:

API Token Authentication (Recommended)

from mealie_client import MealieClient

# Using API token
async with MealieClient(
    base_url="https://your-mealie-instance.com",
    api_token="your-long-lived-api-token"
) as client:
    recipes = await client.recipes.get_all()

Username/Password Authentication

from mealie_client import MealieClient

# Using username/password
async with MealieClient(
    base_url="https://your-mealie-instance.com",
    username="your_username",
    password="your_password"
) as client:
    recipes = await client.recipes.get_all()

Environment Variables

# Set environment variables
# MEALIE_USERNAME=your_username
# MEALIE_PASSWORD=your_password
# MEALIE_API_TOKEN=your_api_token

from mealie_client import MealieClient

client = MealieClient.from_env("https://your-mealie-instance.com")

📖 Usage Examples

Recipe Management

from mealie_client import MealieClient

async def recipe_operations():
    async with MealieClient(
        base_url="https://your-mealie-instance.com",
        api_token="your-api-token"
    ) as client:
        
        # Search recipes with filters
        recipes = await client.recipes.get_all(
            search="pasta",
            categories=["Italian"],
            tags=["quick"],
            per_page=20,
            order_by="created_at",
            order_direction="desc"
        )
        
        # Get recipe details
        recipe = await client.recipes.get("pasta-carbonara")
        
        # Update a recipe
        updated_recipe = await client.recipes.update("pasta-carbonara", {
            "description": "Updated description",
            "prep_time": "PT15M"  # 15 minutes in ISO format
        })
        
        # Upload recipe image
        with open("recipe-image.jpg", "rb") as image_file:
            await client.recipes.upload_image("pasta-carbonara", image_file)
        
        # Import recipe from URL
        imported_recipe = await client.recipes.import_from_url(
            "https://example.com/recipe"
        )
        
        # Delete a recipe
        await client.recipes.delete("old-recipe-slug")

Meal Planning

from datetime import date, timedelta

async def meal_planning():
    async with MealieClient(
        base_url="https://your-mealie-instance.com",
        api_token="your-api-token"
    ) as client:
        
        # Get current meal plans
        today = date.today()
        meal_plans = await client.meal_plans.get_all(
            start_date=today,
            end_date=today + timedelta(days=7)
        )
        
        # Create a meal plan
        meal_plan = await client.meal_plans.create({
            "date": today.isoformat(),
            "entry_type": "dinner",
            "title": "Italian Night",
            "recipe_id": "pasta-carbonara-id"
        })
        
        # Update meal plan
        await client.meal_plans.update(meal_plan.id, {
            "title": "Updated Italian Night"
        })

Shopping Lists

async def shopping_operations():
    async with MealieClient(
        base_url="https://your-mealie-instance.com",
        api_token="your-api-token"
    ) as client:
        
        # Get all shopping lists
        shopping_lists = await client.shopping_lists.get_all()
        
        # Create a shopping list
        new_list = await client.shopping_lists.create({
            "name": "Weekly Groceries",
            "list_items": [
                {"note": "2 lbs chicken breast"},
                {"note": "1 dozen eggs"},
                {"note": "Fresh vegetables"}
            ]
        })
        
        # Add items to existing list
        await client.shopping_lists.add_item(new_list.id, {
            "note": "Milk - 2% gallon"
        })
        
        # Update an item
        await client.shopping_lists.update_item(
            new_list.id, 
            item_id="item-id",
            {"checked": True}
        )

User and Group Management

async def user_management():
    async with MealieClient(
        base_url="https://your-mealie-instance.com",
        api_token="your-admin-api-token"  # Admin privileges required
    ) as client:
        
        # Get current user info
        current_user = await client.users.get_current()
        print(f"Logged in as: {current_user.username}")
        
        # Get all users (admin only)
        users = await client.users.get_all()
        
        # Create a new user (admin only)
        new_user = await client.users.create({
            "username": "newuser",
            "email": "newuser@example.com",
            "password": "secure-password",
            "full_name": "New User"
        })
        
        # Get groups
        groups = await client.groups.get_all()

Error Handling

from mealie_client import MealieClient
from mealie_client.exceptions import (
    MealieAPIError, 
    AuthenticationError, 
    NotFoundError,
    ValidationError
)

async def error_handling_example():
    async with MealieClient(
        base_url="https://your-mealie-instance.com",
        api_token="your-api-token"
    ) as client:
        
        try:
            recipe = await client.recipes.get("non-existent-recipe")
        except NotFoundError:
            print("Recipe not found")
        except AuthenticationError:
            print("Invalid authentication credentials")
        except ValidationError as e:
            print(f"Validation error: {e.validation_errors}")
        except MealieAPIError as e:
            print(f"API Error: {e.message} (Status: {e.status_code})")

🛠️ Development

Prerequisites

  • Python 3.8+
  • PDM (Python Dependency Manager)

Setup Development Environment

  1. Clone the repository:

    git clone https://github.com/yourusername/mealie-client.git
    cd mealie-client
    
  2. Install dependencies:

    pdm install -G dev
    
  3. Set up pre-commit hooks:

    pdm run pre-commit install
    

Running Tests

# Run all tests
pdm run test

# Run unit tests only
pdm run pytest tests/unit

# Run integration tests only  
pdm run pytest tests/integration

# Run with coverage
pdm run pytest --cov=src/mealie_client

Code Quality

# Run linting
pdm run ruff check src tests

# Format code
pdm run black src tests

# Type checking
pdm run mypy src

🔧 Configuration

Environment Variables

export MEALIE_BASE_URL="https://your-mealie-instance.com"
export MEALIE_API_TOKEN="your-api-token"
# OR
export MEALIE_USERNAME="your-username"
export MEALIE_PASSWORD="your-password"

Client Configuration

from mealie_client import MealieClient

client = MealieClient(
    base_url="https://your-mealie-instance.com",
    api_token="your-api-token",
    timeout=30.0,  # Request timeout in seconds
    max_retries=3,  # Number of retry attempts
    retry_delay=1.0,  # Delay between retries
)

📚 API Reference

Core Classes

  • MealieClient: Main client class for interacting with Mealie API
  • RecipesManager: Handles all recipe-related operations
  • MealPlansManager: Manages meal planning functionality
  • ShoppingListsManager: Shopping list operations
  • UsersManager: User management
  • GroupsManager: Group management
  • UnitsManager: Unit management
  • FoodsManager: Food management
  • HouseholdsManager: Household management

Available Models

The SDK includes Pydantic models for all supported data structures:

  • Recipe, RecipeCreateRequest, RecipeUpdateRequest, RecipeSummary
  • MealPlan, MealPlanCreateRequest, MealPlanUpdateRequest
  • ShoppingList, ShoppingListItem, ShoppingListCreateRequest
  • User, UserCreateRequest, UserUpdateRequest
  • Group, GroupSummary
  • Unit, UnitCreateRequest, UnitUpdateRequest, UnitSummary
  • Food, FoodCreateRequest, FoodUpdateRequest, FoodSummary
  • Household, HouseholdSummary

🎯 Roadmap

Version 0.1.0 (Current)

  • Recipes management endpoint
  • Users management endpoint
  • Groups management endpoint
  • Meal plans management endpoint
  • Units management endpoint
  • Foods management endpoint
  • Households management endpoint
  • Tags management endpoint

Version 1.0.0 (Planned)

  • Shopping lists management endpoint
  • Categories, and Tools endpoints
  • Recipe search improvements
  • Better error messages

Version 1.1.0 (Planned)

  • Recipe Extras support
  • Webhooks management
  • Timeline Events
  • Advanced filtering options

Version 2.0.0 (Future)

  • Bulk operations
  • Enhanced meal plan features

🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Development Workflow

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Make your changes and add tests
  4. Ensure all tests pass (pdm run test)
  5. Commit your changes (git commit -m 'Add amazing feature')
  6. Push to the branch (git push origin feature/amazing-feature)
  7. Open a Pull Request

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.

🙏 Acknowledgments

  • Mealie - The amazing self-hosted recipe manager
  • httpx - For the excellent async HTTP client
  • Pydantic - For robust data validation

📞 Support


Disclaimer: This is an unofficial SDK and is not affiliated with or endorsed by the Mealie project.

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

mealie_client-0.1.3.tar.gz (122.2 kB view details)

Uploaded Source

Built Distribution

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

mealie_client-0.1.3-py3-none-any.whl (54.5 kB view details)

Uploaded Python 3

File details

Details for the file mealie_client-0.1.3.tar.gz.

File metadata

  • Download URL: mealie_client-0.1.3.tar.gz
  • Upload date:
  • Size: 122.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.11

File hashes

Hashes for mealie_client-0.1.3.tar.gz
Algorithm Hash digest
SHA256 5ad50094d05b2d49f144348e1afb2b70ae744a04089aa239bc33d6882b16cf6e
MD5 96b7a32108c63c2dcd799a7dd09ee82f
BLAKE2b-256 82704022c6a95d2f43d0dc8d7a42a10e552509ed9700ffc85d5af601afceaaaf

See more details on using hashes here.

File details

Details for the file mealie_client-0.1.3-py3-none-any.whl.

File metadata

  • Download URL: mealie_client-0.1.3-py3-none-any.whl
  • Upload date:
  • Size: 54.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.11

File hashes

Hashes for mealie_client-0.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 fe4d3ab5d85aaabe8c1c05ea5b67009f99596a2fa62feb4f400db9b6b0b608f1
MD5 3bd91b844474a1319f95b889d8dd8ac1
BLAKE2b-256 9534c43d15a70e665b82e5e591554db155820e5448a52d20424139c64b53d59a

See more details on using hashes here.

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