From 4848afbfd5360d5ee494cba04bccf0d1115c9ce1 Mon Sep 17 00:00:00 2001 From: newlog Date: Thu, 3 Aug 2023 16:41:16 +0200 Subject: [PATCH 1/2] Fix all dash deprecation errors --- .gitignore | 3 ++ examples/standalone_example.py | 8 ++--- json_schema_to_dash_forms/forms.py | 55 +++++++++++++++++------------- json_schema_to_dash_forms/utils.py | 12 ++----- 4 files changed, 40 insertions(+), 38 deletions(-) diff --git a/.gitignore b/.gitignore index cd82a47..8333707 100644 --- a/.gitignore +++ b/.gitignore @@ -128,3 +128,6 @@ dmypy.json # Pyre type checker .pyre/ + +.DS_Store +.idea \ No newline at end of file diff --git a/examples/standalone_example.py b/examples/standalone_example.py index 37a8ed0..a2d91b2 100644 --- a/examples/standalone_example.py +++ b/examples/standalone_example.py @@ -1,7 +1,5 @@ import dash import dash_bootstrap_components as dbc -import dash_html_components as html -import json from pathlib import Path from json_schema_to_dash_forms import SchemaFormContainer from dash.dependencies import Input, Output, State @@ -60,7 +58,7 @@ dbc.Textarea( id='display_results', className='string_input', - bs_size="lg", + size="lg", readOnly=True, style={'font-size': '16px', 'min-height': '250px', 'max-height': '500px'} ), @@ -105,10 +103,10 @@ def show_data_from_internal_dict(trigger, is_open): if not trigger: return dash.no_update - alerts, output = my_form.data_to_nested() # Read internal dict and get missing required fields and output nested dict + alerts, output = my_form.data_to_nested() # Read internal dict and get missing required fields and output nested dict if alerts is not None: - return True, alerts, '' # If any missing fields return alerts + return True, alerts, '' # If any missing fields return alerts # Else show json data json_string = json.dumps(output, indent=4) diff --git a/json_schema_to_dash_forms/forms.py b/json_schema_to_dash_forms/forms.py index 5a14c19..4f061ef 100644 --- a/json_schema_to_dash_forms/forms.py +++ b/json_schema_to_dash_forms/forms.py @@ -3,8 +3,8 @@ import dash import dash_bootstrap_components as dbc -import dash_core_components as dcc -import dash_html_components as html +from dash import dcc +from dash import html import numpy as np from dash.dependencies import Input, Output, State, ALL, MATCH from dash_cool_components import TagInput, DateTimePicker @@ -14,7 +14,7 @@ from .utils import make_filebrowser_modal -class SchemaFormItem(dbc.FormGroup): +class SchemaFormItem(dbc.Form): def __init__(self, label, value, input_id, parent, required=False): super().__init__([]) @@ -107,7 +107,7 @@ def get_field_input(self, value, input_id, description=None, required=False): field_input = dbc.Textarea( id=compound_id, className='string_input', - bs_size="lg", + size="lg", style={'font-size': '16px'} ) @@ -145,7 +145,7 @@ def get_field_input(self, value, input_id, description=None, required=False): field_input = html.Div([ dbc.InputGroup([ input_path, - dbc.InputGroupAddon(btn_open_filebrowser, addon_type="append"), + btn_open_filebrowser, ]), modal ]) @@ -155,7 +155,7 @@ def get_field_input(self, value, input_id, description=None, required=False): default = value.get('default', False) field_input = dbc.Checkbox( id=compound_id, - checked=default + value=default ) else: @@ -268,7 +268,8 @@ def __init__(self, schema, key, container=None, parent_form=None): header_text = schema.get('title', self.id.split('-')[-1]) self.header = dbc.CardHeader( - [dbc.Button(html.H4(header_text, style={"color": 'black'}, className="title_" + key), color='link', id={"type": "collapsible-toggle", "container": f"{self.container.id}", 'index': f'{self.id}-collapsible'})], + [dbc.Button(html.H4(header_text, style={"color": 'black'}, className="title_" + key), color='link', + id={"type": "collapsible-toggle", "container": f"{self.container.id}", 'index': f'{self.id}-collapsible'})], style={'padding': '10px'} ) self.body = dbc.CardBody([]) @@ -281,10 +282,11 @@ def __init__(self, schema, key, container=None, parent_form=None): if 'properties' in schema: self.make_form(properties=schema['properties']) - self.body = dbc.Collapse(self.body, id={"type": 'collapsible-body', "container": f"{self.container.id}" ,"index": f'{self.id}-collapsible'}, is_open=True) + self.body = dbc.Collapse(self.body, + id={"type": 'collapsible-body', "container": f"{self.container.id}", "index": f'{self.id}-collapsible'}, + is_open=True) self.children = [self.header, self.body] - def make_form(self, properties): """Iterates over properties of schema and assembles form items""" for k, v in properties.items(): @@ -314,7 +316,7 @@ def make_form(self, properties): continue # If item is an array of subforms, it should have 'minItems' - if 'minItems' in v: + if 'minItems' in v: value = [] if '$ref' in v['items']: # search for reference somewhere else in the root schema for i in v['items']['$ref'].split('/'): @@ -325,7 +327,7 @@ def make_form(self, properties): schema = aux else: schema = v['items'] - + # Creates 'minItems' number of subforms for index in range(v['minItems']): iform = SchemaForm(schema=schema, key=f'{k}-{index}', parent_form=self) @@ -388,8 +390,10 @@ def __init__(self, id, schema, parent_app, root_path=None): # Hidden components that serve to trigger callbacks self.children_triggers = [ - html.Div(id={'type': 'external-trigger-update-forms-values', 'index': id + '-external-trigger-update-forms-values'}, style={'display': 'none'}), - html.Div(id={'type': 'external-trigger-update-links-values', 'index': f'{id}-external-trigger-update-links-values'}, style={"display": "none"}), + html.Div(id={'type': 'external-trigger-update-forms-values', 'index': id + '-external-trigger-update-forms-values'}, + style={'display': 'none'}), + html.Div(id={'type': 'external-trigger-update-links-values', 'index': f'{id}-external-trigger-update-links-values'}, + style={"display": "none"}), html.Div(id=f'{id}-external-trigger-update-internal-dict', style={'display': 'none'}), html.Div(id=f'{id}-output-update-finished-verification', style={'display': 'none'}), html.Div(id=id + '-trigger-update-links-values', style={'display': 'none'}), @@ -411,7 +415,7 @@ def __init__(self, id, schema, parent_app, root_path=None): self.update_forms_values_callback_outputs = [ Output(dict(_args_dict, data_type='path'), 'value'), - Output(dict(_args_dict, data_type='boolean'), 'checked'), + Output(dict(_args_dict, data_type='boolean'), 'value'), Output(dict(_args_dict, data_type='string'), 'value'), Output(dict(_args_dict, data_type='datetime'), 'defaultValue'), Output(dict(_args_dict, data_type='tags'), 'injectedTags'), @@ -421,7 +425,7 @@ def __init__(self, id, schema, parent_app, root_path=None): ] self.update_forms_values_callback_states = [ State(dict(_args_dict, data_type='path'), 'value'), - State(dict(_args_dict, data_type='boolean'), 'checked'), + State(dict(_args_dict, data_type='boolean'), 'value'), State(dict(_args_dict, data_type='string'), 'value'), State(dict(_args_dict, data_type='datetime'), 'value'), State(dict(_args_dict, data_type='tags'), 'value'), @@ -436,7 +440,7 @@ def __init__(self, id, schema, parent_app, root_path=None): //const element = document.getElementById(JSON.stringify(ids, Object.keys(ids).sort())) ctx = dash_clientside.callback_context - + if (typeof ctx.triggered[0] === "undefined"){ return dash_clientside.no_update } @@ -447,9 +451,9 @@ def __init__(self, id, schema, parent_app, root_path=None): } """, - Output({"type":'collapsible-body', "container": f'{self.id}', "index": MATCH}, 'is_open'), + Output({"type": 'collapsible-body', "container": f'{self.id}', "index": MATCH}, 'is_open'), [Input({"type": 'collapsible-toggle', "container": f'{self.id}', "index": MATCH}, 'n_clicks')], - [State({"type":'collapsible-body', "container": f'{self.id}', "index": MATCH}, 'is_open')] + [State({"type": 'collapsible-body', "container": f'{self.id}', "index": MATCH}, 'is_open')] ) @self.parent_app.callback( @@ -457,7 +461,7 @@ def __init__(self, id, schema, parent_app, root_path=None): [Input(f'{self.id}-external-trigger-update-internal-dict', 'children')], [ State({'type': 'metadata-input', 'container_id': self.id, 'data_type': 'path', 'index': ALL}, 'value'), - State({'type': 'metadata-input', 'container_id': self.id, 'data_type': 'boolean', 'index': ALL}, 'checked'), + State({'type': 'metadata-input', 'container_id': self.id, 'data_type': 'boolean', 'index': ALL}, 'value'), State({'type': 'metadata-input', 'container_id': self.id, 'data_type': 'string', 'index': ALL}, 'value'), State({'type': 'metadata-input', 'container_id': self.id, 'data_type': 'datetime', 'index': ALL}, 'value'), State({'type': 'metadata-input', 'container_id': self.id, 'data_type': 'tags', 'index': ALL}, 'value'), @@ -531,7 +535,8 @@ def update_forms_values(trigger, trigger_all, *states): if context['type'] == 'external-trigger-update-forms-values' and all((trg is None) or trg == [] for trg in trigger): raise dash.exceptions.PreventUpdate - if context['type'] == 'internal-trigger-update-forms-values' and all((trg is None) or trg == [] or trg == '' for trg in trigger_all): + if context['type'] == 'internal-trigger-update-forms-values' and all( + (trg is None) or trg == [] or trg == '' for trg in trigger_all): raise dash.exceptions.PreventUpdate output_path = [] @@ -587,7 +592,8 @@ def update_forms_links(trigger, trigger_all, name_change): if 'type' in trigger_source: trigger_source = json.loads(trigger_source)['type'] - if trigger_source == 'external-trigger-update-links-values' and all((trg is None) or trg == [] or trg == '' for trg in trigger_all): + if trigger_source == 'external-trigger-update-links-values' and all( + (trg is None) or trg == [] or trg == '' for trg in trigger_all): raise dash.exceptions.PreventUpdate if trigger_source == f'{self.id}-trigger-update-links-values' and trigger is None: raise dash.exceptions.PreventUpdate @@ -640,7 +646,7 @@ def update_data(self, data, key=None): """Update data in the internal mapping dictionary of this Container""" if key is None: key = self.id - + # Update dict with incoming data for k, v in data.items(): if k in self.skiped_forms: @@ -700,7 +706,8 @@ def data_to_nested(self): for k, v in self.data.items(): field_value = v['value'] - if v['required'] and (field_value is None or (isinstance(field_value, str) and field_value.isspace()) or field_value == '' or (str(field_value) == str(self.root_path))): + if v['required'] and (field_value is None or (isinstance(field_value, str) and field_value.isspace()) or field_value == '' or ( + str(field_value) == str(self.root_path))): empty_required_fields.append(k) alert_children.append(html.A( k, @@ -719,7 +726,7 @@ def data_to_nested(self): elif element != master_key_name: curr_dict = {element: curr_dict} else: - #if element == master_key_name: + # if element == master_key_name: dicts_list.append(curr_dict) for e in dicts_list: diff --git a/json_schema_to_dash_forms/utils.py b/json_schema_to_dash_forms/utils.py index 0a55c6f..b3e83bf 100644 --- a/json_schema_to_dash_forms/utils.py +++ b/json_schema_to_dash_forms/utils.py @@ -3,7 +3,7 @@ import dash import dash_bootstrap_components as dbc -import dash_html_components as html +from dash import html from dash.dependencies import Input, Output, State from dash_cool_components import KeyedFileBrowser from pathlib import Path @@ -56,15 +56,9 @@ def __init__(self, parent_app, id_suffix, root_dir=None, display=None): # Button part input_group = dbc.InputGroup([ - dbc.InputGroupAddon( - dbc.Button(button_text, color='dark', id="button_file_browser_" + id_suffix), - addon_type="prepend", - ), + dbc.Button(button_text, color='dark', id="button_file_browser_" + id_suffix), dbc.Input(id="chosen-filebrowser-" + id_suffix, placeholder=""), - dbc.InputGroupAddon( - dbc.Button('Submit', color='dark', id='submit-filebrowser-' + id_suffix), - addon_type='prepend', - ), + dbc.Button('Submit', color='dark', id='submit-filebrowser-' + id_suffix) ]) # Collapsible part - file browser From b53086f882ff8b1244d9ab8863311442c491f67c Mon Sep 17 00:00:00 2001 From: newlog Date: Thu, 3 Aug 2023 16:42:24 +0200 Subject: [PATCH 2/2] Fix schema.json example --- examples/schema.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/schema.json b/examples/schema.json index 0532c57..c450d9f 100644 --- a/examples/schema.json +++ b/examples/schema.json @@ -82,7 +82,7 @@ "description": "subforms children array w/ size defined by min/max items and referenced by definitions", "minItems": 2, "maxItems": 2, - "items": [{"$ref": "#/definitions/ChildrenExample"}] + "items": {"$ref": "#/definitions/ChildrenExample"} } } }