Config: Move config file generation to tabby_config
Keep the models as a separate reference file without any extra functions. Signed-off-by: kingbri <bdashore3@proton.me>
This commit is contained in:
parent
d2d07ed92d
commit
46f9fff210
3 changed files with 80 additions and 84 deletions
|
|
@ -1,8 +1,7 @@
|
|||
import json
|
||||
from loguru import logger
|
||||
|
||||
from common.config_models import generate_config_file
|
||||
from common.tabby_config import config
|
||||
from common.tabby_config import config, generate_config_file
|
||||
from endpoints.server import export_openapi
|
||||
|
||||
|
||||
|
|
@ -18,10 +17,8 @@ def branch_to_actions() -> bool:
|
|||
"Successfully wrote OpenAPI spec to "
|
||||
+ f"{config.actions.openapi_export_path}"
|
||||
)
|
||||
|
||||
elif config.actions.export_config:
|
||||
generate_config_file(filename=config.actions.config_export_path)
|
||||
|
||||
else:
|
||||
# did not branch
|
||||
return False
|
||||
|
|
|
|||
|
|
@ -1,11 +1,7 @@
|
|||
from inspect import getdoc
|
||||
from pathlib import Path
|
||||
from pydantic import BaseModel, ConfigDict, Field, PrivateAttr
|
||||
from pydantic_core import PydanticUndefined
|
||||
from textwrap import dedent
|
||||
from typing import List, Literal, Optional, Union
|
||||
|
||||
from common.utils import unwrap
|
||||
|
||||
CACHE_SIZES = Literal["FP16", "Q8", "Q6", "Q4"]
|
||||
|
||||
|
|
@ -468,78 +464,3 @@ class TabbyConfigModel(BaseModel):
|
|||
)
|
||||
|
||||
model_config = ConfigDict(validate_assignment=True, protected_namespaces=())
|
||||
|
||||
|
||||
# TODO: Possibly switch to ruamel.yaml for a more native implementation
|
||||
def generate_config_file(
|
||||
model: BaseConfigModel = None,
|
||||
filename: str = "config_sample.yml",
|
||||
indentation: int = 2,
|
||||
) -> None:
|
||||
"""Creates a config.yml file from Pydantic models."""
|
||||
|
||||
# Add a preamble
|
||||
yaml = dedent("""
|
||||
# Sample YAML file for configuration.
|
||||
# Comment and uncomment values as needed.
|
||||
# Every value has a default within the application.
|
||||
# This file serves to be a drop in for config.yml
|
||||
|
||||
# Unless specified in the comments, DO NOT put these options in quotes!
|
||||
# You can use https://www.yamllint.com/ if you want to check your YAML formatting.\n
|
||||
""")
|
||||
|
||||
schema = unwrap(model, TabbyConfigModel())
|
||||
|
||||
# TODO: Make the disordered iteration look cleaner
|
||||
iter_once = False
|
||||
for field, field_data in schema.model_fields.items():
|
||||
# Fetch from the existing model class if it's passed
|
||||
# Probably can use this on schema too, but play it safe
|
||||
if model and hasattr(model, field):
|
||||
subfield_model = getattr(model, field)
|
||||
else:
|
||||
subfield_model = field_data.default_factory()
|
||||
|
||||
if not subfield_model._metadata.include_in_config:
|
||||
continue
|
||||
|
||||
# Since the list is out of order with the length
|
||||
# Add newlines from the beginning once one iteration finishes
|
||||
# This is a sanity check for formatting
|
||||
if iter_once:
|
||||
yaml += "\n"
|
||||
else:
|
||||
iter_once = True
|
||||
|
||||
for line in getdoc(subfield_model).splitlines():
|
||||
yaml += f"# {line}\n"
|
||||
|
||||
yaml += f"{field}:\n"
|
||||
|
||||
sub_iter_once = False
|
||||
for subfield, subfield_data in subfield_model.model_fields.items():
|
||||
# Same logic as iter_once
|
||||
if sub_iter_once:
|
||||
yaml += "\n"
|
||||
else:
|
||||
sub_iter_once = True
|
||||
|
||||
# If a value already exists, use it
|
||||
if hasattr(subfield_model, subfield):
|
||||
value = getattr(subfield_model, subfield)
|
||||
elif subfield_data.default_factory:
|
||||
value = subfield_data.default_factory()
|
||||
else:
|
||||
value = subfield_data.default
|
||||
|
||||
value = value if value is not None else ""
|
||||
value = value if value is not PydanticUndefined else ""
|
||||
|
||||
for line in subfield_data.description.splitlines():
|
||||
yaml += f"{' ' * indentation}# {line}\n"
|
||||
|
||||
yaml += f"{' ' * indentation}{subfield}: {value}\n"
|
||||
|
||||
with open(filename, "w") as f:
|
||||
f.write(yaml)
|
||||
|
|
|
|||
|
|
@ -1,11 +1,14 @@
|
|||
import yaml
|
||||
import pathlib
|
||||
from inspect import getdoc
|
||||
from pydantic_core import PydanticUndefined
|
||||
from loguru import logger
|
||||
from textwrap import dedent
|
||||
from typing import Optional
|
||||
from os import getenv
|
||||
|
||||
from common.utils import unwrap, merge_dicts
|
||||
from common.config_models import TabbyConfigModel, generate_config_file
|
||||
from common.config_models import BaseConfigModel, TabbyConfigModel
|
||||
|
||||
|
||||
class TabbyConfig(TabbyConfigModel):
|
||||
|
|
@ -159,3 +162,78 @@ class TabbyConfig(TabbyConfigModel):
|
|||
|
||||
# Create an empty instance of the config class
|
||||
config: TabbyConfig = TabbyConfig()
|
||||
|
||||
|
||||
# TODO: Possibly switch to ruamel.yaml for a more native implementation
|
||||
def generate_config_file(
|
||||
model: BaseConfigModel = None,
|
||||
filename: str = "config_sample.yml",
|
||||
indentation: int = 2,
|
||||
) -> None:
|
||||
"""Creates a config.yml file from Pydantic models."""
|
||||
|
||||
# Add a preamble
|
||||
yaml = dedent("""
|
||||
# Sample YAML file for configuration.
|
||||
# Comment and uncomment values as needed.
|
||||
# Every value has a default within the application.
|
||||
# This file serves to be a drop in for config.yml
|
||||
|
||||
# Unless specified in the comments, DO NOT put these options in quotes!
|
||||
# You can use https://www.yamllint.com/ if you want to check your YAML formatting.\n
|
||||
""")
|
||||
|
||||
schema = unwrap(model, TabbyConfigModel())
|
||||
|
||||
# TODO: Make the disordered iteration look cleaner
|
||||
iter_once = False
|
||||
for field, field_data in schema.model_fields.items():
|
||||
# Fetch from the existing model class if it's passed
|
||||
# Probably can use this on schema too, but play it safe
|
||||
if model and hasattr(model, field):
|
||||
subfield_model = getattr(model, field)
|
||||
else:
|
||||
subfield_model = field_data.default_factory()
|
||||
|
||||
if not subfield_model._metadata.include_in_config:
|
||||
continue
|
||||
|
||||
# Since the list is out of order with the length
|
||||
# Add newlines from the beginning once one iteration finishes
|
||||
# This is a sanity check for formatting
|
||||
if iter_once:
|
||||
yaml += "\n"
|
||||
else:
|
||||
iter_once = True
|
||||
|
||||
for line in getdoc(subfield_model).splitlines():
|
||||
yaml += f"# {line}\n"
|
||||
|
||||
yaml += f"{field}:\n"
|
||||
|
||||
sub_iter_once = False
|
||||
for subfield, subfield_data in subfield_model.model_fields.items():
|
||||
# Same logic as iter_once
|
||||
if sub_iter_once:
|
||||
yaml += "\n"
|
||||
else:
|
||||
sub_iter_once = True
|
||||
|
||||
# If a value already exists, use it
|
||||
if hasattr(subfield_model, subfield):
|
||||
value = getattr(subfield_model, subfield)
|
||||
elif subfield_data.default_factory:
|
||||
value = subfield_data.default_factory()
|
||||
else:
|
||||
value = subfield_data.default
|
||||
|
||||
value = value if value is not None else ""
|
||||
value = value if value is not PydanticUndefined else ""
|
||||
|
||||
for line in subfield_data.description.splitlines():
|
||||
yaml += f"{' ' * indentation}# {line}\n"
|
||||
|
||||
yaml += f"{' ' * indentation}{subfield}: {value}\n"
|
||||
|
||||
with open(filename, "w") as f:
|
||||
f.write(yaml)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue