refactor REST API to use a Response object
This commit is contained in:
parent
7fbb5b2823
commit
3a0183eb03
1 changed files with 48 additions and 23 deletions
|
@ -7,6 +7,41 @@
|
||||||
import http.server, json, socket, ssl, threading, uuid, urllib.parse
|
import http.server, json, socket, ssl, threading, uuid, urllib.parse
|
||||||
from src import ModuleManager, utils
|
from src import ModuleManager, utils
|
||||||
|
|
||||||
|
class Response(object):
|
||||||
|
def __init__(self, compact=False):
|
||||||
|
self._compact = compact
|
||||||
|
self._headers = {}
|
||||||
|
self._data = b""
|
||||||
|
self.code = 200
|
||||||
|
self.content_type = "text/plain"
|
||||||
|
def write(self, data):
|
||||||
|
self._data += data
|
||||||
|
def write_text(self, data):
|
||||||
|
self._data += data.encode("utf8")
|
||||||
|
def write_json(self, obj):
|
||||||
|
if self._compact:
|
||||||
|
data = json.dumps(event_response, sort_keys=True,
|
||||||
|
separators=(",", ":"))
|
||||||
|
else:
|
||||||
|
data = json.dumps(event_response, sort_keys=True, indent=4)
|
||||||
|
self._data += data.encode("utf8")
|
||||||
|
|
||||||
|
def set_header(self, key: str, value: str):
|
||||||
|
self._headers[key] = value
|
||||||
|
def get_headers(self):
|
||||||
|
headers = {}
|
||||||
|
has_content_type = False
|
||||||
|
for key, value in self._headers.items():
|
||||||
|
if key.lower() == "content-type":
|
||||||
|
has_content_type = True
|
||||||
|
headers[key] = value
|
||||||
|
if not has_content_type:
|
||||||
|
headers["Content-Type"] = self.content_type
|
||||||
|
return headers
|
||||||
|
|
||||||
|
def get_data(self):
|
||||||
|
return self._data
|
||||||
|
|
||||||
_bot = None
|
_bot = None
|
||||||
_events = None
|
_events = None
|
||||||
_log = None
|
_log = None
|
||||||
|
@ -29,12 +64,12 @@ class Handler(http.server.BaseHTTPRequestHandler):
|
||||||
content_length = int(self.headers.get("content-length", 0))
|
content_length = int(self.headers.get("content-length", 0))
|
||||||
return self.rfile.read(content_length)
|
return self.rfile.read(content_length)
|
||||||
|
|
||||||
def _respond(self, code, headers, data):
|
def _respond(self, response):
|
||||||
self.send_response(code)
|
self.send_response(response.code)
|
||||||
for key, value in headers.items():
|
for key, value in response.get_headers().items():
|
||||||
self.send_header(key, value)
|
self.send_header(key, value)
|
||||||
self.end_headers()
|
self.end_headers()
|
||||||
self.wfile.write(data.encode("utf8"))
|
self.wfile.write(response.get_data())
|
||||||
|
|
||||||
def _get_settings(self, key):
|
def _get_settings(self, key):
|
||||||
key_setting = _bot.get_setting("api-key-%s" % key, {})
|
key_setting = _bot.get_setting("api-key-%s" % key, {})
|
||||||
|
@ -51,9 +86,8 @@ class Handler(http.server.BaseHTTPRequestHandler):
|
||||||
params = self._url_params()
|
params = self._url_params()
|
||||||
data = self._body()
|
data = self._body()
|
||||||
|
|
||||||
response = ""
|
response = Response()
|
||||||
code = 404
|
response.code = 404
|
||||||
content_type = "text/plain"
|
|
||||||
|
|
||||||
hooks = _events.on("api").on(method).on(endpoint).get_hooks()
|
hooks = _events.on("api").on(method).on(endpoint).get_hooks()
|
||||||
if hooks:
|
if hooks:
|
||||||
|
@ -74,29 +108,20 @@ class Handler(http.server.BaseHTTPRequestHandler):
|
||||||
event_response = _bot.trigger(lambda:
|
event_response = _bot.trigger(lambda:
|
||||||
_events.on("api").on(method).on(
|
_events.on("api").on(method).on(
|
||||||
endpoint).call_for_result_unsafe(params=params,
|
endpoint).call_for_result_unsafe(params=params,
|
||||||
path=args, data=data, headers=headers))
|
path=args, data=data, headers=headers,
|
||||||
|
response=response))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
_log.error("failed to call API endpoint \"%s\"",
|
_log.error("failed to call API endpoint \"%s\"",
|
||||||
[path], exc_info=True)
|
[path], exc_info=True)
|
||||||
code = 500
|
response.code = 500
|
||||||
|
|
||||||
if not event_response == None:
|
if not event_response == None:
|
||||||
content_type = "application/json"
|
response.write_json(event_response)
|
||||||
if minify:
|
response.content_type = "application/json"
|
||||||
response = json.dumps(event_response,
|
|
||||||
sort_keys=True, separators=(",", ":"))
|
|
||||||
else:
|
else:
|
||||||
response = json.dumps(event_response,
|
response.code = 401
|
||||||
sort_keys=True, indent=4)
|
|
||||||
code = 200
|
|
||||||
else:
|
|
||||||
code = 401
|
|
||||||
|
|
||||||
headers = {
|
self._respond(response)
|
||||||
"Content-type": content_type
|
|
||||||
}
|
|
||||||
|
|
||||||
self._respond(code, headers, response)
|
|
||||||
|
|
||||||
_log.debug("[HTTP] finishing _handle for %s from %s:%d (%d)",
|
_log.debug("[HTTP] finishing _handle for %s from %s:%d (%d)",
|
||||||
[method, self.client_address[0], self.client_address[1], code])
|
[method, self.client_address[0], self.client_address[1], code])
|
||||||
|
|
Loading…
Reference in a new issue