drop black/ruff from dependency list #160
@ -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)
|
||||
|
||||
|
@ -211,6 +211,10 @@ def set_command(args: argparse.Namespace) -> None:
|
||||
)
|
||||
|
||||
|
||||
def rename_command(args: argparse.Namespace) -> None:
|
||||
pass
|
||||
|
||||
|
||||
def register_secrets_parser(subparser: argparse._SubParsersAction) -> None:
|
||||
parser_list = subparser.add_parser("list", help="list secrets")
|
||||
parser_list.set_defaults(func=list_command)
|
||||
@ -244,6 +248,13 @@ def register_secrets_parser(subparser: argparse._SubParsersAction) -> None:
|
||||
)
|
||||
parser_set.set_defaults(func=set_command)
|
||||
|
||||
parser_delete = subparser.add_parser("remove", help="remove a secret")
|
||||
add_secret_argument(parser_delete)
|
||||
parser_delete.set_defaults(func=remove_command)
|
||||
parser_rename = subparser.add_parser("rename", help="rename a secret")
|
||||
add_secret_argument(parser_rename)
|
||||
parser_rename.add_argument(
|
||||
"new_name", help="the new name of the secret", type=secret_name_type
|
||||
)
|
||||
parser_rename.set_defaults(func=rename_command)
|
||||
|
||||
parser_remove = subparser.add_parser("remove", help="remove a secret")
|
||||
add_secret_argument(parser_remove)
|
||||
parser_remove.set_defaults(func=remove_command)
|
||||
|
39
pkgs/clan-cli/clan_cli/webui/__init__.py
Normal file
39
pkgs/clan-cli/clan_cli/webui/__init__.py
Normal 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)
|
41
pkgs/clan-cli/clan_cli/webui/server.py
Normal file
41
pkgs/clan-cli/clan_cli/webui/server.py
Normal 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,
|
||||
)
|
@ -1,6 +1,7 @@
|
||||
{ age
|
||||
, argcomplete
|
||||
, black
|
||||
, fastapi
|
||||
, uvicorn
|
||||
, bubblewrap
|
||||
, installShellFiles
|
||||
, nix
|
||||
@ -9,7 +10,6 @@
|
||||
, pytest-cov
|
||||
, pytest-subprocess
|
||||
, python3
|
||||
, ruff
|
||||
, runCommand
|
||||
, self
|
||||
, setuptools
|
||||
@ -24,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
|
||||
@ -71,13 +75,11 @@ python3.pkgs.buildPythonPackage {
|
||||
'';
|
||||
|
||||
passthru.devDependencies = [
|
||||
ruff
|
||||
black
|
||||
setuptools
|
||||
wheel
|
||||
] ++ testDependencies;
|
||||
|
||||
passthru.testDependencies = testDependencies;
|
||||
passthru.testDependencies = dependencies ++ testDependencies;
|
||||
|
||||
makeWrapperArgs = [
|
||||
"--set CLAN_FLAKE ${self}"
|
||||
|
Loading…
Reference in New Issue
Block a user