Skip to content

Commit 5b35de7

Browse files
feat: support for 0.13.0
1 parent c046820 commit 5b35de7

29 files changed

+517
-127
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
# Appwrite Python SDK
22

33
![License](https://img.shields.io/github/license/appwrite/sdk-for-python.svg?style=flat-square)
4-
![Version](https://img.shields.io/badge/api%20version-0.12.0-blue.svg?style=flat-square)
4+
![Version](https://img.shields.io/badge/api%20version-0.13.0-blue.svg?style=flat-square)
55
[![Build Status](https://img.shields.io/travis/com/appwrite/sdk-generator?style=flat-square)](https://travis-ci.com/appwrite/sdk-generator)
66
[![Twitter Account](https://img.shields.io/twitter/follow/appwrite?color=00acee&label=twitter&style=flat-square)](https://twitter.com/appwrite)
77
[![Discord](https://img.shields.io/discord/564160730845151244?label=discord&style=flat-square)](https://appwrite.io/discord)
88

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

1111
Appwrite is an open-source backend as a service server that abstract and simplify 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)
1212

appwrite/client.py

Lines changed: 71 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
11
import io
22
import requests
3+
import os
4+
from .input_file import InputFile
35
from .exception import AppwriteException
46

57
class Client:
68
def __init__(self):
9+
self._chunk_size = 5*1024*1024
710
self._self_signed = False
811
self._endpoint = 'https://HOSTNAME/v1'
912
self._global_headers = {
1013
'content-type': '',
11-
'x-sdk-version': 'appwrite:python:0.6.1',
12-
'X-Appwrite-Response-Format' : '0.12.0',
14+
'x-sdk-version': 'appwrite:python:0.6.0',
15+
'X-Appwrite-Response-Format' : '0.13.0',
1316
}
1417

1518
def set_self_signed(self, status=True):
@@ -56,6 +59,7 @@ def call(self, method, path='', headers=None, params=None):
5659
data = {}
5760
json = {}
5861
files = {}
62+
stringify = False
5963

6064
headers = {**self._global_headers, **headers}
6165

@@ -69,17 +73,17 @@ def call(self, method, path='', headers=None, params=None):
6973

7074
if headers['content-type'].startswith('multipart/form-data'):
7175
del headers['content-type']
72-
76+
stringify = True
7377
for key in data.copy():
74-
if isinstance(data[key], io.BufferedIOBase):
75-
files[key] = data[key]
78+
if isinstance(data[key], InputFile):
79+
files[key] = (data[key].name, data[key].file)
7680
del data[key]
7781
response = None
7882
try:
7983
response = requests.request( # call method dynamically https://stackoverflow.com/a/4246075/2299554
8084
method=method,
8185
url=self._endpoint + path,
82-
params=self.flatten(params),
86+
params=self.flatten(params, stringify=stringify),
8387
data=self.flatten(data),
8488
json=json,
8589
files=files,
@@ -99,13 +103,67 @@ def call(self, method, path='', headers=None, params=None):
99103
if response != None:
100104
content_type = response.headers['Content-Type']
101105
if content_type.startswith('application/json'):
102-
raise AppwriteException(response.json()['message'], response.status_code, response.json())
106+
raise AppwriteException(response.json()['message'], response.status_code, response.json().get('type'), response.json())
103107
else:
104108
raise AppwriteException(response.text, response.status_code)
105109
else:
106110
raise AppwriteException(e)
107111

108-
def flatten(self, data, prefix=''):
112+
def chunked_upload(
113+
self,
114+
path,
115+
headers = None,
116+
params = None,
117+
param_name = '',
118+
on_progress = None,
119+
):
120+
file_path = str(params[param_name])
121+
file_name = os.path.basename(file_path)
122+
size = os.stat(file_path).st_size
123+
124+
if size < self._chunk_size:
125+
slice = open(file_path, 'rb').read()
126+
params[param_name] = InputFile(file_path, file_name, slice)
127+
return self.call(
128+
'post',
129+
path,
130+
headers,
131+
params
132+
)
133+
134+
input = open(file_path, 'rb')
135+
offset = 0
136+
137+
while offset < size:
138+
slice = input.read(self._chunk_size) or input.read(size - offset)
139+
140+
params[param_name] = InputFile(file_path, file_name, slice)
141+
headers["content-range"] = f'bytes {offset}-{min((offset + self._chunk_size) - 1, size)}/{size}'
142+
143+
result = self.call(
144+
'post',
145+
path,
146+
headers,
147+
params,
148+
)
149+
150+
offset = offset + self._chunk_size
151+
152+
if "$id" in result:
153+
headers["x-appwrite-id"] = result["$id"]
154+
155+
if on_progress is not None:
156+
on_progress({
157+
"$id": result["$id"],
158+
"progress": min(offset, size)/size * 100,
159+
"sizeUploaded": end+1,
160+
"chunksTotal": result["chunksTotal"],
161+
"chunksUploaded": result["chunksUploaded"],
162+
})
163+
164+
return result
165+
166+
def flatten(self, data, prefix='', stringify=False):
109167
output = {}
110168
i = 0
111169

@@ -116,9 +174,12 @@ def flatten(self, data, prefix=''):
116174
i += 1
117175

118176
if isinstance(value, list) or isinstance(value, dict):
119-
output = {**output, **self.flatten(value, finalKey)}
177+
output = {**output, **self.flatten(value, finalKey, stringify)}
120178
else:
121-
output[finalKey] = value
179+
if stringify:
180+
output[finalKey] = str(value)
181+
else:
182+
output[finalKey] = value
122183

123184
return output
124185

appwrite/exception.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
class AppwriteException(Exception):
2-
def __init__(self, message, code = 0, response = None):
2+
def __init__(self, message, code = 0, type = None, response = None):
33
self.message = message
44
self.code = code
5+
self.type = type
56
self.response = response
67
super().__init__(self.message)

appwrite/input_file.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
class InputFile:
2+
def __init__(self, path, name, file):
3+
self.path = path
4+
self.name = name
5+
self.file = file

appwrite/services/account.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,20 @@ def get_session(self, session_id):
215215
'content-type': 'application/json',
216216
}, params)
217217

218+
def update_session(self, session_id):
219+
"""Update Session (Refresh Tokens)"""
220+
221+
if session_id is None:
222+
raise AppwriteException('Missing required parameter: "session_id"')
223+
224+
params = {}
225+
path = '/account/sessions/{sessionId}'
226+
path = path.replace('{sessionId}', session_id)
227+
228+
return self.client.call('patch', path, {
229+
'content-type': 'application/json',
230+
}, params)
231+
218232
def delete_session(self, session_id):
219233
"""Delete Account Session"""
220234

0 commit comments

Comments
 (0)