-
Notifications
You must be signed in to change notification settings - Fork 1
Front Design Notes
"Mint" is the term we coined for "Meta-INTerface", which designates an object that acts as a middle-ware or middle-language to connect two systems, or two sides of a transformation. There can be one or several "mints" making a path between one side and the other. If there are two, often the first is "source oriented", meaning it offers a consistent interface for the source properties and methods of interest, and the second is "target oriented", meaning it offers a consistent interface to enable the creation of the target.
The following shows this pattern for a "python (functions/objects) to app (UI)" path.
The structure of this "parametrized pipeline" is clear. Each step transforms (or adds a layer to) the previous as a function of this previous object, but also of some "specs" that control how this should be done.
Ideally, these specs should be able to control as much as possible, but that doesn't mean we want the user to explicitly specify everything.
Instead, we want to enable he user to specify a convention that contains as much of the specification boilerplate as it can for a given class of problems, and only have to define specifics of particular cases as configs. A mk_specs function will then be responsible for creating specs from this convention and configs.
When put together, these two graphs result in the following:
Note that usually the user specifies a default convention or references the convention to use through an id for sorts.
The user then only needs to specify the objs they want to get an app for, and possibly a few configs if the convention doesn't cover something, or they want to change a specific behavior.
The goal is to get from python functions to a deployed UI that allows the user to interact with these functions, with as little boilerplate as possible (as many defaults as possible), and maximum configurability and separation of concerns.
At a minimum we want a developer to be able to take the app created, and replace the UI, reusing the web service and language layer component. Ideally, things are structured in such a way that (1) the UI replacement can be gradual/incremental and (2) service-to-ui logic can eventually be specified as configuration.
Starting with a set of python functions, we want to automatically generate:
-
web_serviceandopen_api_specsfor this web service -
http2lang, a language binder (e.g. python or js functions calling the services) -
ui, a graphical user interface that will interact with the services -
deploy, a deployment container/process -- that is, something that can then be shared with others so they can try the UI out.

We said py2http to keep it concrete, but this part could be replaced with py2service since we'd like to separate the http concern as well. The need here is primarily to be able to get an equivalent form of the python functionality to run somewhere else, and a secondary want can also be to not expose the python code. We solve both these goals here by creating an http service that forwards calls to python.
The same needs could be solved differently though. For example, CLI are sometimes used as an intermediate interface, or RPC (e.g. protobuf), or various ways to make JS call, or be created from, python (see this) which can be useful for scalability.
from graphviz import Digraph
Digraph(body="""
python_funcs, py2http_configs -> py2http -> web_service, open_api_specs
open_api_specs, http2lang_configs -> http2lang -> lang_layer
lang_layer, service2ui_configs -> service2ui -> ui
ui, ui2deploy_configs -> ui2deploy -> deploy
py2http, http2lang, service2ui, ui2deploy [shape="box"]
python_funcs, py2http_configs, service2ui_configs, ui2deploy_configs [style=filled fillcolor="lightgrey"]
ws_backend, io_trans, url_and_json_schema -> py2http_configs
ws_backend, io_trans, url_and_json_schema [shape="none"]
ws_backend [label="ws_backend\n(e.g. flask, bottle, aiohttp, etc.)"]
io_trans [label="io_trans\n(how python types cast to ws types)"]
url_and_json_schema [label="url_and_json_schema\n(how to translate webrequest to python command)"]
language -> http2lang_configs
language [shape="none"]
language [label="language\n(e.g. python, js, etc.)"]
ui_backend, layout, navig -> service2ui_configs
ui_backend, layout, navig [shape="none"]
ui_backend [label="ui_backend\n(e.g. streamlit, dash, etc.)"]
layout [label="layout\n(rules for elements' layout)"]
navig [label="navig\n(rules for action order)"]
deploy_container -> ui2deploy_configs
deploy_container [shape="none"]
deploy_container [label="deploy_container\n(e.g. local_server, remote_server, docker)"]
""".split('\n'))from qo import dgdisp
dgdisp("""
configs, convention -> [mk_specs] -> obj_specs, ui_obj_specs, app_specs
objs, obj_specs -> [obj_minting] -> objs_mint
objs_mint, ui_obj_specs -> [ui_minting] -> ui_objs_mint
ui_objs_mint, app_specs -> [mk_app] -> app
""")