app: allow endpoints to define Content Type

Signed-off-by:  Eric Callahan <arksine.code@gmail.com>
This commit is contained in:
Eric Callahan 2023-06-22 16:30:06 -04:00
parent 95d5f045db
commit a55818bb1a
No known key found for this signature in database
GPG Key ID: 5A1EB336DFB4C71B
1 changed files with 31 additions and 27 deletions

View File

@ -298,10 +298,9 @@ class MoonrakerApp:
await self.secure_server.close_all_connections() await self.secure_server.close_all_connections()
await self.wsm.close() await self.wsm.close()
def register_api_transport(self, def register_api_transport(
name: str, self, name: str, transport: APITransport
transport: APITransport ) -> Dict[str, APIDefinition]:
) -> Dict[str, APIDefinition]:
self.api_transports[name] = transport self.api_transports[name] = transport
return self.api_cache return self.api_cache
@ -323,13 +322,15 @@ class MoonrakerApp:
for name, transport in self.api_transports.items(): for name, transport in self.api_transports.items():
transport.register_api_handler(api_def) transport.register_api_handler(api_def)
def register_local_handler(self, def register_local_handler(
uri: str, self,
request_methods: List[str], uri: str,
callback: APICallback, request_methods: List[str],
transports: List[str] = ALL_TRANSPORTS, callback: APICallback,
wrap_result: bool = True transports: List[str] = ALL_TRANSPORTS,
) -> None: wrap_result: bool = True,
content_type: Optional[str] = None
) -> None:
if uri in self.registered_base_handlers: if uri in self.registered_base_handlers:
return return
api_def = self._create_api_definition( api_def = self._create_api_definition(
@ -343,17 +344,16 @@ class MoonrakerApp:
params['callback'] = callback params['callback'] = callback
params['wrap_result'] = wrap_result params['wrap_result'] = wrap_result
params['is_remote'] = False params['is_remote'] = False
params['content_type'] = content_type
self.mutable_router.add_handler(uri, DynamicRequestHandler, params) self.mutable_router.add_handler(uri, DynamicRequestHandler, params)
self.registered_base_handlers.append(uri) self.registered_base_handlers.append(uri)
for name, transport in self.api_transports.items(): for name, transport in self.api_transports.items():
if name in transports: if name in transports:
transport.register_api_handler(api_def) transport.register_api_handler(api_def)
def register_static_file_handler(self, def register_static_file_handler(
pattern: str, self, pattern: str, file_path: str, force: bool = False
file_path: str, ) -> None:
force: bool = False
) -> None:
if pattern[0] != "/": if pattern[0] != "/":
pattern = "/server/files/" + pattern pattern = "/server/files/" + pattern
if os.path.isfile(file_path) or force: if os.path.isfile(file_path) or force:
@ -369,10 +369,9 @@ class MoonrakerApp:
params = {'path': file_path} params = {'path': file_path}
self.mutable_router.add_handler(pattern, FileRequestHandler, params) self.mutable_router.add_handler(pattern, FileRequestHandler, params)
def register_upload_handler(self, def register_upload_handler(
pattern: str, self, pattern: str, location_prefix: Optional[str] = None
location_prefix: Optional[str] = None ) -> None:
) -> None:
params: Dict[str, Any] = {'max_upload_size': self.max_upload_size} params: Dict[str, Any] = {'max_upload_size': self.max_upload_size}
if location_prefix is not None: if location_prefix is not None:
params['location_prefix'] = location_prefix params['location_prefix'] = location_prefix
@ -403,12 +402,13 @@ class MoonrakerApp:
for name, transport in self.api_transports.items(): for name, transport in self.api_transports.items():
transport.remove_api_handler(api_def) transport.remove_api_handler(api_def)
def _create_api_definition(self, def _create_api_definition(
endpoint: str, self,
request_methods: List[str] = [], endpoint: str,
callback: Optional[APICallback] = None, request_methods: List[str] = [],
transports: List[str] = ALL_TRANSPORTS callback: Optional[APICallback] = None,
) -> APIDefinition: transports: List[str] = ALL_TRANSPORTS
) -> APIDefinition:
is_remote = callback is None is_remote = callback is None
if endpoint in self.api_cache: if endpoint in self.api_cache:
return self.api_cache[endpoint] return self.api_cache[endpoint]
@ -565,7 +565,8 @@ class DynamicRequestHandler(AuthorizedRequestHandler):
methods: List[str] = [], methods: List[str] = [],
need_object_parser: bool = False, need_object_parser: bool = False,
is_remote: bool = True, is_remote: bool = True,
wrap_result: bool = True wrap_result: bool = True,
content_type: Optional[str] = None
) -> None: ) -> None:
super(DynamicRequestHandler, self).initialize() super(DynamicRequestHandler, self).initialize()
self.callback = callback self.callback = callback
@ -575,6 +576,7 @@ class DynamicRequestHandler(AuthorizedRequestHandler):
else self._do_local_request else self._do_local_request
self._parse_query = self._object_parser if need_object_parser \ self._parse_query = self._object_parser if need_object_parser \
else self._default_parser else self._default_parser
self.content_type = content_type
# Converts query string values with type hints # Converts query string values with type hints
def _convert_type(self, value: str, hint: str) -> Any: def _convert_type(self, value: str, hint: str) -> Any:
@ -696,6 +698,8 @@ class DynamicRequestHandler(AuthorizedRequestHandler):
e.status_code, reason=str(e)) from e e.status_code, reason=str(e)) from e
if self.wrap_result: if self.wrap_result:
result = {'result': result} result = {'result': result}
elif self.content_type is not None:
self.set_header("Content-Type", self.content_type)
if result is None: if result is None:
self.set_status(204) self.set_status(204)
self._log_debug(f"HTTP Response::{req}", result) self._log_debug(f"HTTP Response::{req}", result)