diff --git a/Makefile b/Makefile index 12ec073..19e61b1 100644 --- a/Makefile +++ b/Makefile @@ -39,6 +39,7 @@ help: @echo " db_revision Generate database alembic version revision with model." @echo " db_sync Sync database from alembic version revision." @echo " swagger Generate swagger json file." + @echo " genconfig Generate sample config file." @echo " future_check Find python files without 'type annotations'.(Alpha)" @echo @@ -131,6 +132,11 @@ swagger: poetry run swagger-generator -o $(ROOT_DIR)/docs/api/swagger.json +.PHONY: genconfig +genconfig: + poetry run config-sample-generator -o $(ROOT_DIR)/etc/skyline-apiserver.yaml.sample + + # Find python files without "type annotations" future_check: @find src ! -size 0 -type f -name *.py -exec grep -L 'from __future__ import annotations' {} \; diff --git a/pyproject.toml b/pyproject.toml index 79b0ca7..3a5dcae 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -59,6 +59,7 @@ skyline-log = {path = "./libs/skyline-log", develop = true} [tool.poetry.scripts] swagger-generator = 'skyline_apiserver.cmd.generate_swagger:main' +config-sample-generator = 'skyline_apiserver.cmd.generate_sample_config:main' [tool.black] line-length = 98 diff --git a/src/skyline_apiserver/cmd/generate_sample_config.py b/src/skyline_apiserver/cmd/generate_sample_config.py new file mode 100644 index 0000000..9c4d37c --- /dev/null +++ b/src/skyline_apiserver/cmd/generate_sample_config.py @@ -0,0 +1,52 @@ +# Copyright 2021 99cloud +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import annotations + +import sys + +import click +import yaml + +from skyline_apiserver.config import CONF, configure + + +@click.command(help="Generate skyline-apiserver sample config file.") +@click.option( + "-o", + "--output-file", + "output_file_path", + default="skyline-apiserver.yaml.sample", + help=( + "The path of the output file, this file is used to generate a sample config file " + "for use. (Default value: skyline-apiserver.yaml.sample)" + ), +) +def main(output_file_path: str) -> None: + try: + configure("skyline-apiserver", setup=False) + + result = {} + for group_name, group in CONF.items(): + result[group_name] = {i.name: i.default for i in group.values()} + with open(output_file_path, mode="w") as f: + f.write(yaml.safe_dump(result, allow_unicode=True)) + + except Exception as e: + print(f"Generate skyline-apiserver sample config file failed: {str(e)}") + sys.exit(1) + + +if __name__ == "__main__": + main() diff --git a/src/skyline_apiserver/cmd/generate_swagger.py b/src/skyline_apiserver/cmd/generate_swagger.py index 5e0f22b..5f043ae 100644 --- a/src/skyline_apiserver/cmd/generate_swagger.py +++ b/src/skyline_apiserver/cmd/generate_swagger.py @@ -16,19 +16,10 @@ from __future__ import annotations import json import sys -from logging import StreamHandler -import aiofiles import click -from skyline_log import LOG, setup as log_setup -from skyline_apiserver.config import configure from skyline_apiserver.main import app -from skyline_apiserver.utils.coroutine import sync_run - - -class CommandException(Exception): - EXIT_CODE = 1 @click.command(help="Generate swagger file.") @@ -42,19 +33,15 @@ class CommandException(Exception): "use in the development process. (Default value: swagger.json)" ), ) -@sync_run -async def main(output_file_path: str) -> None: +def main(output_file_path: str) -> None: try: - configure("skyline-apiserver") - log_setup(StreamHandler()) - swagger_dict = app.openapi() - async with aiofiles.open(output_file_path, mode="w") as f: - await f.write(json.dumps(swagger_dict, indent=4)) + with open(output_file_path, mode="w") as f: + f.write(json.dumps(swagger_dict, indent=4)) - except CommandException as e: - LOG.error(e) - sys.exit(e.EXIT_CODE) + except Exception as e: + print(f"Generate swagger file failed: {str(e)}") + sys.exit(1) if __name__ == "__main__": diff --git a/src/skyline_apiserver/config/base.py b/src/skyline_apiserver/config/base.py index 45e2f41..a140c67 100644 --- a/src/skyline_apiserver/config/base.py +++ b/src/skyline_apiserver/config/base.py @@ -83,6 +83,15 @@ class Group: items = ", ".join((f"{opt}=Opt(name='{opt}')" for opt in self._opts)) return f"Group({items})" + def items(self) -> Iterator[Any]: + return self._opts.items() + + def keys(self) -> Iterator[Any]: + return self._opts.keys() + + def values(self) -> Iterator[Any]: + return self._opts.values() + @dataclass(repr=False, frozen=True) class Configuration: @@ -148,5 +157,13 @@ class Configuration: items = ", ".join((f"{group}=Group(name='{group}')" for group in self._groups)) return f"Configuration({items})" + def items(self) -> Iterator[Any]: + return self._groups.items() + + def keys(self) -> Iterator[Any]: + return self._groups.keys() + + def values(self) -> Iterator[Any]: + return self._groups.values() __all__ = ("Opt", "Group", "Configuration")