Skip to content
Merged
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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# Change Log

## 15.2.0

* Extended BuildRuntime and Runtime enums with new runtime versions (e.g., node-23/24/25, php-8.4, ruby-3.4/4.0, python-3.13/3.14, python-ml-3.13, deno-2.5/2.6, dotnet-10, java-25, swift-6.2, kotlin-2.3, bun-1.2/1.3, go-1.24/1.25/1.26).
* Added new permission scopes: schedules.read, schedules.write, and events.read.
* Added contains_any and contains_all filter helpers to the Query API (plus enhanced contains with docstrings).
* Added optional encrypt parameter to all string attribute creation methods (e.g., longtext, mediumtext, text, varchar) in Databases to support encryption at rest.
* Updated README to reflect Appwrite server compatibility version 1.8.x.
* Backward-compatible enhancements: no breaking changes.

## 15.1.0

* Add `dart-3.10` and `flutter-3.38` to `BuildRuntime` and `Runtime` enums
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
[![Twitter Account](https://img.shields.io/twitter/follow/appwrite?color=00acee&label=twitter&style=flat-square)](https://twitter.com/appwrite)
[![Discord](https://img.shields.io/discord/564160730845151244?label=discord&style=flat-square)](https://appwrite.io/discord)

**This SDK is compatible with Appwrite server version latest. For older versions, please check [previous releases](https://github.com/appwrite/sdk-for-python/releases).**
**This SDK is compatible with Appwrite server version 1.8.x. For older versions, please check [previous releases](https://github.com/appwrite/sdk-for-python/releases).**

Appwrite is an open-source backend as a service server that abstracts and simplifies complex and repetitive development tasks behind a very simple to use REST API. Appwrite aims to help you develop your apps faster and in a more secure way. Use the Python SDK to integrate your app with the Appwrite server to easily start interacting with all of Appwrite backend APIs and tools. For full API documentation and tutorials go to [https://appwrite.io/docs](https://appwrite.io/docs)

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.1.0 ({platform.uname().system}; {platform.uname().version}; {platform.uname().machine})',
'user-agent' : f'AppwritePythonSDK/15.2.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.1.0',
'x-sdk-version': '15.2.0',
'X-Appwrite-Response-Format' : '1.8.0',
}

Expand Down
20 changes: 20 additions & 0 deletions appwrite/enums/build_runtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,35 @@ class BuildRuntime(Enum):
NODE_20_0 = "node-20.0"
NODE_21_0 = "node-21.0"
NODE_22 = "node-22"
NODE_23 = "node-23"
NODE_24 = "node-24"
NODE_25 = "node-25"
PHP_8_0 = "php-8.0"
PHP_8_1 = "php-8.1"
PHP_8_2 = "php-8.2"
PHP_8_3 = "php-8.3"
PHP_8_4 = "php-8.4"
RUBY_3_0 = "ruby-3.0"
RUBY_3_1 = "ruby-3.1"
RUBY_3_2 = "ruby-3.2"
RUBY_3_3 = "ruby-3.3"
RUBY_3_4 = "ruby-3.4"
RUBY_4_0 = "ruby-4.0"
PYTHON_3_8 = "python-3.8"
PYTHON_3_9 = "python-3.9"
PYTHON_3_10 = "python-3.10"
PYTHON_3_11 = "python-3.11"
PYTHON_3_12 = "python-3.12"
PYTHON_3_13 = "python-3.13"
PYTHON_3_14 = "python-3.14"
PYTHON_ML_3_11 = "python-ml-3.11"
PYTHON_ML_3_12 = "python-ml-3.12"
PYTHON_ML_3_13 = "python-ml-3.13"
DENO_1_40 = "deno-1.40"
DENO_1_46 = "deno-1.46"
DENO_2_0 = "deno-2.0"
DENO_2_5 = "deno-2.5"
DENO_2_6 = "deno-2.6"
DART_2_15 = "dart-2.15"
DART_2_16 = "dart-2.16"
DART_2_17 = "dart-2.17"
Expand All @@ -41,25 +52,34 @@ class BuildRuntime(Enum):
DOTNET_6_0 = "dotnet-6.0"
DOTNET_7_0 = "dotnet-7.0"
DOTNET_8_0 = "dotnet-8.0"
DOTNET_10 = "dotnet-10"
JAVA_8_0 = "java-8.0"
JAVA_11_0 = "java-11.0"
JAVA_17_0 = "java-17.0"
JAVA_18_0 = "java-18.0"
JAVA_21_0 = "java-21.0"
JAVA_22 = "java-22"
JAVA_25 = "java-25"
SWIFT_5_5 = "swift-5.5"
SWIFT_5_8 = "swift-5.8"
SWIFT_5_9 = "swift-5.9"
SWIFT_5_10 = "swift-5.10"
SWIFT_6_2 = "swift-6.2"
KOTLIN_1_6 = "kotlin-1.6"
KOTLIN_1_8 = "kotlin-1.8"
KOTLIN_1_9 = "kotlin-1.9"
KOTLIN_2_0 = "kotlin-2.0"
KOTLIN_2_3 = "kotlin-2.3"
CPP_17 = "cpp-17"
CPP_20 = "cpp-20"
BUN_1_0 = "bun-1.0"
BUN_1_1 = "bun-1.1"
BUN_1_2 = "bun-1.2"
BUN_1_3 = "bun-1.3"
GO_1_23 = "go-1.23"
GO_1_24 = "go-1.24"
GO_1_25 = "go-1.25"
GO_1_26 = "go-1.26"
STATIC_1 = "static-1"
FLUTTER_3_24 = "flutter-3.24"
FLUTTER_3_27 = "flutter-3.27"
Expand Down
20 changes: 20 additions & 0 deletions appwrite/enums/runtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,35 @@ class Runtime(Enum):
NODE_20_0 = "node-20.0"
NODE_21_0 = "node-21.0"
NODE_22 = "node-22"
NODE_23 = "node-23"
NODE_24 = "node-24"
NODE_25 = "node-25"
PHP_8_0 = "php-8.0"
PHP_8_1 = "php-8.1"
PHP_8_2 = "php-8.2"
PHP_8_3 = "php-8.3"
PHP_8_4 = "php-8.4"
RUBY_3_0 = "ruby-3.0"
RUBY_3_1 = "ruby-3.1"
RUBY_3_2 = "ruby-3.2"
RUBY_3_3 = "ruby-3.3"
RUBY_3_4 = "ruby-3.4"
RUBY_4_0 = "ruby-4.0"
PYTHON_3_8 = "python-3.8"
PYTHON_3_9 = "python-3.9"
PYTHON_3_10 = "python-3.10"
PYTHON_3_11 = "python-3.11"
PYTHON_3_12 = "python-3.12"
PYTHON_3_13 = "python-3.13"
PYTHON_3_14 = "python-3.14"
PYTHON_ML_3_11 = "python-ml-3.11"
PYTHON_ML_3_12 = "python-ml-3.12"
PYTHON_ML_3_13 = "python-ml-3.13"
DENO_1_40 = "deno-1.40"
DENO_1_46 = "deno-1.46"
DENO_2_0 = "deno-2.0"
DENO_2_5 = "deno-2.5"
DENO_2_6 = "deno-2.6"
DART_2_15 = "dart-2.15"
DART_2_16 = "dart-2.16"
DART_2_17 = "dart-2.17"
Expand All @@ -41,25 +52,34 @@ class Runtime(Enum):
DOTNET_6_0 = "dotnet-6.0"
DOTNET_7_0 = "dotnet-7.0"
DOTNET_8_0 = "dotnet-8.0"
DOTNET_10 = "dotnet-10"
JAVA_8_0 = "java-8.0"
JAVA_11_0 = "java-11.0"
JAVA_17_0 = "java-17.0"
JAVA_18_0 = "java-18.0"
JAVA_21_0 = "java-21.0"
JAVA_22 = "java-22"
JAVA_25 = "java-25"
SWIFT_5_5 = "swift-5.5"
SWIFT_5_8 = "swift-5.8"
SWIFT_5_9 = "swift-5.9"
SWIFT_5_10 = "swift-5.10"
SWIFT_6_2 = "swift-6.2"
KOTLIN_1_6 = "kotlin-1.6"
KOTLIN_1_8 = "kotlin-1.8"
KOTLIN_1_9 = "kotlin-1.9"
KOTLIN_2_0 = "kotlin-2.0"
KOTLIN_2_3 = "kotlin-2.3"
CPP_17 = "cpp-17"
CPP_20 = "cpp-20"
BUN_1_0 = "bun-1.0"
BUN_1_1 = "bun-1.1"
BUN_1_2 = "bun-1.2"
BUN_1_3 = "bun-1.3"
GO_1_23 = "go-1.23"
GO_1_24 = "go-1.24"
GO_1_25 = "go-1.25"
GO_1_26 = "go-1.26"
STATIC_1 = "static-1"
FLUTTER_3_24 = "flutter-3.24"
FLUTTER_3_27 = "flutter-3.27"
Expand Down
3 changes: 3 additions & 0 deletions appwrite/enums/scopes.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ class Scopes(Enum):
TARGETS_WRITE = "targets.write"
RULES_READ = "rules.read"
RULES_WRITE = "rules.write"
SCHEDULES_READ = "schedules.read"
SCHEDULES_WRITE = "schedules.write"
MIGRATIONS_READ = "migrations.read"
MIGRATIONS_WRITE = "migrations.write"
VCS_READ = "vcs.read"
Expand All @@ -64,3 +66,4 @@ class Scopes(Enum):
RESTORATIONS_WRITE = "restorations.write"
DOMAINS_READ = "domains.read"
DOMAINS_WRITE = "domains.write"
EVENTS_READ = "events.read"
24 changes: 24 additions & 0 deletions appwrite/query.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,32 @@ def offset(offset):

@staticmethod
def contains(attribute, value):
"""
Filter resources where attribute contains the specified value.
For string attributes, checks if the string contains the substring.

Note: For array attributes, use contains_any() or contains_all() instead.
"""
return str(Query("contains", attribute, value))

@staticmethod
def contains_any(attribute, value):
"""
Filter resources where attribute contains ANY of the specified values.
For array and relationship attributes, matches documents where the attribute
contains at least one of the given values.
"""
return str(Query("containsAny", attribute, value))

@staticmethod
def contains_all(attribute, value):
"""
Filter resources where attribute contains ALL of the specified values.
For array and relationship attributes, matches documents where the attribute
contains every one of the given values.
"""
return str(Query("containsAll", attribute, value))

@staticmethod
def not_contains(attribute, value):
return str(Query("notContains", attribute, value))
Expand Down
70 changes: 70 additions & 0 deletions appwrite/services/activities.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
from ..service import Service
from typing import List, Dict, Any, Optional
from ..exception import AppwriteException
from appwrite.utils.deprecated import deprecated

class Activities(Service):

def __init__(self, client) -> None:
super(Activities, self).__init__(client)

def list_events(self, queries: Optional[str] = None) -> Dict[str, Any]:
"""
List all events for selected filters.

Parameters
----------
queries : Optional[str]
Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/databases#querying-documents). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on attributes such as userId, teamId, etc.

Returns
-------
Dict[str, Any]
API response as a dictionary

Raises
------
AppwriteException
If API request fails
"""

api_path = '/activities/events'
api_params = {}

if queries is not None:
api_params['queries'] = queries

return self.client.call('get', api_path, {
}, api_params)

def get_event(self, event_id: str) -> Dict[str, Any]:
"""
Get event by ID.


Parameters
----------
event_id : str
Event ID.

Returns
-------
Dict[str, Any]
API response as a dictionary

Raises
------
AppwriteException
If API request fails
"""

api_path = '/activities/events/{eventId}'
api_params = {}
if event_id is None:
raise AppwriteException('Missing required parameter: "event_id"')

api_path = api_path.replace('{eventId}', event_id)


return self.client.call('get', api_path, {
}, api_params)
Loading