forked from gvangool/wapi
-
Notifications
You must be signed in to change notification settings - Fork 1
/
bindings.py
115 lines (96 loc) · 4.23 KB
/
bindings.py
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
107
108
109
110
111
112
113
114
115
# -*- coding: utf-8 -*-
# Copyright (c) 2008 Alberto García Hierro <fiam@rm-fr.net>
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
"""Different bindings for Wapi. This version only includes ReST"""
from copy import copy
from django.http import Http404
from django.conf import settings
from django.core.exceptions import ValidationError
from wapi.responses import get_response
from wapi.formatters import UnknownFormat
from wapi.exceptions import ApiError, ApiLoginRequired
from wapi.function import ApiFunction
from wapi.utils import api_iterate, get_instance
class Binding(object):
"""Base class for all Wapi bindings"""
def __init__(self, api):
self.api = get_instance(api)
self.registry = {
'read': {},
'write': {},
}
for func in api_iterate(api):
registered_name = self.mangle_name(func.func_name)
apifunc = ApiFunction(func)
if settings.DEBUG or apifunc.is_read:
self.registry['read'][registered_name] = apifunc
if settings.DEBUG or apifunc.is_write:
self.registry['write'][registered_name] = apifunc
@property
def __name__(self):
return self.__class__.__name__
def mangle_name(self, name):
"""Modifies the function name which gets exposed"""
return name
def get_method(self, read_or_write, method_name):
try:
return self.registry[read_or_write][method_name]
except KeyError:
raise Http404('Method "%s" not found' % method_name)
class RestBinding(Binding):
"""Exposes an API trough ResT"""
PATTERN = '(?P<method_name>.*)\.(?P<format>\w+)'
READ_WRITE_MAPPING = {
'GET': 'read',
'POST': 'write',
}
def __init__(self, api, auth=None):
super(RestBinding, self).__init__(api)
self.auth = get_instance(auth)
def mangle_name(self, name):
return name.replace('__', '/')
def __call__(self, request, method_name, format):
"""Searchs the method, calls it and transforms the response
into a serialized format"""
if self.auth:
response = self.auth.login(request)
if response:
return response
try:
response_cls = get_response(format)
except UnknownFormat:
raise Http404('No registered serializer for format "%s"' % format)
try:
method = self.get_method(self.READ_WRITE_MAPPING[request.method],
method_name)
except KeyError:
raise Http404('Method "%s" not found' % method_name)
try:
if request.method == 'POST':
response = method(request, copy(request.POST))
else:
response = method(request, copy(request.GET))
except ApiLoginRequired:
return self.auth.login_required(request)
except ApiError, e:
from wapi.responses import SingleSerializableResponse
response = SingleSerializableResponse(e)
except ValidationError, e:
from wapi.responses import SingleSerializableResponse
response = SingleSerializableResponse(e)
response.kwargs['request'] = request
return response.transform(response_cls)