Source code for runtimepy.net.server.app

"""
A module implementing application methods for this package's server interface.
"""

# built-in
from contextlib import suppress
from importlib import import_module as _import_module
from typing import Any

# third-party
from vcorelib.names import import_str_and_item

# internal
from runtimepy.net.arbiter.info import AppInfo
from runtimepy.net.server import RuntimepyServerConnection
from runtimepy.net.server.app.create import (
    config_param,
    create_app,
    create_cacheable_app,
)
from runtimepy.net.server.app.landing_page import landing_page
from runtimepy.subprocess import spawn_exec


[docs] async def launch_browser(app: AppInfo) -> None: """ Attempts to launch browser windows/tabs if any 'http_server' server ports are configured. """ # Launch browser based on config option. for prefix in ["http", "https"]: if config_param(app, f"xdg_open_{prefix}", False): port: Any for port in app.config["root"]["ports"]: # type: ignore if f"{prefix}_server" in port["name"]: # URI parameters. hostname = config_param(app, "xdg_host", "localhost") # Assemble URI. uri = f"{prefix}://{hostname}:{port['port']}/" # Add a fragment if one was specified. fragment = config_param(app, "xdg_fragment", "") if fragment: uri += "#" + fragment with suppress(FileNotFoundError): await app.stack.enter_async_context( spawn_exec("xdg-open", uri) )
# Could add an interface for adding multiple applications. APPS = {"landing_page": landing_page}
[docs] async def setup(app: AppInfo) -> int: """Perform server application setup steps.""" # Set default application. module, method = import_str_and_item( config_param( app, "html_method", "runtimepy.net.server.app.env.channel_environments", ) ) RuntimepyServerConnection.metadata.update(app.config_param("html", {})) # Default application (environment tabs). html_app = create_app(app, getattr(_import_module(module), method)) target: str for target in app.config_param("http_app_paths", []): assert target not in RuntimepyServerConnection.apps, target RuntimepyServerConnection.apps[target] = html_app # Register redirects. redirects: dict[str, str] = app.config_param("http_redirects", {}) for key, val in redirects.items(): RuntimepyServerConnection.add_redirect_path(val, key) # Register custom applications. for key, app_method in APPS.items(): app_cfg: dict[str, Any] = app.config_param(key, {}) paths = app_cfg.get("paths", []) if paths: # Only create a handler if paths are configured to serve the app. created = create_cacheable_app(app, app_method) for path in paths: RuntimepyServerConnection.apps[path] = created await launch_browser(app) return 0