File: flask.py

package info (click to toggle)
python-wsme 0.12.1-6
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 616 kB
  • sloc: python: 6,064; makefile: 27; javascript: 8
file content (106 lines) | stat: -rw-r--r-- 3,219 bytes parent folder | download | duplicates (2)
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
104
105
106
import functools
import logging
import sys
import inspect

import flask

import wsme
import wsme.api
import wsme.rest.args
import wsme.rest.json
import wsme.rest.xml
from wsme.utils import is_valid_code

log = logging.getLogger(__name__)


TYPES = {
    'application/json': wsme.rest.json,
    'application/xml': wsme.rest.xml,
    'text/xml': wsme.rest.xml,
}


def get_dataformat():
    if 'Accept' in flask.request.headers:
        for t in TYPES:
            if t in flask.request.headers['Accept']:
                return TYPES[t]

    # Look for the wanted data format in the request.
    req_dataformat = getattr(flask.request, 'response_type', None)
    if req_dataformat in TYPES:
        return TYPES[req_dataformat]

    log.info('Could not determine what format is wanted by the caller, '
             'falling back to JSON')
    return wsme.rest.json


def signature(*args, **kw):
    sig = wsme.signature(*args, **kw)

    def decorator(f):
        args = inspect.getfullargspec(f)[0]
        ismethod = args and args[0] == 'self'
        sig(f)
        funcdef = wsme.api.FunctionDefinition.get(f)
        funcdef.resolve_types(wsme.types.registry)

        @functools.wraps(f)
        def wrapper(*args, **kwargs):
            if ismethod:
                self, args = args[0], args[1:]
            args, kwargs = wsme.rest.args.get_args(
                funcdef, args, kwargs,
                flask.request.args, flask.request.form,
                flask.request.data,
                flask.request.mimetype
            )

            if funcdef.pass_request:
                kwargs[funcdef.pass_request] = flask.request

            dataformat = get_dataformat()

            try:
                if ismethod:
                    args = [self] + list(args)
                result = f(*args, **kwargs)

                # NOTE: Support setting of status_code with default 20
                status_code = funcdef.status_code
                if isinstance(result, wsme.api.Response):
                    status_code = result.status_code
                    result = result.obj

                res = flask.make_response(
                    dataformat.encode_result(
                        result,
                        funcdef.return_type
                    )
                )
                res.mimetype = dataformat.content_type
                res.status_code = status_code
            except Exception:
                try:
                    exception_info = sys.exc_info() or None
                    orig_exception = exception_info[1]
                    orig_code = getattr(orig_exception, 'code', None)
                    data = wsme.api.format_exception(exception_info)
                finally:
                    del exception_info

                res = flask.make_response(dataformat.encode_error(None, data))
                if orig_code and is_valid_code(orig_code):
                    res.status_code = orig_code
                elif data['faultcode'].lower() == 'client':
                    res.status_code = 400
                else:
                    res.status_code = 500
            return res

        wrapper.wsme_func = f
        return wrapper
    return decorator