A Python package for form field helpers and payload translation utilities.
pip install git+https://github.com/MassDynamics/md_form.gitThe package provides field helper functions for creating form fields with validation rules and conditional visibility. All helpers accept common parameters via the decorator:
name: Display namedescription: Help textwhen: AWhencondition to control visibilityrules: A rule or list of rules frommd_form.field_utils.rulesparameters: Dict of custom UI parameters to merge intojson_schema_extra.parameters. These are merged with any existing parameters from the field helper, allowing you to customise or extend the default behaviour.
Note: Fields are optional by default (default=None). Include is_required() in rules to make a field required.
The parameters argument allows you to customise field behaviour by merging custom UI parameters with the field helper's default parameters. The merging logic works as follows:
- Field helpers provide default parameters - Each helper function includes sensible defaults (e.g.,
select_fieldincludesoptions,control_variables_fieldincludesradioOptions) - Custom parameters are merged - Your custom
parametersdict is merged into the existingjson_schema_extra.parameters - Custom parameters take precedence - If you provide a parameter with the same key as a default, your value will override the default
- New parameters are added - Any new parameters you provide are added to the existing set
Example:
# control_variables_field has default parameters.radioOptions = ["categorical", "numerical"]
control_vars = control_variables_field(
name="Control Variables",
parameters={
"placeholder": "Select control variable type", # New parameter
"radioOptions": ["custom", "other"] # Override default
}
)
# Result: parameters.radioOptions = ["custom", "other"], parameters.placeholder = "Select control variable type"boolean_field(default=None, label=None)string_field(default=None, disabled=False)number_field(default=None, ge=None, le=None)select_field(default=None, options=None, discriminator=None)optionsis a list of strings; each option becomes{ "name": v, "value": v }(name equals value)discriminatoris passed through for downstream oneOf selection
numberrange_field(default=None, ge=None, le=None, interval=None)
experiment_design_field()condition_column_field()condition_comparisons_field()control_variables_field(default=None)intensity_input_dataset_field()entity_type_field(default=None)
Example:
from md_form.field_utils import (
condition_column_field,
is_not_equal_to_value,
is_not_equal_to_value_from_field,
is_required,
When
)
# Create a condition column field with validation rules
condition_column = condition_column_field(
name="Condition Column",
rules=[
is_not_equal_to_value("sample_name"),
is_not_equal_to_value_from_field("control_variables"),
is_required(),
],
when=When.not_equals("input_datasets", None)
)is_equal_to_value(value)- Validates that a field equals a specific literal valueis_not_equal_to_value(value)- Validates that a field does not equal a specific literal valueis_equal_to_value_from_field(field)- Validates that a field equals the value of another specified fieldis_not_equal_to_value_from_field(field)- Validates that a field does not equal the value of another specified fieldis_required()- Marks a field as required/mandatoryis_all_unique_in_column(column)- Ensures all values in a specified column are unique (no duplicates)has_unique_in_column(column)- Ensures at least one unique value exists in a specified columnis_all_unique_in_column_from_field(field)- Ensures all values in a column (specified by another field) are uniquehas_unique_in_column_from_field(field)- Ensures at least one unique value exists in a column (specified by another field)
Use the When class to create conditional logic:
from md_form.field_utils import When
# Field is shown when input_datasets is not None
when = When.not_equals("input_datasets", None)
# Field is shown when some_field equals "value"
when = When.equals("some_field", "value")Use the translate_payload function to transform JSON-schema-like payloads to a simplified form schema suitable for UI rendering.
Key behaviours:
- Keeps only allowed second-layer keys:
fieldType,parameters,name,rules,description,default,when - Converts
enum: [v1, v2]toparameters.options: [{"name": v, "value": v}](name equals value) - Renames keys:
maximum/minimum -> max/min,maxItems/minItems -> max/min - Moves
options,min,maxintoparameters - Flattens
$refand nestedproperties; resolvesoneOfwithdiscriminatorby inlining referenced sub-properties - Removes top-level
output_dataset_typeand non-object nodes
from md_form import translate_payload
# Transform function parameters schema (example)
parameters_new = translate_payload(dict(fn.parameters))To install in development mode:
pip install -e .