-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathclient.py
More file actions
103 lines (85 loc) · 3.27 KB
/
client.py
File metadata and controls
103 lines (85 loc) · 3.27 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
import hashlib
import hmac
import urlparse
import httplib
import mimetypes
from datetime import datetime, timedelta
try:
from cStringIO import StringIO
except ImportError:
from StringIO import StringIO
try:
# Should be (manually) installed if using Python 2.6 or older,
# or if you want the speedup for raw bytestrings provided by
# simplejson.
import simplejson as json
except ImportError:
import json # Works with python 2.7+
BASE_API = 'http://api2.transloadit.com/assemblies'
FILE_BOUNDARY = '----------Python_Transloadit_Client_Boundary_$'
CRLF = '\r\n'
class Client(object):
def __init__(self, key, secret, api=None):
self.key = key
self.secret = secret
if api:
self.api = api
else:
self.api = BASE_API
def _sign_request(self, params):
return hmac.new(self.secret, json.dumps(params),
hashlib.sha1).hexdigest()
def _send_request(self, files, **fields):
parts = urlparse.urlparse(self.api)
content_type, body = self._encode_request(fields, files)
req = httplib.HTTP(parts[1])
req.putrequest('POST', parts[2])
req.putheader('Content-Type', content_type)
req.putheader('Content-Length', str(len(body)))
req.endheaders()
req.send(body)
errcode, errmsg, headers = req.getreply()
output = req.file.read()
try:
return json.loads(output)
except json.JSONDecodeError:
# Workaround for https://github.com/joestump/python-transloadit/issues/5
output = '{' + output.split('{', 1)[-1]
output = output.rsplit('}', 1)[0] + '}'
return json.loads(output)
def _encode_request(self, fields, files):
body = StringIO()
for key, value in fields.iteritems():
body.write('--%s%s' % (FILE_BOUNDARY, CRLF))
body.write('Content-Disposition: form-data; name="%s"%s' % (key, CRLF))
body.write(CRLF)
body.write(value)
body.write(CRLF)
if files:
for key, filename, value in files:
content_type = self._get_content_type(filename)
body.write('--%s%s' % (FILE_BOUNDARY, CRLF))
body.write('Content-Disposition: form-data;' + \
' name="%s"; filename="%s"%s' % (key, filename, CRLF))
body.write('Content-Type: %s%s' % (content_type, CRLF))
body.write(CRLF)
body.write(value)
body.write(CRLF)
body.write('--%s--%s' % (FILE_BOUNDARY, CRLF))
body.write(CRLF)
content_type = 'multipart/form-data; boundary=%s' % FILE_BOUNDARY
return content_type, body.getvalue()
def _get_content_type(self, filename):
return mimetypes.guess_type(filename)[0] or 'application/octet-stream'
def request(self, files=None, **params):
if 'auth' not in params:
params['auth'] = {
'key': self.key,
'expires': (datetime.now() +
timedelta(days=1)).strftime('%Y/%m/%d %H:%M:%S')
}
fields = {
'params': json.dumps(params),
'signature': self._sign_request(params)
}
return self._send_request(files, **fields)