integrate webserver into cli
All checks were successful
build / test (pull_request) Successful in 19s

This commit is contained in:
Jörg Thalheim 2023-08-23 17:17:34 +02:00
parent 79c61f61c7
commit d60548dfc4
4 changed files with 93 additions and 4 deletions

View File

@ -3,9 +3,9 @@ import sys
from types import ModuleType
from typing import Optional
from . import admin, secrets, update
from . import admin, secrets, update, webui
# from . import admin, config, secrets, update
# from . import admin, config, secrets, update, webui
from .errors import ClanError
from .ssh import cli as ssh_cli
@ -39,6 +39,9 @@ def main() -> None:
)
update.register_parser(parser_update)
parser_webui = subparsers.add_parser("webui", help="start webui")
webui.register_parser(parser_webui)
if argcomplete:
argcomplete.autocomplete(parser)

View File

@ -0,0 +1,39 @@
import argparse
from typing import Callable, NoReturn, Optional
start_server: Optional[Callable] = None
ServerImportError: Optional[ImportError] = None
try:
from .server import start_server
except ImportError as e:
ServerImportError = e
def fastapi_is_not_installed(_: argparse.Namespace) -> NoReturn:
assert ServerImportError is not None
print(
f"Dependencies for the webserver is not installed. The webui command has been disabled ({ServerImportError})"
)
exit(1)
def register_parser(parser: argparse.ArgumentParser) -> None:
parser.add_argument("--port", type=int, default=2979, help="Port to listen on")
parser.add_argument("--host", type=str, default="::1", help="Host to listen on")
parser.add_argument(
"--no-open", action="store_true", help="Don't open the browser", default=False
)
parser.add_argument(
"--reload", action="store_true", help="Don't reload on changes", default=False
)
parser.add_argument(
"--log-level",
type=str,
default="info",
help="Log level",
choices=["critical", "error", "warning", "info", "debug", "trace"],
)
if start_server is None:
parser.set_defaults(func=fastapi_is_not_installed)
else:
parser.set_defaults(func=start_server)

View File

@ -0,0 +1,41 @@
import argparse
import time
import urllib.request
import webbrowser
from threading import Thread
from fastapi import FastAPI
# XXX: can we dynamically load this using nix develop?
from uvicorn import run
app = FastAPI()
@app.get("/health")
async def read_root() -> str:
return "OK"
def defer_open_browser(base_url: str) -> None:
for i in range(5):
try:
urllib.request.urlopen(base_url + "/health")
break
except OSError:
time.sleep(i)
webbrowser.open(base_url)
def start_server(args: argparse.Namespace) -> None:
if not args.no_open:
Thread(
target=defer_open_browser, args=(f"http://[{args.host}]:{args.port}",)
).start()
run(
"clan_cli.webui.server:app",
host=args.host,
port=args.port,
log_level=args.log_level,
reload=args.reload,
)

View File

@ -1,5 +1,7 @@
{ age
, argcomplete
, fastapi
, uvicorn
, bubblewrap
, installShellFiles
, nix
@ -22,7 +24,11 @@ let
# evaluating the flake .#
CLAN_OPTIONS_FILE = ./clan_cli/config/jsonschema/options.json;
dependencies = [ argcomplete ];
dependencies = [
argcomplete # optional dependency: if not enabled, shell completion will not work
fastapi
uvicorn # optional dependencies: if not enabled, webui subcommand will not work
];
testDependencies = [
pytest
@ -73,7 +79,7 @@ python3.pkgs.buildPythonPackage {
wheel
] ++ testDependencies;
passthru.testDependencies = testDependencies;
passthru.testDependencies = dependencies ++ testDependencies;
makeWrapperArgs = [
"--set CLAN_FLAKE ${self}"