APIResource classΒΆ
APIResource
is the name of the class that the ZunZun instance
will call to handle the incoming requests.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | from zunzuncito import tools
class APIResource(object):
def dispatch(self, request, response):
request.log.debug(tools.log_json({
'API': request.version,
'URI': request.URI,
'method': request.method,
'vroot': request.vroot
}, True))
# print all the environ
return tools.log_json(request.environ, 4)
|
For example, the following request:
http://127.0.0.1:8080/v0/upload
Is handled by the custom python module zun_upload/zun_upload.py
which contents:
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 | """
upload resource
Upload by chunks
@see http://www.grid.net.ru/nginx/resumable_uploads.en.html
"""
import os
from zunzuncito import tools
class APIResource(object):
@tools.allow_methods('post, put')
def dispatch(self, request, response):
try:
temp_name = request.path[0]
except:
raise tools.HTTPException(400)
"""rfc2616-sec14.html
see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
see http://www.grid.net.ru/nginx/resumable_uploads.en.html
"""
content_range = request.environ.get('HTTP_CONTENT_RANGE', 0)
length = int(request.environ.get('CONTENT_LENGTH', 0))
if content_range:
content_range = content_range.split()[1].split('/')
index, offset = [int(x) for x in content_range[0].split('-')]
total_size = int(content_range[1])
if length:
chunk_size = length
elif offset > index:
chunk_size = (offset - index) + 1
elif total_size:
chunk_size = total_size
else:
raise tools.HTTPException(416)
elif length:
chunk_size = total_size = length
index = 0
offset = 0
else:
raise tools.HTTPException(400)
stream = request.environ['wsgi.input']
body = []
try:
temp_file = os.path.join(
os.path.dirname('/tmp/test_upload/'),
temp_name)
with open(temp_file, 'a+b') as f:
original_file_size = f.tell()
f.seek(index)
f.truncate()
bytes_to_write = chunk_size
while chunk_size > 0:
# buffer size
chunk = stream.read(min(chunk_size, 1 << 13))
if not chunk:
break
f.write(chunk)
chunk_size -= len(chunk)
f.flush()
bytes_written = f.tell() - index
if bytes_written != bytes_to_write:
f.truncate(original_file_size)
f.close()
raise tools.HTTPException(416)
if os.stat(temp_file).st_size == total_size:
response.status = 200
else:
response.status = 201
body.append('%d-%d/%d' % (index, offset, total_size))
request.log.info(tools.log_json({
'index': index,
'offset': offset,
'size': total_size,
'status': response.status,
'temp_file': temp_file
}, True))
return body
except IOError:
raise tools.HTTPException(
500,
title="upload directory [ %s ]doesn't exist" % temp_file,
display=True)
|
Note
All the custom modules must have the APIResource class and the method dispatch in order to work
Many thanks Paw - The ultimate REST client for Mac. for supporting Open Source projects.
A great amount of time has been spent creating, crafting and maintaining this software, please consider donating.
Donating helps ensure continued support, development and availability.
comments powered by Disqus