diff --git a/ack/entrypoints/json/main.py b/ack/entrypoints/json/main.py index 92ff166..3d70adb 100644 --- a/ack/entrypoints/json/main.py +++ b/ack/entrypoints/json/main.py @@ -27,8 +27,12 @@ @click.option( "--config-file", help="Path of the json file used to build the command.", required=True, type=click.Path(exists=True), ) -def read_and_write(config_file): +def read_and_write_from_json(config_file): data = read_json(config_file) + read_and_write(data) + + +def read_and_write(data): if "normalize_keys" not in data.keys(): data["normalize_keys"] = False @@ -44,4 +48,4 @@ def read_and_write(config_file): if __name__ == "__main__": - read_and_write() + read_and_write_from_json() diff --git a/ack/ui/__init__.py b/ack/ui/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/ack/ui/helpers.py b/ack/ui/helpers.py new file mode 100644 index 0000000..e9f3a4f --- /dev/null +++ b/ack/ui/helpers.py @@ -0,0 +1,69 @@ +from datetime import datetime, date + + +def datetimeconverter(o): + if isinstance(o, date): + return str(o) + + +def make_recording_widget(f, d): + + def wrapper(json_name, label, *args, **kwargs): + widget_value = f(label, *args, **kwargs) + d[json_name] = widget_value + return widget_value + + return wrapper + + +def make_recording_list_widget(f, d): + + def wrapper(json_name, label, *args, **kwargs): + widget_value = f(label, *args, **kwargs) + d[json_name] = widget_value.strip('][').split(',') + return widget_value + + return wrapper + + +def create_field_ui(field, field_name, col, d, title): + + selectbox = make_recording_widget(col.selectbox, d) + date_input = make_recording_widget(col.date_input, d) + checkbox = make_recording_widget(col.checkbox, d) + number_input = make_recording_widget(col.number_input, d) + text_input = make_recording_widget(col.text_input, d) + array_input = make_recording_list_widget(col.text_input, d) + multi_select = make_recording_widget(col.multiselect, d) + + if "enum" in field: + selectbox(field_name, field["title"], field["enum"], key=f'{title}{field_name}') + elif "format" in field and field["format"] == "date-time": + date_input(field_name, field["title"], datetime.now(), key=f'{title}{field_name}') + elif field["type"] == 'string': + default = field.get("default", "") + text_input(field_name, field["title"], default, key=f'{title}{field_name}') + elif field["type"] == "array": + if 'enum' in field['items'] : + multi_select(field_name, field["title"] + " (array)", field['items']['enum'], key=f'{title}{field_name}') + else : + array_input(field_name, field["title"] + " (array)", "[]", + help="this must look like ['a','b']", key=f'{title}{field_name}') + elif field["type"] == "boolean": + checkbox(field_name, field["title"], [True, False], key=f'{title}{field_name}') + elif field["type"] == "integer" or field["type"] == "number": + default = field.get("default", 1) + number_input(field_name, field["title"], default, key=f'{title}{field_name}') + else : + raise NotImplementedError + + +def create_ui_schema(schema, col, d, fields): + exp = col.beta_expander("params") + for field, field_name, field_opt in zip(schema["properties"].values(), schema["properties"], fields): + if field_opt.required: + create_field_ui(field, field_name, exp, d, schema["title"]) + else : + a = exp.checkbox("use field " + field["title"]) + if a: + create_field_ui(field, field_name, exp, d, schema["title"]) diff --git a/ack/ui/ui.py b/ack/ui/ui.py new file mode 100644 index 0000000..7c96467 --- /dev/null +++ b/ack/ui/ui.py @@ -0,0 +1,59 @@ +import streamlit as st +from ack.entrypoints.json.readers import readers_classes +from ack.entrypoints.json.writers import writers_classes +from ack.ui.helpers import create_ui_schema, datetimeconverter +import pandas as pd +import json +import sys +import io + +from ack.entrypoints.json.main import read_and_write + +st.set_page_config(layout="wide") + +WRITER_PATH = "../writers" +READER_PATH = "../readers" + +reader_dict = {} +writer_dict = {} +result_dict = {"reader": reader_dict, "writers": [writer_dict]} + +st.header("ACK UI : The best way to test out ACK") + +reader_col, writer_col = st.beta_columns(2) + +reader = reader_col.selectbox("choose a reader", options=list(readers_classes.keys())) +reader_fields = readers_classes[reader][1].__fields__.values() +writer = writer_col.selectbox("choose a writer", options=list(writers_classes.keys())) +writer_fields = readers_classes[reader][1].__fields__.values() +reader_schema = readers_classes[reader][1].schema() +if len(writers_classes[writer]) > 1: + writer_schema = writers_classes[writer][1].schema() + create_ui_schema(writer_schema, writer_col, writer_dict, writer_fields) + + +create_ui_schema(reader_schema, reader_col, reader_dict, reader_fields) + +st.text("") +jsonbutton = st.button("generate JSON") +lauchbutton = st.button("launch") + +reader_dict["name"] = reader +writer_dict["name"] = writer + +if jsonbutton : + st.text(json.dumps(result_dict, default=datetimeconverter, indent=2)) + +if lauchbutton : + json_result = json.dumps(result_dict, default=datetimeconverter, indent=2) + dict_final = json.loads(json_result) + if writer == "console": + out = io.TextIOWrapper(io.BytesIO()) + sys.stdout = out + read_and_write(dict_final) + out.seek(0) + df = pd.read_json(out.read(), lines=True) + df + sys.stdout = sys.__stdout__ + else : + read_and_write(dict_final) diff --git a/requirements.txt b/requirements.txt index 7eec3a8..37a0678 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ addressable==1.4.2 boto3==1.10.34 botocore==1.13.34 -cachetools==3.1.1 +cachetools==4.2.2 certifi==2019.11.28 chardet==3.0.4 Click==7.0 @@ -35,7 +35,6 @@ num2words==0.5.10 numpy==1.20.2 oauth2client==1.5.2 prettytable==0.7.2 -protobuf==3.11.1 pyasn1==0.4.8 pyasn1-modules==0.2.7 pycountry==19.8.18 @@ -65,3 +64,5 @@ pyjwt==1.7.1 cryptography==3.3.2 bs4==0.0.1 pydantic==1.8.1 +streamlit==0.80.0 +protobuf==3.15.8 \ No newline at end of file