application: support internal API consumption
Track registered endpoints and allow internal APIs calls through their JSON-RPC method names. Signed-off-by: Eric Callahan <arksine.code@gmail.com>
This commit is contained in:
parent
3bd5f7edbd
commit
27c65e0a64
|
@ -17,12 +17,12 @@ import tornado.iostream
|
|||
import tornado.httputil
|
||||
import tornado.web
|
||||
from inspect import isclass
|
||||
from tornado.escape import json_encode, url_unescape, url_escape
|
||||
from tornado.escape import url_unescape, url_escape
|
||||
from tornado.routing import Rule, PathMatches, AnyMatches
|
||||
from tornado.http1connection import HTTP1Connection
|
||||
from tornado.log import access_log
|
||||
from utils import ServerError
|
||||
from websockets import WebRequest, WebsocketManager, WebSocket
|
||||
from websockets import WebRequest, WebsocketManager, WebSocket, APITransport
|
||||
from streaming_form_data import StreamingFormDataParser
|
||||
from streaming_form_data.targets import FileTarget, ValueTarget, SHA256Target
|
||||
|
||||
|
@ -36,6 +36,7 @@ from typing import (
|
|||
Union,
|
||||
Dict,
|
||||
List,
|
||||
Tuple,
|
||||
AsyncGenerator,
|
||||
)
|
||||
if TYPE_CHECKING:
|
||||
|
@ -43,7 +44,6 @@ if TYPE_CHECKING:
|
|||
from moonraker import Server
|
||||
from eventloop import EventLoop
|
||||
from confighelper import ConfigHelper
|
||||
from websockets import APITransport
|
||||
from components.file_manager.file_manager import FileManager
|
||||
import components.authorization
|
||||
MessageDelgate = Optional[tornado.httputil.HTTPMessageDelegate]
|
||||
|
@ -62,7 +62,7 @@ MAX_BODY_SIZE = 50 * 1024 * 1024
|
|||
EXCLUDED_ARGS = ["_", "token", "access_token", "connection_id"]
|
||||
AUTHORIZED_EXTS = [".png"]
|
||||
DEFAULT_KLIPPY_LOG_PATH = "/tmp/klippy.log"
|
||||
ALL_TRANSPORTS = ["http", "websocket", "mqtt"]
|
||||
ALL_TRANSPORTS = ["http", "websocket", "mqtt", "internal"]
|
||||
|
||||
class MutableRouter(tornado.web.ReversibleRuleRouter):
|
||||
def __init__(self, application: MoonrakerApp) -> None:
|
||||
|
@ -123,6 +123,42 @@ class APIDefinition:
|
|||
self.callback = callback
|
||||
self.need_object_parser = need_object_parser
|
||||
|
||||
class InternalTransport(APITransport):
|
||||
def __init__(self, server: Server) -> None:
|
||||
self.server = server
|
||||
self.callbacks: Dict[str, Tuple[str, str, APICallback]] = {}
|
||||
|
||||
def register_api_handler(self, api_def: APIDefinition) -> None:
|
||||
ep = api_def.endpoint
|
||||
cb = api_def.callback
|
||||
if cb is None:
|
||||
# Request to Klippy
|
||||
method = api_def.jrpc_methods[0]
|
||||
action = ""
|
||||
cb = self.server.make_request
|
||||
self.callbacks[method] = (ep, action, cb)
|
||||
else:
|
||||
for method, action in \
|
||||
zip(api_def.jrpc_methods, api_def.request_methods):
|
||||
self.callbacks[method] = (ep, action, cb)
|
||||
|
||||
def remove_api_handler(self, api_def: APIDefinition) -> None:
|
||||
for method in api_def.jrpc_methods:
|
||||
self.callbacks.pop(method, None)
|
||||
|
||||
async def call_method(self,
|
||||
method_name: str,
|
||||
request_arguments: Dict[str, Any] = {},
|
||||
**kwargs
|
||||
) -> Any:
|
||||
if method_name not in self.callbacks:
|
||||
raise self.server.error(f"No method {method_name} available")
|
||||
ep, action, func = self.callbacks[method_name]
|
||||
# Request arguments can be suppplied either through a dict object
|
||||
# or via keyword arugments
|
||||
args = request_arguments or kwargs
|
||||
return await func(WebRequest(ep, args, action))
|
||||
|
||||
class MoonrakerApp:
|
||||
def __init__(self, config: ConfigHelper) -> None:
|
||||
self.server = config.get_server()
|
||||
|
@ -141,8 +177,10 @@ class MoonrakerApp:
|
|||
|
||||
# Set Up Websocket and Authorization Managers
|
||||
self.wsm = WebsocketManager(self.server)
|
||||
self.internal_transport = InternalTransport(self.server)
|
||||
self.api_transports: Dict[str, APITransport] = {
|
||||
"websocket": self.wsm
|
||||
"websocket": self.wsm,
|
||||
"internal": self.internal_transport
|
||||
}
|
||||
|
||||
mimetypes.add_type('text/plain', '.log')
|
||||
|
@ -230,6 +268,9 @@ class MoonrakerApp:
|
|||
def get_websocket_manager(self) -> WebsocketManager:
|
||||
return self.wsm
|
||||
|
||||
def get_internal_transport(self) -> InternalTransport:
|
||||
return self.internal_transport
|
||||
|
||||
async def close(self) -> None:
|
||||
if self.http_server is not None:
|
||||
self.http_server.stop()
|
||||
|
|
Loading…
Reference in New Issue