ConfigSpecs
A typed schema (dict of ParamSpec) plus value-management helpers.
The helpers (strip_computed_keys, validate_values, merge_computed, diff_values) operate on a values dict shaped by these specs.
ITEM_ID_KEY is the reserved per-row key on ParamSet items. ParamSet.validate mints, preserves, and restores it; nothing else in ConfigSpecs writes it.
ITEM_ID_KEY: ClassVarMAX_KEY_LENGTH: ClassVarinvalid_reason: str | Noneis_valid: boolspecs: dictDefine the spec of a task or a view Example: ConfigSpecs({ "param1": IntParam(human_name="Param 1", default_value=1), "param2": StrParam(human_name="Param 2", default_value="Hello") })
dict[str, gws_core.config.param.param_spec.ParamSpec] | Nonebool - FalsestrParamSpecstrParamSpecCheck if all the config are optional
boolRaise if this ConfigSpecs was built with an invalid definition.
Explicit fail-fast hook for runtime/non-class-body callers. The constructor itself never raises (see is_valid).
Build the ConfigParams from the param_specs and param_values. ConfigParam is supposed to be used directly not stored. Check the param_values with params_specs and return ConfigParams if ok. ConfigParams contains all value and default value if not provided.
Computed params (accepts_user_input=False) are evaluated after validation and merged into the returned ConfigParams.
dictConfigParamsCheck that the config specs are valid.
Validates spec keys (shape + length) and types, and delegates to ComputedParamGraphChecker for cycle detection and reference validation across computed expressions (which already recurses into ParamSets). Key validation also recurses into ParamSet inner specs.
strEvaluate all entries with accepts_user_input=False over the provided values and return (computed_values, errors_by_key).
Thin delegator to ComputedParamResolver.compute_all — see that method for the full contract.
dictAnytupleRender a {field_key: message} map as a sorted list of
"Label: message" strings (labels via :meth:format_field_key).
Centralizes what every save/test surface used to do inline so the order and format are consistent across them.
dictlistTranslate an internal field-key into a human-readable label using
spec.human_name (falling back to the raw key when no human name
is set).
Outputs:
"total_mass"→"Total mass""samples[].density"→"Samples[].Density"(formula on a ParamSet inner key — applies to every row)"samples[2].mass"→"Samples[2].Mass"(a single row)
Used by save/test surfaces to turn validation- and computed-error keys into messages a user can read; the same shape is also handy for any other UI that needs a label for a stored field path.
strstrCheck and validate all values based on spec Returns all the parameters including default value if not provided
raises MissingConfigsException: If one or more mandatory params where not provided it raises a MissingConfigsException
dictdictdictReturn paths of every missing mandatory field, recursing into ParamSet rows.
Path format uses human_name (with spec key as fallback):
- top-level scalar:
Mass - ParamSet row field:
Samples[0].Mass(0-based row index)
Empty list means all mandatories are set. Used by the form save flow to surface a precise list of what is missing on the SUBMITTED gate.
dictliststrParamSpecReturn a copy of the specs dictionary.
Useful for unpacking specs into a new ConfigSpecs, e.g.: ConfigSpecs({ "my_param": StrParam(...), **other_config_specs.get_specs_as_dict(), })
dictstrboolboolCheck if the config has visible specs
boolcheck that all mandatory configs are provided
dictboolMerge the outer-scope computed dict into user_values and return
the union.
Per-row ParamSet computed cells are populated in-place by
compute_values itself, so this only needs to handle outer-scope
keys. The result is the single dict the caller persists.
dictdictdictMerge two ConfigSpecs objects
ConfigSpecsConfigSpecsstrDrop keys whose spec.accepts_user_input is False (currently
ComputedParam). Recurses into ParamSet rows.
Defensive input-side strip: clients must not write to computed keys; the evaluator owns those values.
dictdictconvert the config specs to json
bool - Truedictconvert the config specs to json
bool - TruedictstrParamSpecRun leaf-level ParamSpec.validate(...) on every provided value.
Lenient on two axes:
- missing mandatories DO NOT raise (use
mandatory_values_are_setas a separate gate when required); - per-leaf
ParamSpec.validatefailures are collected into the returnederrorsdict instead of aborting the whole pass. The offending value is dropped from the result so downstream consumers (computed evaluation, persistence) don't see invalid data.
Error keys mirror computed errors:
"<key>"for outer-scope leaves;"<paramset>[<row_index>].<inner>"for ParamSet rows (row index included because a range failure is per-row data, unlike computed errors which apply uniformly across rows).
For ParamSets, ParamSet.validate_lenient mints __item_id per
row and the result carries it back. Callers that want the old
raise-on-error contract should use :meth:validate_values_or_raise.
dictValidateValuesResultRaise-on-error wrapper around :meth:validate_values.
Aggregates every leaf-validation failure into a single
BadRequestException (rather than the old fail-fast behavior where
the first invalid field aborted). Use from non-form callers that want
the legacy raising contract; the form pipeline uses validate_values
directly so it can render per-field diagnostics.
dictdictCreate a config specs from a dto
dictConfigSpecsCreate a config specs from a json
dictConfigSpecsDiff a single non-ParamSet value into 0 or 1 ConfigChangeEntry.
Public so ParamSet.diff_values can reuse it for inner-field diffing.
strAnyAnyboolboollistRecursive diff producing one ConfigChangeEntry per leaf change.
Field-path shape:
- top-level scalar:
mass - ParamSet item field:
samples[item_id=<uuid>].mass - whole item add/remove:
samples[item_id=<uuid>]
Reorder = REMOVED + ADDED for the same __item_id. Pure reorders
(no inner field changes) produce no entries. Workflow-level events
like form status transitions are appended by the caller.
ParamSet diffing is delegated to ParamSet.diff_values (it owns the
per-row identity model). This entry point only handles dispatch.
dict[str, typing.Any] | Nonedict[str, typing.Any] | Nonelist