@@ -93,107 +93,8 @@ class AdminUserModel(BaseModel):
93
93
return UserModel
94
94
95
95
96
- # Example form configuration with default values set
97
- example_form_config = {
98
- "example_form" : {
99
- "text_input" : {
100
- "input_type" : "text" ,
101
- "output_type" : str ,
102
- "field_name" : "text_input" ,
103
- "default" : "Default Text" ,
104
- "validators" : {
105
- "min_length" : 1 , # These are drawn from:
106
- "max_length" : 200 , # https://docs.pydantic.dev/latest/api/fields/#pydantic.fields.Field
107
- "pattern" : r'^[\s\S]*$' ,
108
- },
109
- "required" : True ,
110
- "options" : None ,
111
- "description" : "This is a text field" ,
112
- },
113
- "number_input" : {
114
- "input_type" : "number" ,
115
- "output_type" : int ,
116
- "field_name" : "number_input" ,
117
- "default" : 42 ,
118
- "validators" : {
119
- "ge" : 0 , # These are drawn from:
120
- "le" : 10000 , # https://docs.pydantic.dev/latest/api/fields/#pydantic.fields.Field
121
- },
122
- "required" : False ,
123
- "options" : None ,
124
- "description" : "This is a number field" ,
125
- },
126
- "email_input" : {
127
- "input_type" : "email" ,
128
- "output_type" : str ,
129
- "field_name" : "email_input" ,
130
-
131
- "required" : False ,
132
- "options" : None ,
133
- "description" : "This is an email field" ,
134
- },
135
- "date_input" : {
136
- "input_type" : "date" ,
137
- "output_type" : date ,
138
- "field_name" : "date_input" ,
139
- "default" : "2024-01-01" ,
140
- "required" : False ,
141
- "options" : None ,
142
- "description" : "This is a date field" ,
143
- },
144
- "checkbox_input" : {
145
- "input_type" : "checkbox" ,
146
- "output_type" : List [str ],
147
- "field_name" : "checkbox_input" ,
148
- "options" : ["Option1" , "Option2" , "Option3" ],
149
- "required" : True ,
150
- "default" : ["Option1" , "Option3" ],
151
- "description" : "This is a checkbox field" ,
152
- },
153
- "radio_input" : {
154
- "input_type" : "radio" ,
155
- "output_type" : str ,
156
- "field_name" : "radio_input" ,
157
- "options" : ["Option1" , "Option2" ],
158
- "required" : False ,
159
- "default" : "Option1" ,
160
- "description" : "This is a radio field" ,
161
- },
162
- "select_input" : {
163
- "input_type" : "select" ,
164
- "output_type" : str ,
165
- "field_name" : "select_input" ,
166
- "options" : ["Option1" , "Option2" , "Option3" ],
167
- "required" : False ,
168
- "default" : "Option2" ,
169
- "description" : "This is a select field" ,
170
- },
171
- "textarea_input" : {
172
- "input_type" : "textarea" ,
173
- "output_type" : str ,
174
- "field_name" : "textarea_input" ,
175
- "default" : "Default textarea content." ,
176
- "validators" : {
177
- "min_length" : 0 , # A note about min-length: https://stackoverflow.com/a/10294291/13301284. Better to set a pattern and set required.
178
- "max_length" : 200 , # These are drawn from: https://docs.pydantic.dev/latest/api/fields/#pydantic.fields.Field
179
- "pattern" : r'^[\s\S]*$' ,
180
- },
181
- "required" : False ,
182
- "options" : None ,
183
- "description" : "This is a textarea field" ,
184
- },
185
- "file_input" : {
186
- "input_type" : "file" ,
187
- "output_type" : bytes ,
188
- "field_name" : "file_input" ,
189
- "options" : None ,
190
- "required" : False ,
191
- "default" : None , # File inputs can't have default values
192
- "description" : "This is a file field" ,
193
- },
194
- },
195
- }
196
-
96
+ # The options in the `validator` field are drawn from: https://docs.pydantic.dev/latest/api/fields/#pydantic.fields.Field
97
+ # A note about min-length: https://stackoverflow.com/a/10294291/13301284. Better to set a pattern and set required.
197
98
EXAMPLE_FORM_CONFIG_YAML = """
198
99
example_form:
199
100
text_input:
@@ -290,45 +191,59 @@ class AdminUserModel(BaseModel):
290
191
description: This is a file field
291
192
"""
292
193
194
+ def get_yaml_constructors (** kwargs ):
195
+ """
196
+ This factory is used to build a dictionary of built-in and custom constructors that
197
+ will be used in building the internal, dictionary representation of the form config.
198
+ """
199
+
200
+ # Default constructors for returning Python types
201
+ def type_constructor_int (loader , node ):
202
+ return int
293
203
294
- # Constructors that return Python types themselves
295
- def type_constructor_int (loader , node ):
296
- return int
204
+ def type_constructor_str (loader , node ):
205
+ return str
297
206
298
- def type_constructor_str (loader , node ):
299
- return str
207
+ def type_constructor_date (loader , node ):
208
+ return date
300
209
301
- def type_constructor_date (loader , node ):
302
- return date
210
+ def type_constructor_datetime (loader , node ):
211
+ return datetime
303
212
304
- def type_constructor_datetime (loader , node ):
305
- return datetime
213
+ def type_constructor_time (loader , node ):
214
+ return time
306
215
307
- def type_constructor_time (loader , node ):
308
- return time
216
+ def type_constructor_timedelta (loader , node ):
217
+ return timedelta
309
218
310
- def type_constructor_timedelta (loader , node ):
311
- return timedelta
219
+ def type_constructor_list (loader , node ):
220
+ return list
312
221
313
- def type_constructor_list (loader , node ):
314
- return list
222
+ def type_constructor_tuple (loader , node ):
223
+ return tuple
315
224
316
- def type_constructor_tuple (loader , node ):
317
- return tuple
225
+ def type_constructor_bytes (loader , node ):
226
+ return bytes
318
227
319
- def type_constructor_bytes (loader , node ):
320
- return bytes
228
+ # We create a constructor mapping that we'll use later to
229
+ # register the constructors.
230
+ constructor_mapping = {
231
+ '!int' : type_constructor_int ,
232
+ '!str' : type_constructor_str ,
233
+ '!date' : type_constructor_date ,
234
+ '!type_datetime' : type_constructor_datetime ,
235
+ '!type_time' : type_constructor_time ,
236
+ '!type_timedelta' : type_constructor_time ,
237
+ '!list' : type_constructor_list ,
238
+ '!tuple' : type_constructor_list ,
239
+ '!bytes' : type_constructor_bytes ,
240
+ ** kwargs ,
241
+ }
242
+ return constructor_mapping
321
243
322
244
# Register the type constructors
323
- yaml .add_constructor ('!int' , type_constructor_int )
324
- yaml .add_constructor ('!str' , type_constructor_str )
325
- yaml .add_constructor ('!date' , type_constructor_date )
326
- yaml .add_constructor ('!type_datetime' , type_constructor_datetime )
327
- yaml .add_constructor ('!type_time' , type_constructor_time )
328
- yaml .add_constructor ('!type_timedelta' , type_constructor_time )
329
- yaml .add_constructor ('!list' , type_constructor_list )
330
- yaml .add_constructor ('!tuple' , type_constructor_list )
331
- yaml .add_constructor ('!bytes' , type_constructor_bytes )
245
+ for key , value in get_yaml_constructors ().items ():
246
+ yaml .add_constructor (key , value )
332
247
333
248
def load_form_config (config_path = None ):
334
249
"""
0 commit comments