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.

paw

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.

dalmp


comments powered by Disqus