Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
18 changes: 11 additions & 7 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
# Change Log

## 15.3.0

* Added get_console_pausing health endpoint
* Added ttl parameter to list_documents and list_rows for cached responses
* Added optional activate parameter to Sites.create_deployment
* Updated docs and examples to reflect TTL usage and activation
* Updated query filtering docs in Messaging service
## 16.0.0

* Breaking change: All service methods now return typed Pydantic models instead of `Dict[str, Any]`
* Breaking change: Models with dynamic fields (e.g., `Row`, `Document`) now store user-defined data in a typed `.data` property instead of direct attribute access
* Breaking change: Added `pydantic>=2,<3` as a required dependency
* Breaking change: Minimum Python version raised from 3.5 to 3.9
* Added `AppwriteModel` base class (Pydantic `BaseModel`) for all response models with `from_dict()` and `to_dict()` helpers
* Added 130+ typed model classes under `appwrite/models/` (e.g., `Database`, `Collection`, `Document`, `User`, `Session`, `File`, `Bucket`, etc.)
* Added Generic[T] support for models with dynamic fields (e.g., `Row`, `Document`) - pass `model_type=YourModel` to methods like `get_row()` or `list_rows()` for type-safe access to user-defined data via `result.data.field_name`
* Updated README with `uv add appwrite` installation example
* Updated all doc examples to use typed response models (e.g., `result: TemplateFunctionList = functions.list_templates(...)`)

## 15.2.0

Expand Down
72 changes: 69 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ To install via [PyPI](https://pypi.org/):
pip install appwrite
```

Or with `uv`:

```bash
uv add appwrite
```


## Getting Started

Expand All @@ -43,10 +49,16 @@ client = Client()
### Make Your First Request
Once your SDK object is set, create any of the Appwrite service objects and choose any request to send. Full documentation for any service method you would like to use can be found in your SDK documentation or in the [API References](https://appwrite.io/docs) section.

All service methods return typed Pydantic models, so you can access response fields as attributes:

```python
users = Users(client)

result = users.create(ID.unique(), email = "email@example.com", phone = "+123456789", password = "password", name = "Walter O'Brien")
user = users.create(ID.unique(), email = "email@example.com", phone = "+123456789", password = "password", name = "Walter O'Brien")

print(user.name) # "Walter O'Brien"
print(user.email) # "email@example.com"
print(user.id) # The generated user ID
```

### Full Example
Expand All @@ -66,7 +78,60 @@ client = Client()

users = Users(client)

result = users.create(ID.unique(), email = "email@example.com", phone = "+123456789", password = "password", name = "Walter O'Brien")
user = users.create(ID.unique(), email = "email@example.com", phone = "+123456789", password = "password", name = "Walter O'Brien")

print(user.name) # Access fields as attributes
print(user.to_dict()) # Convert to dictionary if needed
```

### Type Safety with Models

The Appwrite Python SDK provides type safety when working with database rows through generic methods. Methods like `get_row`, `list_rows`, and others accept a `model_type` parameter that allows you to specify your custom Pydantic model for full type safety.

```python
from pydantic import BaseModel
from datetime import datetime
from typing import Optional
from appwrite.client import Client
from appwrite.services.tables_db import TablesDB

# Define your custom model matching your table schema
class Post(BaseModel):
postId: int
authorId: int
title: str
content: str
createdAt: datetime
updatedAt: datetime
isPublished: bool
excerpt: Optional[str] = None

client = Client()
# ... configure your client ...

tables_db = TablesDB(client)

# Fetch a single row with type safety
row = tables_db.get_row(
database_id="your-database-id",
table_id="your-table-id",
row_id="your-row-id",
model_type=Post # Pass your custom model type
)

print(row.data.title) # Fully typed - IDE autocomplete works
print(row.data.postId) # int type, not Any
print(row.data.createdAt) # datetime type

# Fetch multiple rows with type safety
result = tables_db.list_rows(
database_id="your-database-id",
table_id="your-table-id",
model_type=Post
)

for row in result.rows:
print(f"{row.data.title} by {row.data.authorId}")
```

### Error Handling
Expand All @@ -75,7 +140,8 @@ The Appwrite Python SDK raises `AppwriteException` object with `message`, `code`
```python
users = Users(client)
try:
result = users.create(ID.unique(), email = "email@example.com", phone = "+123456789", password = "password", name = "Walter O'Brien")
user = users.create(ID.unique(), email = "email@example.com", phone = "+123456789", password = "password", name = "Walter O'Brien")
print(user.name)
except AppwriteException as e:
print(e.message)
```
Expand Down
4 changes: 2 additions & 2 deletions appwrite/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ def __init__(self):
self._endpoint = 'https://cloud.appwrite.io/v1'
self._global_headers = {
'content-type': '',
'user-agent' : f'AppwritePythonSDK/15.3.0 ({platform.uname().system}; {platform.uname().version}; {platform.uname().machine})',
'user-agent' : f'AppwritePythonSDK/16.0.0 ({platform.uname().system}; {platform.uname().version}; {platform.uname().machine})',
'x-sdk-name': 'Python',
'x-sdk-platform': 'server',
'x-sdk-language': 'python',
'x-sdk-version': '15.3.0',
'x-sdk-version': '16.0.0',
'X-Appwrite-Response-Format' : '1.8.0',
}

Expand Down
6 changes: 5 additions & 1 deletion appwrite/encoders/value_class_encoder.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import json
from ..models.base_model import AppwriteModel
from ..enums.authenticator_type import AuthenticatorType
from ..enums.authentication_factor import AuthenticationFactor
from ..enums.o_auth_provider import OAuthProvider
Expand Down Expand Up @@ -43,6 +44,9 @@

class ValueClassEncoder(json.JSONEncoder):
def default(self, o):
if isinstance(o, AppwriteModel):
return o.to_dict()

if isinstance(o, AuthenticatorType):
return o.value

Expand Down Expand Up @@ -166,4 +170,4 @@ def default(self, o):
if isinstance(o, MessageStatus):
return o.value

return super().default(o)
return super().default(o)
Loading