# py-cozi-client
An unofficial Python client for the Cozi Family Organizer API that provides a robust and type-safe interface to the Cozi service.
## Features
- **Async/await support** - Built with `aiohttp` for efficient async operations
- **Type safety** - Full type hints and Pydantic models for all API interactions
- **Comprehensive API coverage** - Support for lists, calendar, and account management
- **Error handling** - Custom exception classes for different error scenarios
- **Rate limiting** - Built-in rate limit handling and retry logic
- **Authentication** - Secure credential management and session handling
## Installation
```bash
pip install py-cozi-client
```
For development:
```bash
pip install py-cozi-client[dev]
```
## Quick Start
```python
import asyncio
from cozi_client import CoziClient
from models import ListType, ItemStatus
async def main():
async with CoziClient("your_username", "your_password") as client:
# Create a shopping list
shopping_list = await client.create_list("Groceries", ListType.SHOPPING)
# Add items to the list
await client.add_item(shopping_list.id, "Milk")
await client.add_item(shopping_list.id, "Bread")
# Get all lists
lists = await client.get_lists()
for lst in lists:
print(f"List: {lst.title} ({lst.list_type})")
asyncio.run(main())
```
## API Reference
### CoziClient
The main client class for interacting with the Cozi API.
#### Authentication
```python
# Authentication happens automatically with username/password in constructor
client = CoziClient(username, password)
# Or logout manually
await client.logout()
```
#### List Management
```python
# Create lists
await client.create_list(title: str, list_type: ListType) -> CoziList
# Get lists
await client.get_lists() -> List[CoziList]
await client.get_lists_by_type(list_type: ListType) -> List[CoziList]
# Update lists
await client.update_list(list_obj: CoziList) -> CoziList
# Delete lists
await client.delete_list(list_id: str) -> bool
```
#### Item Management
```python
# Add items
await client.add_item(list_id: str, text: str, position: int = 0) -> CoziItem
# Update item text
await client.update_item_text(list_id: str, item_id: str, text: str) -> CoziItem
# Mark item status
await client.mark_item(list_id: str, item_id: str, status: ItemStatus) -> CoziItem
# Remove items
await client.remove_items(list_id: str, item_ids: List[str]) -> bool
```
#### Calendar Operations
```python
# Get calendar for a specific month
await client.get_calendar(year: int, month: int) -> List[CoziAppointment]
# Create appointments
await client.create_appointment(appointment: CoziAppointment) -> CoziAppointment
# Update appointments
await client.update_appointment(appointment: CoziAppointment) -> CoziAppointment
# Delete appointments
await client.delete_appointment(appointment_id: str, year: int, month: int) -> bool
```
#### Account Management
```python
# Get family members
await client.get_family_members() -> List[CoziPerson]
# Get account information
await client.get_account_info()
```
### Data Models
All models are built with Pydantic for automatic validation, serialization, and type safety.
#### CoziList
```python
class CoziList(BaseModel):
id: Optional[str]
title: str
list_type: ListType # Automatically converted to string values
items: List[CoziItem]
owner: Optional[str] = None
version: Optional[int] = None
notes: Optional[str] = None
created_at: Optional[datetime] = None
updated_at: Optional[datetime] = None
```
#### CoziItem
```python
class CoziItem(BaseModel):
id: Optional[str]
text: str
status: ItemStatus # Automatically converted to string values
position: Optional[int] = None
item_type: Optional[str] = None
due_date: Optional[date] = None
notes: Optional[str] = None
owner: Optional[str] = None
version: Optional[int] = None
created_at: Optional[datetime] = None
updated_at: Optional[datetime] = None
```
#### CoziAppointment
```python
class CoziAppointment(BaseModel):
id: Optional[str]
subject: str
start_day: date
start_time: Optional[time]
end_time: Optional[time]
date_span: int = 0
attendees: List[str] = []
location: Optional[str] = None
notes: Optional[str] = None
# ... additional fields for recurrence, item details, etc.
```
#### CoziPerson
```python
class CoziPerson(BaseModel):
id: str
name: str
email: Optional[str] = None
phone: Optional[str] = None
color: Optional[int] = None
# ... additional account fields
```
### Enums
```python
class ListType(Enum):
SHOPPING = "shopping"
TODO = "todo"
class ItemStatus(Enum):
COMPLETE = "complete"
INCOMPLETE = "incomplete"
```
### Exceptions
- `CoziException` - Base exception class
- `AuthenticationError` - Authentication failures
- `ValidationError` - Request validation errors
- `RateLimitError` - API rate limit exceeded
- `APIError` - General API errors
- `NetworkError` - Network connectivity issues
- `ResourceNotFoundError` - Resource not found (404)
## Development
### Setup
```bash
git clone <repository-url>
cd py-cozi-client
pip install -e .[dev]
```
## Examples
See the test files for comprehensive usage examples:
- `test_list_operations.py` - List and item management
- `test_calendar_operations.py` - Calendar and appointment management
## Requirements
- Python 3.7+
- aiohttp 3.9.2+
- pydantic 1.10.0+
## License
MIT License
## Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
## Author
Matthew Jucius
Raw data
{
"_id": null,
"home_page": null,
"name": "py-cozi-client",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.7",
"maintainer_email": null,
"keywords": "cozi, family organizer, calendar, shopping list, todo, api client, async, pydantic",
"author": "Matthew Jucius",
"author_email": null,
"download_url": "https://files.pythonhosted.org/packages/cb/0a/a5a2722bca0b50a099cf634d0f4d57c60385549a540a8401765fe25adcda/py_cozi_client-1.3.0.tar.gz",
"platform": null,
"description": "# py-cozi-client\n\nAn unofficial Python client for the Cozi Family Organizer API that provides a robust and type-safe interface to the Cozi service.\n\n## Features\n\n- **Async/await support** - Built with `aiohttp` for efficient async operations\n- **Type safety** - Full type hints and Pydantic models for all API interactions\n- **Comprehensive API coverage** - Support for lists, calendar, and account management\n- **Error handling** - Custom exception classes for different error scenarios\n- **Rate limiting** - Built-in rate limit handling and retry logic\n- **Authentication** - Secure credential management and session handling\n\n## Installation\n\n```bash\npip install py-cozi-client\n```\n\nFor development:\n\n```bash\npip install py-cozi-client[dev]\n```\n\n## Quick Start\n\n```python\nimport asyncio\nfrom cozi_client import CoziClient\nfrom models import ListType, ItemStatus\n\nasync def main():\n async with CoziClient(\"your_username\", \"your_password\") as client:\n # Create a shopping list\n shopping_list = await client.create_list(\"Groceries\", ListType.SHOPPING)\n \n # Add items to the list\n await client.add_item(shopping_list.id, \"Milk\")\n await client.add_item(shopping_list.id, \"Bread\")\n \n # Get all lists\n lists = await client.get_lists()\n for lst in lists:\n print(f\"List: {lst.title} ({lst.list_type})\")\n\nasyncio.run(main())\n```\n\n## API Reference\n\n### CoziClient\n\nThe main client class for interacting with the Cozi API.\n\n#### Authentication\n```python\n# Authentication happens automatically with username/password in constructor\nclient = CoziClient(username, password)\n\n# Or logout manually\nawait client.logout()\n```\n\n#### List Management\n```python\n# Create lists\nawait client.create_list(title: str, list_type: ListType) -> CoziList\n\n# Get lists\nawait client.get_lists() -> List[CoziList]\nawait client.get_lists_by_type(list_type: ListType) -> List[CoziList]\n\n# Update lists\nawait client.update_list(list_obj: CoziList) -> CoziList\n\n# Delete lists\nawait client.delete_list(list_id: str) -> bool\n```\n\n#### Item Management\n```python\n# Add items\nawait client.add_item(list_id: str, text: str, position: int = 0) -> CoziItem\n\n# Update item text\nawait client.update_item_text(list_id: str, item_id: str, text: str) -> CoziItem\n\n# Mark item status\nawait client.mark_item(list_id: str, item_id: str, status: ItemStatus) -> CoziItem\n\n# Remove items\nawait client.remove_items(list_id: str, item_ids: List[str]) -> bool\n```\n\n#### Calendar Operations\n```python\n# Get calendar for a specific month\nawait client.get_calendar(year: int, month: int) -> List[CoziAppointment]\n\n# Create appointments\nawait client.create_appointment(appointment: CoziAppointment) -> CoziAppointment\n\n# Update appointments\nawait client.update_appointment(appointment: CoziAppointment) -> CoziAppointment\n\n# Delete appointments\nawait client.delete_appointment(appointment_id: str, year: int, month: int) -> bool\n```\n\n#### Account Management\n```python\n# Get family members\nawait client.get_family_members() -> List[CoziPerson]\n\n# Get account information\nawait client.get_account_info()\n```\n\n### Data Models\n\nAll models are built with Pydantic for automatic validation, serialization, and type safety.\n\n#### CoziList\n```python\nclass CoziList(BaseModel):\n id: Optional[str]\n title: str\n list_type: ListType # Automatically converted to string values\n items: List[CoziItem]\n owner: Optional[str] = None\n version: Optional[int] = None\n notes: Optional[str] = None\n created_at: Optional[datetime] = None\n updated_at: Optional[datetime] = None\n```\n\n#### CoziItem\n```python\nclass CoziItem(BaseModel):\n id: Optional[str]\n text: str\n status: ItemStatus # Automatically converted to string values\n position: Optional[int] = None\n item_type: Optional[str] = None\n due_date: Optional[date] = None\n notes: Optional[str] = None\n owner: Optional[str] = None\n version: Optional[int] = None\n created_at: Optional[datetime] = None\n updated_at: Optional[datetime] = None\n```\n\n#### CoziAppointment\n```python\nclass CoziAppointment(BaseModel):\n id: Optional[str]\n subject: str\n start_day: date\n start_time: Optional[time]\n end_time: Optional[time]\n date_span: int = 0\n attendees: List[str] = []\n location: Optional[str] = None\n notes: Optional[str] = None\n # ... additional fields for recurrence, item details, etc.\n```\n\n#### CoziPerson\n```python\nclass CoziPerson(BaseModel):\n id: str\n name: str\n email: Optional[str] = None\n phone: Optional[str] = None\n color: Optional[int] = None\n # ... additional account fields\n```\n\n### Enums\n\n```python\nclass ListType(Enum):\n SHOPPING = \"shopping\"\n TODO = \"todo\"\n\nclass ItemStatus(Enum):\n COMPLETE = \"complete\"\n INCOMPLETE = \"incomplete\"\n```\n\n### Exceptions\n\n- `CoziException` - Base exception class\n- `AuthenticationError` - Authentication failures\n- `ValidationError` - Request validation errors\n- `RateLimitError` - API rate limit exceeded\n- `APIError` - General API errors\n- `NetworkError` - Network connectivity issues\n- `ResourceNotFoundError` - Resource not found (404)\n\n## Development\n\n### Setup\n```bash\ngit clone <repository-url>\ncd py-cozi-client\npip install -e .[dev]\n```\n\n## Examples\n\nSee the test files for comprehensive usage examples:\n- `test_list_operations.py` - List and item management\n- `test_calendar_operations.py` - Calendar and appointment management\n\n## Requirements\n\n- Python 3.7+\n- aiohttp 3.9.2+\n- pydantic 1.10.0+\n\n## License\n\nMIT License\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n\n## Author\n\nMatthew Jucius\n",
"bugtrack_url": null,
"license": null,
"summary": "Async Python client for the Cozi Family Organizer API with Pydantic models, full type safety and comprehensive error handling",
"version": "1.3.0",
"project_urls": null,
"split_keywords": [
"cozi",
" family organizer",
" calendar",
" shopping list",
" todo",
" api client",
" async",
" pydantic"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "40118b9f7c7aea59822ce1326b915c8ba6ee4a72032937ceaf5d3b7378f9c315",
"md5": "2c27b424d9a2697dee94e871fa1ce8f5",
"sha256": "999984bbd33cf214776065edd454a703c5a54d34f28c88fd328e6abff9ded4ea"
},
"downloads": -1,
"filename": "py_cozi_client-1.3.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "2c27b424d9a2697dee94e871fa1ce8f5",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.7",
"size": 13482,
"upload_time": "2025-09-07T23:50:07",
"upload_time_iso_8601": "2025-09-07T23:50:07.638446Z",
"url": "https://files.pythonhosted.org/packages/40/11/8b9f7c7aea59822ce1326b915c8ba6ee4a72032937ceaf5d3b7378f9c315/py_cozi_client-1.3.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "cb0aa5a2722bca0b50a099cf634d0f4d57c60385549a540a8401765fe25adcda",
"md5": "1ab248bd40f0f9911811545e6a53a9d7",
"sha256": "dcf77bab79ddf1f274da2ba8f2db55fbcfea630f20ba88e7e8ef7ef926ba4bff"
},
"downloads": -1,
"filename": "py_cozi_client-1.3.0.tar.gz",
"has_sig": false,
"md5_digest": "1ab248bd40f0f9911811545e6a53a9d7",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.7",
"size": 14181,
"upload_time": "2025-09-07T23:50:08",
"upload_time_iso_8601": "2025-09-07T23:50:08.450329Z",
"url": "https://files.pythonhosted.org/packages/cb/0a/a5a2722bca0b50a099cf634d0f4d57c60385549a540a8401765fe25adcda/py_cozi_client-1.3.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-09-07 23:50:08",
"github": false,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"lcname": "py-cozi-client"
}