Skip to content

Commit

Permalink
Merge pull request #80 from appwrite/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
abnegate authored Mar 8, 2024
2 parents 1473969 + 99aa333 commit 38e762e
Show file tree
Hide file tree
Showing 290 changed files with 4,864 additions and 1,434 deletions.
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Copyright (c) 2023 Appwrite (https://appwrite.io) and individual contributors.
Copyright (c) 2024 Appwrite (https://appwrite.io) and individual contributors.
All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
Expand Down
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
# Appwrite Python SDK

![License](https://img.shields.io/github/license/appwrite/sdk-for-python.svg?style=flat-square)
![Version](https://img.shields.io/badge/api%20version-1.4.12-blue.svg?style=flat-square)
![Version](https://img.shields.io/badge/api%20version-1.5.0-blue.svg?style=flat-square)
[![Build Status](https://img.shields.io/travis/com/appwrite/sdk-generator?style=flat-square)](https://travis-ci.com/appwrite/sdk-generator)
[![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 1.4.x. For older versions, please check [previous releases](https://github.com/appwrite/sdk-for-python/releases).**
**This SDK is compatible with Appwrite server version 1.5.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 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)

![Appwrite](https://appwrite.io/images/github.png)
![Appwrite](https://github.com/appwrite/appwrite/raw/main/public/images/github.png)

## Installation

Expand Down Expand Up @@ -46,7 +46,7 @@ Once your SDK object is set, create any of the Appwrite service objects and choo
```python
users = Users(client)

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

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

users = Users(client)

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

### Error Handling
Expand All @@ -75,7 +75,7 @@ The Appwrite Python SDK raises `AppwriteException` object with `message`, `code`
```python
users = Users(client)
try:
result = users.create(ID.unique(), 'email@example.com', 'password')
result = users.create(ID.unique(), email = "email@example.com", phone = "+123456789", password = "password", name = "Walter O'Brien")
except AppwriteException as e:
print(e.message)
```
Expand Down
39 changes: 28 additions & 11 deletions appwrite/client.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
import io
import requests
import json
import os
import requests
from .input_file import InputFile
from .exception import AppwriteException
from .encoders.value_class_encoder import ValueClassEncoder

class Client:
def __init__(self):
self._chunk_size = 5*1024*1024
self._self_signed = False
self._endpoint = 'https://HOSTNAME/v1'
self._endpoint = 'https://cloud.appwrite.io/v1'
self._global_headers = {
'content-type': '',
'user-agent' : 'AppwritePythonSDK/4.1.0 (${os.uname().sysname}; ${os.uname().version}; ${os.uname().machine})',
'user-agent' : 'AppwritePythonSDK/5.0.0 (${os.uname().sysname}; ${os.uname().version}; ${os.uname().machine})',
'x-sdk-name': 'Python',
'x-sdk-platform': 'server',
'x-sdk-language': 'python',
'x-sdk-version': '4.1.0',
'X-Appwrite-Response-Format' : '1.4.0',
'x-sdk-version': '5.0.0',
'X-Appwrite-Response-Format' : '1.5.0',
}

def set_self_signed(self, status=True):
Expand Down Expand Up @@ -53,7 +55,19 @@ def set_locale(self, value):
self._global_headers['x-appwrite-locale'] = value
return self

def call(self, method, path='', headers=None, params=None):
def set_session(self, value):
"""The user session to authenticate with"""

self._global_headers['x-appwrite-session'] = value
return self

def set_forwarded_user_agent(self, value):
"""The user agent string of the client that made the request"""

self._global_headers['x-forwarded-user-agent'] = value
return self

def call(self, method, path='', headers=None, params=None, response_type='json'):
if headers is None:
headers = {}

Expand All @@ -63,7 +77,6 @@ def call(self, method, path='', headers=None, params=None):
params = {k: v for k, v in params.items() if v is not None} # Remove None values from params dictionary

data = {}
json = {}
files = {}
stringify = False

Expand All @@ -74,8 +87,7 @@ def call(self, method, path='', headers=None, params=None):
params = {}

if headers['content-type'].startswith('application/json'):
json = data
data = {}
data = json.dumps(data, cls=ValueClassEncoder)

if headers['content-type'].startswith('multipart/form-data'):
del headers['content-type']
Expand All @@ -84,23 +96,28 @@ def call(self, method, path='', headers=None, params=None):
if isinstance(data[key], InputFile):
files[key] = (data[key].filename, data[key].data)
del data[key]
data = self.flatten(data, stringify=stringify)

response = None
try:
response = requests.request( # call method dynamically https://stackoverflow.com/a/4246075/2299554
method=method,
url=self._endpoint + path,
params=self.flatten(params, stringify=stringify),
data=self.flatten(data),
json=json,
data=data,
files=files,
headers=headers,
verify=(not self._self_signed),
allow_redirects=False if response_type == 'location' else True
)

response.raise_for_status()

content_type = response.headers['Content-Type']

if response_type == 'location':
return response.headers.get('Location')

if content_type.startswith('application/json'):
return response.json()

Expand Down
1 change: 1 addition & 0 deletions appwrite/encoders/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

77 changes: 77 additions & 0 deletions appwrite/encoders/value_class_encoder.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import json
from ..enums.authenticator_type import AuthenticatorType
from ..enums.authentication_factor import AuthenticationFactor
from ..enums.o_auth_provider import OAuthProvider
from ..enums.browser import Browser
from ..enums.credit_card import CreditCard
from ..enums.flag import Flag
from ..enums.relationship_type import RelationshipType
from ..enums.relation_mutate import RelationMutate
from ..enums.index_type import IndexType
from ..enums.runtime import Runtime
from ..enums.execution_method import ExecutionMethod
from ..enums.name import Name
from ..enums.smtp_encryption import SmtpEncryption
from ..enums.compression import Compression
from ..enums.image_gravity import ImageGravity
from ..enums.image_format import ImageFormat
from ..enums.password_hash import PasswordHash
from ..enums.messaging_provider_type import MessagingProviderType

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

return super().default(o)
1 change: 1 addition & 0 deletions appwrite/enums/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

7 changes: 7 additions & 0 deletions appwrite/enums/authentication_factor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from enum import Enum

class AuthenticationFactor(Enum):
EMAIL = "email"
PHONE = "phone"
TOTP = "totp"
RECOVERYCODE = "recoverycode"
4 changes: 4 additions & 0 deletions appwrite/enums/authenticator_type.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from enum import Enum

class AuthenticatorType(Enum):
TOTP = "totp"
17 changes: 17 additions & 0 deletions appwrite/enums/browser.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from enum import Enum

class Browser(Enum):
AVANT_BROWSER = "aa"
ANDROID_WEBVIEW_BETA = "an"
GOOGLE_CHROME = "ch"
GOOGLE_CHROME_IOS = "ci"
GOOGLE_CHROME_MOBILE = "cm"
CHROMIUM = "cr"
MOZILLA_FIREFOX = "ff"
SAFARI = "sf"
MOBILE_SAFARI = "mf"
MICROSOFT_EDGE = "ps"
MICROSOFT_EDGE_IOS = "oi"
OPERA_MINI = "om"
OPERA = "op"
OPERA_NEXT = "on"
6 changes: 6 additions & 0 deletions appwrite/enums/compression.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from enum import Enum

class Compression(Enum):
NONE = "none"
GZIP = "gzip"
ZSTD = "zstd"
19 changes: 19 additions & 0 deletions appwrite/enums/credit_card.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from enum import Enum

class CreditCard(Enum):
AMERICAN_EXPRESS = "amex"
ARGENCARD = "argencard"
CABAL = "cabal"
CONSOSUD = "censosud"
DINERS_CLUB = "diners"
DISCOVER = "discover"
ELO = "elo"
HIPERCARD = "hipercard"
JCB = "jcb"
MASTERCARD = "mastercard"
NARANJA = "naranja"
TARJETA_SHOPPING = "targeta-shopping"
UNION_CHINA_PAY = "union-china-pay"
VISA = "visa"
MIR = "mir"
MAESTRO = "maestro"
9 changes: 9 additions & 0 deletions appwrite/enums/execution_method.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from enum import Enum

class ExecutionMethod(Enum):
GET = "GET"
POST = "POST"
PUT = "PUT"
PATCH = "PATCH"
DELETE = "DELETE"
OPTIONS = "OPTIONS"
Loading

0 comments on commit 38e762e

Please sign in to comment.