Skip to content

Front Design Notes

Thor Whalen edited this page Jan 5, 2022 · 5 revisions

Main architecture

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_service and open_api_specs for 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.

image

Notes

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.

Dated

2022-01-05

Get from functions to browser based UI semi-automatically, where:

  • Service (web or js) is a separate concern — minimum: a front-ender can just use the web-service part of the app
  • Service has a spec (like OpenAPI spec), so that language-binders can easily be made Input/Output trans (io casting?) is separate and has boilerplate-reducing tooling (e.g. arg-name and type mapping), so that backend functions can be "pure" (no trace of the web-service or UI concerns)

Proposal: Use https://github.com/i2mint/front as to aggregate code, discussions, tools, as well as issues and wikis. front is now tied closely to streamlit, but the goal is that the ui be made as a replaceable layer/plugin just as flask, bottle and aiohttp are plugins for py2http.

Our stuff on getting web-services from python functions:

Our stuff on getting UIs from python function

Tool to (apparently) go from python functions (that are pydantic-typed) to UI, but with separable layers (web-service and web-service-specification (like OpenAPI?)): https://github.com/ml-tooling/opyrator

Appendix

Graphviz for main architecture graph

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'))

Clone this wiki locally