forked from yashasvini121/predictive-calc
-
Notifications
You must be signed in to change notification settings - Fork 0
/
form_handler.py
172 lines (154 loc) · 5.1 KB
/
form_handler.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
import streamlit as st
import json
from typing import Dict, Any
class FormHandler:
"""
A class to handle rendering a form in Streamlit based on a configuration file.
Attributes:
name (str): The name of the form to be rendered.
button_label (str): The label for the submit button.
model (callable): The model function to be called with form data.
config_path (str): Path to the configuration JSON file.
Structure of the configuration JSON file:
{
"Form Name": {
"field_label": {
"field_name": "field_name",
"type": "field_type",
"default_value": "default_value",
"min_value": min_value,
"max_value": max_value,
"step": step,
"options": ["option1", "option2"],
},
...
}
}
"""
def __init__(
self, name: str, button_label: str, model: callable, config_path: str
) -> None:
"""
Initializes the FormHandler with the provided parameters.
Parameters:
name (str): The name of the form to be rendered.
button_label (str): The label for the submit button.
model (callable): The model function to be called with form data.
config_path (str): Path to the configuration JSON file.
"""
self.name = name
self.button_label = button_label
self.model = model
self.config_path = config_path
self.fields = self.load_fields_from_config()
def load_fields_from_config(self) -> Dict[str, Dict[str, Any]]:
"""
Loads form fields from the configuration JSON file.
Returns:
Dict[str, Dict[str, Any]]: A dictionary of form fields and their attributes.
"""
# Try-except block to handle the exception if file not found or if parsing has parsing issues in JSON
try:
with open(self.config_path, "r") as f:
config = json.load(f)
return config.get(self.name, {})
except FileNotFoundError:
st.error(f"Configuration file not found: {self.config_path}")
return {}
except json.JSONDecodeError:
st.error(f"Error parsing the configuration file: {self.config_path}")
return {}
def render(self) -> None:
"""
Renders the form in the Streamlit application.
This method collects user input and, upon form submission, calls the specified model
with the collected data mapped to the appropriate field names from the config file.
"""
# Dictionary to hold form data
form_data: Dict[str, Any] = {}
# Loop over the fields in the form
for label, attributes in self.fields.items():
field_type = attributes.get("type")
field_name = attributes.get(
"field_name", label
) # Use field_name from the config
#Handle different types of input fields
if field_type == "number":
form_data[field_name] = st.number_input(
label,
value=attributes.get("default_value"),
min_value=attributes.get("min_value"),
max_value=attributes.get("max_value"),
step=attributes.get("step", 1),
)
elif field_type == "float": # New case for float values
form_data[field_name] = st.number_input(
label,
value=attributes.get("default_value"),
min_value=attributes.get("min_value"),
max_value=attributes.get("max_value"),
step=attributes.get("step"),
format="%.6f" # format to 6 decimal places
)
elif field_type == "dropdown":
form_data[field_name] = st.selectbox(
label,
options=attributes.get("options"),
index=attributes.get("options").index(
attributes.get("default_value")
),
)
elif field_type == "range":
form_data[field_name] = st.slider(
label,
min_value=attributes.get("min_value"),
max_value=attributes.get("max_value"),
value=tuple(attributes.get("default_value")), # type: ignore
)
elif field_type == "multiselect":
form_data[field_name] = st.multiselect(
label,
options=attributes.get("options"),
default=attributes.get("default_value"),
)
elif field_type == "text":
form_data[field_name] = st.text_input(
label, value=attributes.get("default_value")
)
elif field_type == "checkbox":
form_data[field_name] = st.checkbox(
label, value=attributes.get("default_value", False)
)
elif field_type == "radio":
form_data[field_name] = st.radio(
label,
options=attributes.get("options"),
index=attributes.get("options").index(
attributes.get("default_value")
),
)
elif field_type == "slider":
form_data[field_name] = st.slider(
label,
min_value=attributes.get("min_value"),
max_value=attributes.get("max_value"),
value=attributes.get("default_value"),
)
elif field_type == "date":
form_data[field_name] = st.date_input(label)
elif field_type == "time":
form_data[field_name] = st.time_input(label)
elif field_type == "file":
form_data[field_name] = st.file_uploader(label)
elif field_type == "password":
form_data[field_name] = st.text_input(label, type="password")
elif field_type == "image":
form_data[field_name] = st.image(label)
else:
st.warning(f"Unknown field type: {field_type}")
# Submit button
if st.button(self.button_label):
# Call the model with the form data
result = self.model(**form_data)
# Display the result
st.success(f"Result: {result}")