Start: Fix startup with new argparser
Since the full argparser requires pydantic, gate it until all dependencies are installed. Also if the venv is deleted, assume that start_options.json is invalid as well. Signed-off-by: kingbri <bdashore3@proton.me>
This commit is contained in:
parent
16abaf0922
commit
3c8384ee71
4 changed files with 79 additions and 22 deletions
|
|
@ -1,10 +1,11 @@
|
|||
"""Argparser for overriding config values"""
|
||||
|
||||
import argparse
|
||||
from typing import Optional
|
||||
from pydantic import BaseModel
|
||||
|
||||
from common.config_models import TabbyConfigModel
|
||||
from common.utils import is_list_type, unwrap_optional_type
|
||||
from common.utils import is_list_type, unwrap, unwrap_optional_type
|
||||
|
||||
|
||||
def add_field_to_group(group, field_name, field_type, field) -> None:
|
||||
|
|
@ -23,12 +24,18 @@ def add_field_to_group(group, field_name, field_type, field) -> None:
|
|||
group.add_argument(f"--{field_name}", **kwargs)
|
||||
|
||||
|
||||
def init_argparser() -> argparse.ArgumentParser:
|
||||
def init_argparser(
|
||||
existing_parser: Optional[argparse.ArgumentParser] = None,
|
||||
) -> argparse.ArgumentParser:
|
||||
"""
|
||||
Initializes an argparse parser based on a Pydantic config schema.
|
||||
|
||||
If an existing provider is given, use that.
|
||||
"""
|
||||
|
||||
parser = argparse.ArgumentParser(description="TabbyAPI server")
|
||||
parser = unwrap(
|
||||
existing_parser, argparse.ArgumentParser(description="TabbyAPI server")
|
||||
)
|
||||
|
||||
# Loop through each top-level field in the config
|
||||
for field_name, field_info in TabbyConfigModel.model_fields.items():
|
||||
|
|
|
|||
|
|
@ -12,6 +12,11 @@ if exist "%CONDA_PREFIX%" (
|
|||
if not exist "venv\" (
|
||||
echo Venv doesn't exist! Creating one for you.
|
||||
python -m venv venv
|
||||
|
||||
if exist "start_options.json" (
|
||||
echo Removing old start_options.json
|
||||
del start_options.json
|
||||
)
|
||||
)
|
||||
|
||||
call .\venv\Scripts\activate.bat
|
||||
|
|
|
|||
76
start.py
76
start.py
|
|
@ -10,8 +10,6 @@ import sys
|
|||
from shutil import copyfile
|
||||
import traceback
|
||||
|
||||
from common.args import convert_args_to_dict, init_argparser
|
||||
|
||||
|
||||
start_options = {}
|
||||
|
||||
|
|
@ -93,6 +91,20 @@ def get_install_features(lib_name: str = None):
|
|||
return install_features
|
||||
|
||||
|
||||
def create_argparser():
|
||||
try:
|
||||
from common.args import init_argparser
|
||||
|
||||
return init_argparser()
|
||||
except ModuleNotFoundError:
|
||||
print(
|
||||
"Pydantic not found. Showing an abridged help menu.\n"
|
||||
"Run this script once to install dependencies.\n"
|
||||
)
|
||||
|
||||
return argparse.ArgumentParser()
|
||||
|
||||
|
||||
def add_start_args(parser: argparse.ArgumentParser):
|
||||
"""Add start script args to the provided parser"""
|
||||
start_group = parser.add_argument_group("start")
|
||||
|
|
@ -151,9 +163,25 @@ if __name__ == "__main__":
|
|||
subprocess.run(["pip", "-V"])
|
||||
|
||||
# Create an argparser and add extra startup script args
|
||||
# Try creating a full argparser if pydantic is installed
|
||||
# Otherwise, create an abridged one solely for startup
|
||||
try:
|
||||
from common.args import init_argparser
|
||||
|
||||
parser = init_argparser()
|
||||
has_full_parser = True
|
||||
except ModuleNotFoundError:
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Abridged TabbyAPI start script parser.",
|
||||
epilog=(
|
||||
"Some dependencies were not found to display the full argparser. "
|
||||
"Run the script once to install/update them."
|
||||
),
|
||||
)
|
||||
has_full_parser = False
|
||||
|
||||
add_start_args(parser)
|
||||
args = parser.parse_args()
|
||||
args, _ = parser.parse_known_args()
|
||||
script_ext = "bat" if platform.system() == "Windows" else "sh"
|
||||
|
||||
start_options_path = pathlib.Path("start_options.json")
|
||||
|
|
@ -176,6 +204,7 @@ if __name__ == "__main__":
|
|||
# Set variables that rely on start options
|
||||
first_run = not start_options.get("first_run_done")
|
||||
|
||||
# Set gpu_lib for dependency install
|
||||
if args.gpu_lib:
|
||||
print("Overriding GPU lib name from args.")
|
||||
gpu_lib = args.gpu_lib
|
||||
|
|
@ -184,25 +213,13 @@ if __name__ == "__main__":
|
|||
else:
|
||||
gpu_lib = None
|
||||
|
||||
# Create a config if it doesn't exist
|
||||
# This is not necessary to run TabbyAPI, but is new user proof
|
||||
config_path = (
|
||||
pathlib.Path(args.config) if args.config else pathlib.Path("config.yml")
|
||||
)
|
||||
if not config_path.exists():
|
||||
sample_config_path = pathlib.Path("config_sample.yml")
|
||||
copyfile(sample_config_path, config_path)
|
||||
|
||||
print(
|
||||
"A config.yml wasn't found.\n"
|
||||
f"Created one at {str(config_path.resolve())}"
|
||||
)
|
||||
|
||||
# Pull from GitHub
|
||||
if args.update_repository:
|
||||
print("Pulling latest changes from Github.")
|
||||
pull_command = "git pull"
|
||||
subprocess.run(pull_command.split(" "))
|
||||
|
||||
# Install/update dependencies
|
||||
if first_run or args.update_deps:
|
||||
install_command = ["pip", "install", "-U"]
|
||||
|
||||
|
|
@ -231,6 +248,7 @@ if __name__ == "__main__":
|
|||
"inside the `update_scripts` folder."
|
||||
)
|
||||
|
||||
# First run options
|
||||
if first_run:
|
||||
start_options["first_run_done"] = True
|
||||
|
||||
|
|
@ -245,12 +263,34 @@ if __name__ == "__main__":
|
|||
"will reinstall TabbyAPI as a first-time user."
|
||||
)
|
||||
|
||||
# Import entrypoint after installing all requirements
|
||||
# Expand the parser if it's not fully created
|
||||
if not has_full_parser:
|
||||
from common.args import init_argparser
|
||||
|
||||
parser = init_argparser(parser)
|
||||
args = parser.parse_args()
|
||||
|
||||
# Assume all dependencies are installed from here
|
||||
try:
|
||||
from common.args import convert_args_to_dict
|
||||
from main import entrypoint
|
||||
|
||||
converted_args = convert_args_to_dict(args, parser)
|
||||
|
||||
# Create a config if it doesn't exist
|
||||
# This is not necessary to run TabbyAPI, but is new user proof
|
||||
config_path = (
|
||||
pathlib.Path(args.config) if args.config else pathlib.Path("config.yml")
|
||||
)
|
||||
if not config_path.exists():
|
||||
sample_config_path = pathlib.Path("config_sample.yml")
|
||||
copyfile(sample_config_path, config_path)
|
||||
|
||||
print(
|
||||
"A config.yml wasn't found.\n"
|
||||
f"Created one at {str(config_path.resolve())}"
|
||||
)
|
||||
|
||||
print("Starting TabbyAPI...")
|
||||
entrypoint(converted_args)
|
||||
except (ModuleNotFoundError, ImportError):
|
||||
|
|
|
|||
5
start.sh
5
start.sh
|
|
@ -8,6 +8,11 @@ else
|
|||
if [ ! -d "venv" ]; then
|
||||
echo "Venv doesn't exist! Creating one for you."
|
||||
python3 -m venv venv
|
||||
|
||||
if [ -f "start_options.json" ]; then
|
||||
echo "Removing old start_options.json"
|
||||
rm -rf start_options.json
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "Activating venv"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue