161 lines
4.8 KiB
Python
161 lines
4.8 KiB
Python
import pathlib
|
|
import subprocess
|
|
import click
|
|
from os import environ
|
|
from flask import current_app
|
|
from flask.cli import FlaskGroup, run_command, with_appcontext
|
|
import pkg_resources
|
|
from flaschengeist.app import create_app
|
|
from flaschengeist.config import configure_logger
|
|
|
|
|
|
def get_version(ctx, param, value):
|
|
if not value or ctx.resilient_parsing:
|
|
return
|
|
|
|
import platform
|
|
from werkzeug import __version__ as werkzeug_version
|
|
from flask import __version__ as flask_version
|
|
from flaschengeist import __version__
|
|
|
|
click.echo(
|
|
f"Python {platform.python_version()}\n"
|
|
f"Flask {flask_version}\n"
|
|
f"Werkzeug {werkzeug_version}\n"
|
|
f"Flaschengeist {__version__}",
|
|
color=ctx.color,
|
|
)
|
|
ctx.exit()
|
|
|
|
|
|
@with_appcontext
|
|
def verbosity(ctx, param, value):
|
|
"""Toggle verbosity between WARNING <-> DEBUG"""
|
|
if not value or ctx.resilient_parsing:
|
|
return
|
|
configure_logger(cli=30 - max(0, min(value * 10, 20)))
|
|
|
|
|
|
@click.group(
|
|
cls=FlaskGroup,
|
|
add_version_option=False,
|
|
add_default_commands=False,
|
|
create_app=lambda: create_app(cli=30),
|
|
)
|
|
@click.option(
|
|
"--version",
|
|
help="Show the flask version",
|
|
expose_value=False,
|
|
callback=get_version,
|
|
is_flag=True,
|
|
is_eager=True,
|
|
)
|
|
@click.option(
|
|
"--verbose",
|
|
"-v",
|
|
help="Increase logging level",
|
|
callback=verbosity,
|
|
count=True,
|
|
expose_value=False,
|
|
)
|
|
def cli():
|
|
"""Management script for the Flaschengeist application."""
|
|
pass
|
|
|
|
|
|
@cli.command()
|
|
@with_appcontext
|
|
def install():
|
|
"""Install and initialize enabled plugins.
|
|
|
|
Most plugins need to install custom tables into the database
|
|
running this command will lookup all enabled plugins and run
|
|
their database initalization routines.
|
|
"""
|
|
from flaschengeist.app import install_all
|
|
|
|
install_all()
|
|
|
|
|
|
@cli.command()
|
|
@click.option("--output", "-o", help="Output file, default is stdout", type=click.Path())
|
|
@click.option("--namespace", "-n", help="TS namespace for the interfaces", type=str, show_default=True)
|
|
@click.option("--plugin", "-p", help="Also export types for a plugin (even if disabled)", multiple=True, type=str)
|
|
@click.option("--no-core", help="Skip models / types from flaschengeist core", is_flag=True)
|
|
def export(namespace, output, no_core, plugin):
|
|
from flaschengeist import models
|
|
from flaschengeist import logger
|
|
from .InterfaceGenerator import InterfaceGenerator
|
|
|
|
gen = InterfaceGenerator(namespace, output, logger)
|
|
if not no_core:
|
|
gen.run(models)
|
|
if plugin:
|
|
for entry_point in pkg_resources.iter_entry_points("flaschengeist.plugins"):
|
|
if len(plugin) == 0 or entry_point.name in plugin:
|
|
plg = entry_point.load()
|
|
if hasattr(plg, "models") and plg.models is not None:
|
|
gen.run(plg.models)
|
|
gen.write()
|
|
|
|
|
|
@cli.command()
|
|
@click.option("--host", help="set hostname to listen on", default="127.0.0.1", show_default=True)
|
|
@click.option("--port", help="set port to listen on", type=int, default=5000, show_default=True)
|
|
@click.option("--debug", help="run in debug mode", is_flag=True)
|
|
@with_appcontext
|
|
@click.pass_context
|
|
def run(ctx, host, port, debug):
|
|
"""Run Flaschengeist using a development server."""
|
|
|
|
class PrefixMiddleware(object):
|
|
def __init__(self, app, prefix=""):
|
|
self.app = app
|
|
self.prefix = prefix
|
|
|
|
def __call__(self, environ, start_response):
|
|
|
|
if environ["PATH_INFO"].startswith(self.prefix):
|
|
environ["PATH_INFO"] = environ["PATH_INFO"][len(self.prefix) :]
|
|
environ["SCRIPT_NAME"] = self.prefix
|
|
return self.app(environ, start_response)
|
|
else:
|
|
start_response("404", [("Content-Type", "text/plain")])
|
|
return ["This url does not belong to the app.".encode()]
|
|
|
|
from flaschengeist.config import config
|
|
|
|
# re configure logger, as we are no logger in CLI mode
|
|
configure_logger()
|
|
current_app.wsgi_app = PrefixMiddleware(current_app.wsgi_app, prefix=config["FLASCHENGEIST"].get("root", ""))
|
|
if debug:
|
|
environ["FLASK_DEBUG"] = "1"
|
|
environ["FLASK_ENV"] = "development"
|
|
|
|
ctx.invoke(run_command, host=host, port=port, debugger=debug)
|
|
|
|
|
|
@cli.command()
|
|
@click.option(
|
|
"--output",
|
|
"-o",
|
|
help="Documentation output path",
|
|
default="./docs",
|
|
type=click.Path(file_okay=False, path_type=pathlib.Path),
|
|
)
|
|
def docs(output: pathlib.Path):
|
|
"""Generate and export API documentation using pdoc3"""
|
|
output.mkdir(parents=True, exist_ok=True)
|
|
command = [
|
|
"python",
|
|
"-m",
|
|
"pdoc",
|
|
"--skip-errors",
|
|
"--html",
|
|
"--output-dir",
|
|
str(output),
|
|
"flaschengeist",
|
|
]
|
|
click.echo(f"Running command: {command}")
|
|
subprocess.check_call(command)
|