blob: ecf730a385eaa848bb4c362032edfdde4901f49a [file] [log] [blame]
mblighe8819cd2008-02-15 16:48:40 +00001"""\
2RPC request handler Django. Exposed RPC interface functions should be
3defined in rpc_interface.py.
4"""
5
6__author__ = 'showard@google.com (Steve Howard)'
7
8import django.http
9import traceback, pydoc
10
11from frontend.afe.json_rpc import serviceHandler
12from frontend.afe import rpc_interface, rpc_utils, site_rpc_interface
13
14# since site_rpc_interface is later in the list, its methods will override those
15# of rpc_interface
16RPC_INTERFACE_MODULES = (rpc_interface, site_rpc_interface)
17
18class RpcMethodHolder(object):
19 'Dummy class to hold RPC interface methods as attributes.'
20
21rpc_methods = RpcMethodHolder()
22
23dispatcher = serviceHandler.ServiceHandler(rpc_methods)
24
25# get documentation for rpc_interface we can send back to the user
26html_doc = pydoc.html.document(rpc_interface)
27
28def rpc_handler(request):
29 rpc_utils.set_user(request.afe_user)
30 response = django.http.HttpResponse()
31 if len(request.POST):
32 response.write(dispatcher.handleRequest(request.raw_post_data))
33 else:
34 response.write(html_doc)
35
36 response['Content-length'] = str(len(response.content))
37 return response
38
39
40def allow_keyword_args(f):
41 """\
42 Decorator to allow a function to take keyword args even though the RPC
43 layer doesn't support that. The decorated function assumes its last
44 argument is a dictionary of keyword args and passes them to the original
45 function as keyword args.
46 """
47 def new_fn(*args):
48 assert args
49 keyword_args = args[-1]
50 args = args[:-1]
51 return f(*args, **keyword_args)
52 new_fn.func_name = f.func_name
53 return new_fn
54
55# decorate all functions in rpc_interface to take keyword args
56function_type = type(rpc_handler) # could be any function
57for module in RPC_INTERFACE_MODULES:
58 for name in dir(module):
59 thing = getattr(module, name)
60 if type(thing) is function_type:
61 decorated_function = allow_keyword_args(thing)
62 setattr(rpc_methods, name, decorated_function)