Added export target to starter script. Allows export of typescript interfaces of backend models

This commit is contained in:
Ferdinand Thiessen 2020-10-19 01:42:54 +02:00
parent c629f5abf3
commit 233660d452
1 changed files with 60 additions and 5 deletions

View File

@ -1,11 +1,14 @@
#!/usr/bin/python3
import sys
import inspect
import argparse
import bjoern
import sqlalchemy
from sqlalchemy.orm import RelationshipProperty, ColumnProperty
def install(arguments):
from flaschengeist.app import create_app, install_all
app = create_app()
with app.app_context():
install_all()
@ -13,6 +16,7 @@ def install(arguments):
def run(arguments):
from flaschengeist.app import create_app
app = create_app()
with app.app_context():
if arguments.debug:
@ -21,18 +25,69 @@ def run(arguments):
bjoern.run(app, arguments.host, arguments.port, reuse_port=True)
if __name__ == '__main__':
def export(arguments):
import flaschengeist.system.models as models
known = []
done = []
def orm_type(attr):
if hasattr(attr, 'type'):
tt = attr.type
if isinstance(attr, ColumnProperty):
tt = attr.columns[0].type
elif isinstance(attr, RelationshipProperty):
proto = "{}"
if attr.key.endswith("s"):
proto = "Array<{}>"
return proto.format(attr.mapper.class_.__name__)
else:
raise TypeError("Couldn't inspect type.")
tt = tt.__str__().split("(")[0]
return {"INTEGER": "number",
"VARCHAR": "string",
"DATETIME": "Date"}[tt]
def walker(mod, file):
if inspect.isclass(mod[1]) and mod[1].__module__.startswith(models.__name__) and mod[0] not in done:
mapper = sqlalchemy.inspect(mod[1], False)
if mapper is not None:
file.write("interface {} {{\n".format(mod[0]))
for desc in mapper.attrs:
file.write(" {}: {};\n".format(desc.key, orm_type(desc)))
file.write("}\n")
done.append(mod[0])
elif inspect.ismodule(mod[1]) and mod[1].__name__.startswith(models.__name__) and mod[1].__name__ not in known:
known.append(mod[1].__name__)
for cls in inspect.getmembers(mod[1], lambda x: inspect.isclass(x) or inspect.ismodule(x)):
walker(cls, file)
from flaschengeist.app import create_app
app = create_app()
with app.app_context():
with open(arguments.file, "w") as file:
walker(("models", models), file)
if __name__ == "__main__":
# create the top-level parser
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(help='sub-command help', dest="sub_command")
subparsers = parser.add_subparsers(help="sub-command help", dest="sub_command")
subparsers.required = True
parser_run = subparsers.add_parser('run', help='run flaschengeist')
parser_run = subparsers.add_parser("run", help="run flaschengeist")
parser_run.set_defaults(func=run)
parser_run.add_argument("--host", help="set hostname to listen on", default="127.0.0.1")
parser_run.add_argument("--port", help="set port to listen on", type=int, default=5000)
parser_run.add_argument("--debug", help="run in debug mode", action="store_true")
parser_install = subparsers.add_parser('install', help='run database setup for flaschengeist and all installed plugins')
parser_install = subparsers.add_parser(
"install", help="run database setup for flaschengeist and all installed plugins"
)
parser_install.set_defaults(func=install)
parser_export = subparsers.add_parser("export", help="export models to typescript interfaces")
parser_export.set_defaults(func=export)
parser_export.add_argument("--file", help="Filename where to save", default="flaschengeist.d.ts")
args = parser.parse_args()
args.func(args)