Skip to content

Commit c94729b

Browse files
committed
Initial Commit
0 parents  commit c94729b

File tree

13 files changed

+665
-0
lines changed

13 files changed

+665
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
*.pyc
2+
.idea

README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# chatkit-server-python
2+
3+
The Unofficial Python server SDK for Pusher Chatkit.
4+
5+
**WORK IN PROGRESS**
6+
7+
## Installation
8+
9+
```sh
10+
$ python3 setup.py install
11+
```
12+
13+
## Credits
14+
This work is sponsored by [LedgerX](https://ledgerx.com)

pusher_chatkit/__init__.py

Whitespace-only changes.

pusher_chatkit/backends/Requests.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import requests
2+
import json
3+
4+
5+
from pusher_chatkit.client import process_response
6+
7+
8+
class RequestsBackend(object):
9+
10+
def __init__(self):
11+
self.http = requests
12+
self.session = requests.Session()
13+
14+
def process_request(self, method, endpoint, body=None, token=None):
15+
headers = {'Content-Type': 'application/json'}
16+
17+
if token:
18+
headers['Authorization'] = 'Bearer {}'.format(token['token'])
19+
20+
resp = self.session.request(
21+
method,
22+
endpoint,
23+
headers=headers,
24+
data=json.dumps(body),
25+
timeout=30)
26+
27+
return process_response(resp.status_code, resp.text)

pusher_chatkit/backends/Tornado.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import json
2+
import tornado
3+
import tornado.httpclient
4+
5+
from tornado.concurrent import Future
6+
from pusher_chatkit.client import process_response
7+
8+
9+
class TornadoBackend(object):
10+
11+
def __init__(self):
12+
self.http = tornado.httpclient.AsyncHTTPClient()
13+
14+
def process_request(self, method, endpoint, body=None, token=None):
15+
data = body
16+
headers = {'Content-Type': 'application/json'}
17+
future = Future()
18+
19+
headers['Authorization'] = 'Bearer {}'.format(token['token'])
20+
21+
def process_response_future(response):
22+
if response.exception() is not None:
23+
future.set_exception(response.exception())
24+
25+
else:
26+
result = response.result()
27+
code = result.code
28+
body = (result.body or b'').decode('utf8')
29+
future.set_result(process_response(code, body))
30+
31+
request = tornado.httpclient.HTTPRequest(
32+
endpoint,
33+
method=method,
34+
body=json.dumps(data),
35+
headers=headers,
36+
request_timeout=30)
37+
38+
response_future = self.http.fetch(request, raise_error=False)
39+
response_future.add_done_callback(process_response_future)
40+
41+
return future
42+

pusher_chatkit/backends/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
from .Requests import RequestsBackend
2+
from .Tornado import TornadoBackend

pusher_chatkit/client.py

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
import json
2+
3+
from pusher_chatkit.exceptions import PusherBadAuth, PusherBadRequest, PusherBadStatus, PusherForbidden
4+
from urllib.parse import urlencode, quote_plus
5+
6+
7+
class PusherChatKitClient(object):
8+
9+
def __init__(self, backend, instance_locator):
10+
self.http = backend()
11+
self.instance_locator = instance_locator.split(':')
12+
self.scheme = 'https'
13+
self.host = self.instance_locator[1] + '.pusherplatform.io'
14+
self.instance_id = self.instance_locator[2]
15+
self.services = {
16+
'api': {
17+
'service_name': 'chatkit',
18+
'service_version': 'v2'
19+
},
20+
'authorizer': {
21+
'service_name': 'chatkit_authorizer',
22+
'service_version': 'v2'
23+
},
24+
'cursors': {
25+
'service_name': 'chatkit_cursors',
26+
'service_version': 'v2'
27+
}
28+
}
29+
30+
def build_endpoint(self, service, api_endpoint, query):
31+
service_path_fragment = self.services[service]['service_name'] + '/' + self.services[service]['service_version']
32+
full_path = '{}://{}/services/{}/{}{}'.format(
33+
self.scheme,
34+
self.host,
35+
service_path_fragment,
36+
self.instance_id,
37+
api_endpoint
38+
)
39+
query = '?' + urlencode(query, quote_via=quote_plus) if query else ""
40+
41+
return full_path + query
42+
43+
def get(self, service, endpoint, query=None, **kwargs):
44+
return self.http.process_request(
45+
'GET',
46+
self.build_endpoint(service, endpoint, query),
47+
kwargs.get('body', None),
48+
kwargs.get('token', None),
49+
)
50+
51+
def put(self, service, endpoint, query=None, **kwargs):
52+
return self.http.process_request(
53+
'PUT',
54+
self.build_endpoint(service, endpoint, query),
55+
kwargs.get('body', None),
56+
kwargs.get('token', None),
57+
)
58+
59+
def post(self, service, endpoint, query=None, **kwargs):
60+
return self.http.process_request(
61+
'POST',
62+
self.build_endpoint(service, endpoint, query),
63+
kwargs.get('body', None),
64+
kwargs.get('token', None),
65+
)
66+
67+
def delete(self, service, endpoint, query=None, **kwargs):
68+
return self.http.process_request(
69+
'DELETE',
70+
self.build_endpoint(service, endpoint, query),
71+
kwargs.get('body', None),
72+
kwargs.get('token', None),
73+
)
74+
75+
76+
def process_response(status, body):
77+
if status >= 200 and status <= 299:
78+
return json.loads(body)
79+
80+
elif status == 400:
81+
raise PusherBadRequest(body)
82+
83+
elif status == 401:
84+
raise PusherBadAuth(body)
85+
86+
elif status == 403:
87+
raise PusherForbidden(body)
88+
89+
else:
90+
raise PusherBadStatus("%s: %s" % (status, body))

pusher_chatkit/constants.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
GLOBAL_SCOPE = 'global'
2+
ROOM_SCOPE = 'room'

pusher_chatkit/exceptions.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
class PusherBadRequest(Exception):
2+
pass
3+
4+
5+
class PusherBadAuth(Exception):
6+
pass
7+
8+
9+
class PusherForbidden(Exception):
10+
pass
11+
12+
13+
class PusherBadStatus(Exception):
14+
pass

0 commit comments

Comments
 (0)