Unofficial Python SDK for Mealie - a self-hosted recipe manager and meal planner
Project description
Mealie Client
An unofficial Python SDK for Mealie - a self-hosted recipe manager and meal planner with a RestAPI backend.
🚀 Features
- Asynchronous API Client: Built with
httpxfor high-performance async operations - Type Safety: Full type hints with
pydanticmodels 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
-
Clone the repository:
git clone https://github.com/yourusername/mealie-client.git cd mealie-client
-
Install dependencies:
pdm install -G dev
-
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 APIRecipesManager: Handles all recipe-related operationsMealPlansManager: Manages meal planning functionalityShoppingListsManager: Shopping list operationsUsersManager: User managementGroupsManager: Group managementUnitsManager: Unit managementFoodsManager: Food managementHouseholdsManager: Household management
Available Models
The SDK includes Pydantic models for all supported data structures:
Recipe,RecipeCreateRequest,RecipeUpdateRequest,RecipeSummaryMealPlan,MealPlanCreateRequest,MealPlanUpdateRequestShoppingList,ShoppingListItem,ShoppingListCreateRequestUser,UserCreateRequest,UserUpdateRequestGroup,GroupSummaryUnit,UnitCreateRequest,UnitUpdateRequest,UnitSummaryFood,FoodCreateRequest,FoodUpdateRequest,FoodSummaryHousehold,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
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes and add tests
- Ensure all tests pass (
pdm run test) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - 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
- Issues: GitHub Issues
Disclaimer: This is an unofficial SDK and is not affiliated with or endorsed by the Mealie project.
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 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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5ad50094d05b2d49f144348e1afb2b70ae744a04089aa239bc33d6882b16cf6e
|
|
| MD5 |
96b7a32108c63c2dcd799a7dd09ee82f
|
|
| BLAKE2b-256 |
82704022c6a95d2f43d0dc8d7a42a10e552509ed9700ffc85d5af601afceaaaf
|
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fe4d3ab5d85aaabe8c1c05ea5b67009f99596a2fa62feb4f400db9b6b0b608f1
|
|
| MD5 |
3bd91b844474a1319f95b889d8dd8ac1
|
|
| BLAKE2b-256 |
9534c43d15a70e665b82e5e591554db155820e5448a52d20424139c64b53d59a
|