2016-03-03 11:55:43 -08:00
|
|
|
from webagg.inputrequest import DirectWSGIInputRequest, POSTInputRequest
|
2016-05-10 16:31:44 -07:00
|
|
|
from werkzeug.routing import Map, Rule
|
2016-02-28 14:33:08 -08:00
|
|
|
|
2016-03-12 22:15:24 -08:00
|
|
|
import requests
|
2016-02-29 12:34:06 -08:00
|
|
|
import traceback
|
|
|
|
import json
|
|
|
|
|
2016-05-10 16:31:44 -07:00
|
|
|
from six.moves.urllib.parse import parse_qsl
|
2016-05-11 11:38:59 -07:00
|
|
|
import six
|
2016-05-10 16:31:44 -07:00
|
|
|
|
2016-03-02 18:13:13 -08:00
|
|
|
JSON_CT = 'application/json; charset=utf-8'
|
|
|
|
|
2016-03-05 16:49:26 -08:00
|
|
|
|
|
|
|
#=============================================================================
|
2016-03-06 23:10:30 -08:00
|
|
|
class ResAggApp(object):
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
|
self.route_dict = {}
|
2016-03-26 22:30:47 -04:00
|
|
|
self.debug = kwargs.get('debug', False)
|
|
|
|
|
2016-05-10 16:31:44 -07:00
|
|
|
self.url_map = Map()
|
|
|
|
|
|
|
|
def list_routes(environ):
|
|
|
|
return {}, self.route_dict, {}
|
2016-03-06 23:10:30 -08:00
|
|
|
|
2016-05-10 16:31:44 -07:00
|
|
|
self.url_map.add(Rule('/', endpoint=list_routes))
|
2016-03-06 23:10:30 -08:00
|
|
|
|
|
|
|
def add_route(self, path, handler):
|
2016-05-10 16:31:44 -07:00
|
|
|
def direct_input_request(environ, mode=''):
|
|
|
|
params = self.get_query_dict(environ)
|
2016-03-06 23:10:30 -08:00
|
|
|
params['mode'] = mode
|
2016-05-10 16:31:44 -07:00
|
|
|
params['_input_req'] = DirectWSGIInputRequest(environ)
|
2016-03-06 23:10:30 -08:00
|
|
|
return handler(params)
|
|
|
|
|
2016-05-10 16:31:44 -07:00
|
|
|
def post_fullrequest(environ, mode=''):
|
|
|
|
params = self.get_query_dict(environ)
|
2016-03-06 23:10:30 -08:00
|
|
|
params['mode'] = mode
|
2016-05-10 16:31:44 -07:00
|
|
|
params['_input_req'] = POSTInputRequest(environ)
|
2016-03-06 23:10:30 -08:00
|
|
|
return handler(params)
|
|
|
|
|
2016-05-10 16:31:44 -07:00
|
|
|
self.url_map.add(Rule(path, endpoint=direct_input_request))
|
|
|
|
self.url_map.add(Rule(path + '/<path:mode>', endpoint=direct_input_request))
|
|
|
|
|
|
|
|
self.url_map.add(Rule(path + '/postreq', endpoint=post_fullrequest))
|
|
|
|
self.url_map.add(Rule(path + '/<path:mode>/postreq', endpoint=post_fullrequest))
|
|
|
|
|
2016-03-06 23:10:30 -08:00
|
|
|
handler_dict = handler.get_supported_modes()
|
2016-05-10 16:31:44 -07:00
|
|
|
|
2016-03-06 23:10:30 -08:00
|
|
|
self.route_dict[path] = handler_dict
|
|
|
|
self.route_dict[path + '/postreq'] = handler_dict
|
|
|
|
|
2016-05-10 16:31:44 -07:00
|
|
|
def get_query_dict(self, environ):
|
|
|
|
query_str = environ.get('QUERY_STRING')
|
|
|
|
if query_str:
|
|
|
|
return dict(parse_qsl(query_str))
|
|
|
|
else:
|
|
|
|
return {}
|
|
|
|
|
|
|
|
def __call__(self, environ, start_response):
|
|
|
|
urls = self.url_map.bind_to_environ(environ)
|
|
|
|
try:
|
|
|
|
endpoint, args = urls.match()
|
|
|
|
except HTTPException as e:
|
|
|
|
return e(environ, start_response)
|
|
|
|
|
|
|
|
try:
|
|
|
|
result = endpoint(environ, **args)
|
|
|
|
|
|
|
|
out_headers, res, errs = result
|
|
|
|
|
2016-05-11 11:38:59 -07:00
|
|
|
if not res:
|
|
|
|
return self.send_error(errs, start_response)
|
2016-05-10 16:31:44 -07:00
|
|
|
|
2016-05-11 11:38:59 -07:00
|
|
|
if isinstance(res, dict):
|
|
|
|
res = self.json_encode(res, out_headers)
|
2016-05-10 16:31:44 -07:00
|
|
|
|
2016-05-11 11:38:59 -07:00
|
|
|
if errs:
|
|
|
|
out_headers['ResErrors'] = json.dumps(errs)
|
2016-05-10 16:31:44 -07:00
|
|
|
|
2016-05-11 11:38:59 -07:00
|
|
|
start_response('200 OK', list(out_headers.items()))
|
|
|
|
return res
|
2016-05-10 16:31:44 -07:00
|
|
|
|
|
|
|
except Exception as e:
|
|
|
|
message = 'Internal Error: ' + str(e)
|
|
|
|
status = 500
|
2016-05-11 11:38:59 -07:00
|
|
|
return self.send_error({}, start_response,
|
2016-05-10 16:31:44 -07:00
|
|
|
message=message,
|
|
|
|
status=status)
|
|
|
|
|
2016-05-11 11:38:59 -07:00
|
|
|
def json_encode(self, res, out_headers):
|
|
|
|
res = json.dumps(res).encode('utf-8')
|
|
|
|
out_headers['Content-Type'] = JSON_CT
|
|
|
|
out_headers['Content-Length'] = str(len(res))
|
|
|
|
return [res]
|
2016-05-10 16:31:44 -07:00
|
|
|
|
2016-05-11 11:38:59 -07:00
|
|
|
def send_error(self, errs, start_response,
|
2016-05-10 16:31:44 -07:00
|
|
|
message='No Resource Found', status=404):
|
|
|
|
last_exc = errs.pop('last_exc', None)
|
|
|
|
if last_exc:
|
|
|
|
if self.debug:
|
|
|
|
traceback.print_exc()
|
2016-03-02 18:13:13 -08:00
|
|
|
|
2016-05-10 16:31:44 -07:00
|
|
|
status = last_exc.status()
|
|
|
|
message = last_exc.msg
|
2016-03-02 18:13:13 -08:00
|
|
|
|
2016-05-10 16:31:44 -07:00
|
|
|
res = {'message': message}
|
|
|
|
if errs:
|
|
|
|
res['errors'] = errs
|
2016-02-28 14:33:08 -08:00
|
|
|
|
2016-05-11 11:38:59 -07:00
|
|
|
out_headers = {}
|
|
|
|
res = self.json_encode(res, out_headers)
|
2016-03-01 14:46:05 -08:00
|
|
|
|
2016-05-11 11:38:59 -07:00
|
|
|
if six.PY3:
|
|
|
|
out_headers['ResErrors'] = res[0].decode('utf-8')
|
|
|
|
else:
|
|
|
|
out_headers['ResErrors'] = res[0]
|
|
|
|
message = message.encode('utf-8')
|
2016-02-28 14:33:08 -08:00
|
|
|
|
2016-05-11 11:38:59 -07:00
|
|
|
message = str(status) + ' ' + message
|
|
|
|
start_response(message, list(out_headers.items()))
|
|
|
|
return res
|