Tree — Filters, Controls, Parameters¶
FilterGroup wraps one filter (typed CategoryFilter /
NumericRangeFilter / TimeRangeFilter) and its scope (sheet-wide,
visual-pinned, or all-sheets). FilterControl and ParameterControl
variants surface the filter / parameter to the analyst as a UI widget
on a sheet.
ParameterDecl subtypes (StringParameter / IntegerParameter /
DecimalParameter / DatetimeParameter) declare an analysis-level
parameter that filters can read from and drills can write to.
filters ¶
Filter primitives — typed Filter wrappers + FilterGroup.
Filter groups carry their scope as object refs (Sheet + [VisualLike])
and validate at the call site that scoped visuals belong to the
referenced sheet. Catches the wrong-sheet bug class — the type
checker carries the wiring; raise at construction confirms.
Typed Filter wrappers (CategoryFilter / NumericRangeFilter /
TimeRangeFilter) sit alongside the FilterGroup. They share names
with the underlying models.py classes — models are aliased on
import so user-facing code reads cleanly:
from quicksight_gen.common.tree import CategoryFilter, FilterGroup
The NumericRangeFilter's minimum_parameter /
maximum_parameter fields take a ParameterDeclLike object ref —
the type checker catches "filter bound to undeclared parameter" at
the wiring site, where the existing string-keyed Parameter=name
pattern lets typos through to deploy.
CategoryMatchOperator
module-attribute
¶
CategoryMatchOperator = Literal['CONTAINS', 'EQUALS', 'DOES_NOT_EQUAL', 'STARTS_WITH']
DefaultControl
module-attribute
¶
DefaultControl = DefaultDateTimePickerControl | DefaultDropdownControl | DefaultSliderControl
CategoryBinding
module-attribute
¶
CategoryBinding = _ValuesBinding | _ParameterBinding | _LiteralBinding
FilterLike ¶
Bases: Protocol
Structural type for tree-level filter nodes.
Each typed wrapper (CategoryFilter / NumericRangeFilter /
TimeRangeFilter) satisfies this Protocol — exposes a
filter_id, the underlying dataset (object ref), and emits
a models.Filter. The dataset field participates in the
L.1.7 dependency-graph walk.
filter_id is str | None because typed wrappers default to
None and let App._resolve_auto_ids fill it. calc_field()
returns the CalcField the filter references (or None if it points
at a real column) — used by the dependency-graph walk and by
FilterControl wrappers that need the filter_id post-resolve.
DefaultDateTimePickerControl
dataclass
¶
DefaultDropdownControl
dataclass
¶
Inline default widget config for CategoryFilter (or any
list/parameter-driven filter).
DefaultSliderControl
dataclass
¶
Inline default widget config for NumericRangeFilter.
__init__ ¶
__init__(title: str, minimum_value: float, maximum_value: float, step_size: float, type: Literal['SINGLE_POINT', 'RANGE'] = 'SINGLE_POINT') -> None
CategoryFilter
dataclass
¶
Filter on a categorical (string) column or calc field.
dataset is a Dataset object ref (L.1.7 hard switch).
column may name a real dataset column or an analysis-level
calc field — both resolve to a ColumnIdentifier against the
given dataset.
Construct via the factory methods (L.1.22 — the discriminated binding makes the "neither/both set" bug class structurally impossible):
CategoryFilter.with_values(dataset, column, values, ...)— static list. EmitsFilterListConfigurationwithCategoryValues. Use for the calc-field'yes'sentinel pattern or a hardcoded include-list.CategoryFilter.with_parameter(dataset, column, parameter, ...)— parameter-bound. EmitsCustomFilterConfigurationwithParameterNamefrom the param ref. Use when a dropdown writes a single value into a string parameter and the filter narrows to it (e.g. Money Trail's chain root selector).
null_option only surfaces in the parameter-bound emit (the
list-based FilterListConfiguration doesn't carry it).
match_operator
class-attribute
instance-attribute
¶
match_operator: CategoryMatchOperator = 'CONTAINS'
default_control
class-attribute
instance-attribute
¶
default_control: DefaultDropdownControl | None = None
__init__ ¶
__init__(dataset: Dataset, column: ColumnRef, binding: CategoryBinding, match_operator: CategoryMatchOperator = 'CONTAINS', null_option: NullOption = 'ALL_VALUES', default_control: DefaultDropdownControl | None = None, filter_id: str | AutoResolved = AUTO) -> None
with_values
classmethod
¶
with_values(*, dataset: Dataset, column: ColumnRef, values: list[str], match_operator: CategoryMatchOperator = 'CONTAINS', null_option: NullOption = 'ALL_VALUES', select_all_options: SelectAllOptions | None = None, default_control: DefaultDropdownControl | None = None, filter_id: str | AutoResolved = AUTO) -> 'CategoryFilter'
Static-list category filter — CategoryValues is the literal
list of allowed values. Pass values=[] plus
select_all_options="FILTER_ALL_VALUES" for the
multi-select-with-all-default pattern: an empty values list
means "every distinct column value is selected at runtime".
with_parameter
classmethod
¶
with_parameter(*, dataset: Dataset, column: ColumnRef, parameter: ParameterDeclLike, match_operator: CategoryMatchOperator = 'EQUALS', null_option: NullOption = 'ALL_VALUES', default_control: DefaultDropdownControl | None = None, filter_id: str | AutoResolved = AUTO) -> 'CategoryFilter'
Parameter-bound category filter — ParameterName is read
from the parameter ref at emit time. Default match_operator
is EQUALS since dropdown-driven parameters typically write a
single value.
with_literal
classmethod
¶
with_literal(*, dataset: Dataset, column: ColumnRef, value: str, match_operator: CategoryMatchOperator = 'EQUALS', null_option: NullOption = 'NON_NULLS_ONLY', default_control: DefaultDropdownControl | None = None, filter_id: str | AutoResolved = AUTO) -> 'CategoryFilter'
Single-literal exact-match category filter — emits
CustomFilterConfiguration with a literal CategoryValue.
The list-based FilterListConfiguration rejects EQUALS at the
API (only CONTAINS / DOES_NOT_CONTAIN), so this is the only
shape that supports an exact-equality test against a single
value. Used for the K.2 calc-field PASS pattern: a calc field
returns "PASS" and the filter requires equality against
that literal.
StaticBound
dataclass
¶
ParameterBound
dataclass
¶
A parameter-driven bound — emits Parameter (resolved from
parameter.name) in the range filter.
NumericRangeFilter
dataclass
¶
Filter on a numeric column. Range bounds are typed Bound
variants — StaticBound(value) for a literal, ParameterBound(
parameter) for a parameter-driven bound. The parameter-binding
object ref catches "bound to a parameter that doesn't exist" at
the wiring site (the type checker resolves param.name).
L.1.22 — the discriminated Bound union makes the "both
static_value and parameter set" bug class structurally impossible:
a StaticBound carries a value but no parameter, and a
ParameterBound carries a parameter but no value. Each side
(min / max) is at most one Bound.
default_control
class-attribute
instance-attribute
¶
default_control: DefaultSliderControl | None = None
minimum_parameter
property
¶
minimum_parameter: ParameterDeclLike | None
The parameter ref the minimum bound is bound to, or None. Used by the parameter-references validator walk.
maximum_parameter
property
¶
maximum_parameter: ParameterDeclLike | None
The parameter ref the maximum bound is bound to, or None.
__init__ ¶
__init__(dataset: Dataset, column: ColumnRef, minimum: Bound | None = None, maximum: Bound | None = None, null_option: NullOption = 'NON_NULLS_ONLY', include_minimum: bool | None = None, include_maximum: bool | None = None, default_control: DefaultSliderControl | None = None, filter_id: str | AutoResolved = AUTO) -> None
TimeRangeFilter
dataclass
¶
Filter on a date / datetime column.
dataset is a Dataset object ref (L.1.7 hard switch).
column is a ColumnRef — a real column or a CalcField.
minimum and maximum are passthrough dicts for now (the
existing usage takes a variety of shapes — RollingDate, StaticValue,
Parameter — and lifting all of them under typed wrappers can wait
for the L.2/L.3/L.4 ports to surface concrete needs).
time_granularity
class-attribute
instance-attribute
¶
time_granularity: TimeGranularity | None = None
default_control
class-attribute
instance-attribute
¶
default_control: DefaultDateTimePickerControl | None = None
__init__ ¶
__init__(dataset: Dataset, column: ColumnRef, minimum: dict[str, Any] | None = None, maximum: dict[str, Any] | None = None, null_option: NullOption = 'NON_NULLS_ONLY', time_granularity: TimeGranularity | None = None, include_minimum: bool | None = None, include_maximum: bool | None = None, default_control: DefaultDateTimePickerControl | None = None, filter_id: str | AutoResolved = AUTO) -> None
TimeEqualityFilter
dataclass
¶
Single-day equality filter on a date column.
Used when paired with a SINGLE_VALUED date picker control —
TimeRangeFilter renders broken in the QS UI when paired with
a single-day picker; TimeEqualityFilter is the right shape
for "show rows where the date column equals one specific day".
parameter (a typed DateTimeParam ref) is the only binding
mode currently exposed (the AR Daily Statement use case). Extend
with rolling_date / static_value factories when other apps
need them.
time_granularity
class-attribute
instance-attribute
¶
time_granularity: TimeGranularity | None = None
default_control
class-attribute
instance-attribute
¶
default_control: DefaultDateTimePickerControl | None = None
__init__ ¶
__init__(dataset: Dataset, column: ColumnRef, parameter: ParameterDeclLike, time_granularity: TimeGranularity | None = None, default_control: DefaultDateTimePickerControl | None = None, filter_id: str | AutoResolved = AUTO) -> None
FilterGroup
dataclass
¶
Tree node for one analysis-level filter group.
Construct with FilterGroup(filter_group_id=..., filters=[...]),
then attach scope by chaining .scope_visuals(sheet, [v1, v2])
or .scope_sheet(sheet). Both call methods validate immediately:
scope_visualsraises if any visual isn't on the given sheet (catches the wrong-sheet bug at the call site).scope_sheetis the all-visuals-on-sheet shortcut.
Multiple scope entries are allowed — the same FilterGroup can
apply to (visual subset on sheet A) plus (all visuals on sheet B).
Each entry emits its own SheetVisualScopingConfiguration.
filters takes a list of typed FilterLike wrappers
(CategoryFilter / NumericRangeFilter / TimeRangeFilter
above). Each wrapper's emit() returns a models.Filter at
emission time. Parameter-bound filters (NumericRangeFilter with
minimum_parameter / maximum_parameter) carry object refs
to ParameterDeclLike nodes — the type checker catches
"filter bound to undeclared parameter" at the wiring site.
filter_group_id is optional (L.1.8.5 auto-ID). When omitted,
the App's tree walker assigns fg-{n} at emit time based on
the FilterGroup's index in the analysis's filter group list.
cross_dataset
class-attribute
instance-attribute
¶
cross_dataset: Literal['SINGLE_DATASET', 'ALL_DATASETS'] = 'SINGLE_DATASET'
filter_group_id
class-attribute
instance-attribute
¶
filter_group_id: FilterGroupId | AutoResolved = AUTO
__init__ ¶
__init__(filters: list[FilterLike], cross_dataset: Literal['SINGLE_DATASET', 'ALL_DATASETS'] = 'SINGLE_DATASET', enabled: bool = True, filter_group_id: FilterGroupId | AutoResolved = AUTO) -> None
scope_visuals ¶
scope_visuals(sheet: 'Sheet', visuals: list[VisualLike]) -> FilterGroup
Scope this filter to specific visuals on a sheet.
Construction-time check: every visual must already be registered
on the given sheet via sheet.add_visual(). Cross-sheet
wiring is the bug class this catches — without the check, a
scope mixing visuals from sheet A with sheet B's identifier
emits a SheetVisualScopingConfiguration that silently drops
the off-sheet visual at deploy time.
scope_sheet ¶
scope_sheet(sheet: 'Sheet') -> FilterGroup
Scope this filter to ALL visuals on a sheet.
Equivalent to the existing _selected_sheets_scope([sheet_id])
helper — emits Scope=ALL_VISUALS on the sheet's
SheetVisualScopingConfiguration, no per-visual list.
controls ¶
Typed Filter + Parameter control wrappers (L.1.9).
Each control binds to a typed source by object reference: parameter
controls take a ParameterDeclLike (the parameter declaration node
they read/write); filter controls take a FilterLike (the inner
filter their UI drives). At emit time the wrapper reads
parameter.name or filter.filter_id to populate the underlying
models.SourceParameterName / SourceFilterId.
Naming convention: same as L.1.6 — tree wrappers use a clean,
unsuffixed name that doesn't collide with the underlying
models.*Control classes (Parameter*Control, Filter*Control).
User code reads:
from quicksight_gen.common.tree import (
ParameterDropdown, ParameterSlider, FilterDropdown, ...,
)
LinkedValues / StaticValues typed wrappers replace the
existing dict-shaped SelectableValues argument — LinkedValues
takes a typed Dataset ref + column name (catches "dropdown
populated from undeclared dataset" via the App's dependency graph
walk).
Auto-IDs (L.1.8.5 extension): control_id fields are Optional;
the App walker assigns position-indexed IDs at emit time
(pc-{kind}-s{sheet_idx}-{control_idx} for parameter controls,
fc-{kind}-s{sheet_idx}-{control_idx} for filter controls).
StaticValues
dataclass
¶
LinkedValues
dataclass
¶
Auto-populate the dropdown's options from a dataset column.
Construct via the factory methods (L.1.22 — the canonical fields
are dataset + column_name; the factories normalize the two
legitimate construction forms into that pair, eliminating the
dual-form __post_init__ validation):
LinkedValues.from_column(ds["col"])— typed Column form. The Column carries its own dataset, so the factory derivesdatasetfrom the Column. Preferred — the contract validates the column name at the wiring site.LinkedValues.from_string(dataset=ds, column_name="col")— bare-string escape hatch for datasets without a registeredDatasetContract. Dataset must be passed explicitly.
The Dataset participates in the L.1.7 dependency-graph walk via
the control's datasets() method.
from_column
classmethod
¶
from_column(column: Column) -> 'LinkedValues'
Linked values pulled from a typed Column. The Column's dataset is the source dataset.
ParameterControlLike ¶
Bases: Protocol
Tree-level parameter control nodes.
datasets() participates in the L.1.7 dependency-graph walk —
controls with LinkedValues populate from a Dataset, and
that's a dep. Controls with static values return an empty set.
FilterControlLike ¶
Bases: Protocol
Tree-level filter control nodes.
datasets() participates in the L.1.7 dependency-graph walk —
same shape as ParameterControlLike.datasets().
ParameterDropdown
dataclass
¶
Dropdown control bound to a ParameterDeclLike parameter.
parameter is the typed parameter declaration the control
reads/writes — at emit time, the control's SourceParameterName
becomes parameter.name. The type checker catches "control
bound to a parameter that doesn't exist" at the wiring site.
selectable_values accepts a StaticValues(["a", "b"]) for a
fixed option list or LinkedValues(dataset, column) for an
auto-populated list. The LinkedValues.dataset ref participates
in the App's dependency graph.
hidden_select_all=True suppresses the "Select all" entry —
needed for SINGLE_SELECT dropdowns where empty/All semantics don't
apply (e.g. a Sankey anchor that needs exactly one value).
cascade_source makes this dropdown depend on another dropdown:
when cascade_source changes value, QS refreshes THIS dropdown's
options. Required for cascading filters even when the source
dataset's params are bridged via MappedDataSetParameters —
QS won't refresh the dropdown widget without explicit UI-level
cascade wiring (M.3.10c finding).
type
class-attribute
instance-attribute
¶
type: Literal['SINGLE_SELECT', 'MULTI_SELECT'] = 'SINGLE_SELECT'
cascade_source
class-attribute
instance-attribute
¶
cascade_source: 'ParameterDropdown | None' = None
cascade_match_column
class-attribute
instance-attribute
¶
cascade_match_column: 'Column | None' = None
__init__ ¶
__init__(parameter: ParameterDeclLike, title: str, selectable_values: SelectableValues, type: Literal['SINGLE_SELECT', 'MULTI_SELECT'] = 'SINGLE_SELECT', hidden_select_all: bool = False, cascade_source: 'ParameterDropdown | None' = None, cascade_match_column: 'Column | None' = None, control_id: str | AutoResolved = AUTO) -> None
ParameterSlider
dataclass
¶
Slider control bound to a numeric parameter.
__init__ ¶
__init__(parameter: ParameterDeclLike, title: str, minimum_value: float, maximum_value: float, step_size: float, control_id: str | AutoResolved = AUTO) -> None
ParameterDateTimePicker
dataclass
¶
Date/time picker control bound to a DateTime parameter.
__init__ ¶
__init__(parameter: ParameterDeclLike, title: str, control_id: str | AutoResolved = AUTO) -> None
ParameterTextField
dataclass
¶
Free-text input control bound to a string parameter.
Right shape when the parameter's option universe is unbounded /
unknown at deploy time, or when the LinkedValues / StaticValues
paths are unavailable. The analyst types a value; QS writes it to
the bound parameter verbatim. No sample-values fetch — sidesteps
the X.1.b Sample values not found failure mode entirely.
__init__ ¶
__init__(parameter: ParameterDeclLike, title: str, control_id: str | AutoResolved = AUTO) -> None
FilterDropdown
dataclass
¶
Dropdown control bound to an inner filter (CategoryFilter).
filter is the typed inner filter the dropdown drives — at
emit time, the control's SourceFilterId becomes
filter.filter_id. The filter must be inside a FilterGroup
that's been registered on the analysis.
type
class-attribute
instance-attribute
¶
type: Literal['SINGLE_SELECT', 'MULTI_SELECT'] = 'MULTI_SELECT'
selectable_values
class-attribute
instance-attribute
¶
selectable_values: SelectableValues | None = None
__init__ ¶
__init__(filter: FilterLike, title: str, type: Literal['SINGLE_SELECT', 'MULTI_SELECT'] = 'MULTI_SELECT', selectable_values: SelectableValues | None = None, control_id: str | AutoResolved = AUTO) -> None
FilterSlider
dataclass
¶
Slider control bound to a NumericRangeFilter.
__init__ ¶
__init__(filter: FilterLike, title: str, minimum_value: float, maximum_value: float, step_size: float, type: Literal['SINGLE_POINT', 'RANGE'] = 'RANGE', control_id: str | AutoResolved = AUTO) -> None
FilterDateTimePicker
dataclass
¶
Date/time picker control bound to a TimeRangeFilter.
type
class-attribute
instance-attribute
¶
type: Literal['SINGLE_VALUED', 'DATE_RANGE'] = 'DATE_RANGE'
__init__ ¶
__init__(filter: FilterLike, title: str, type: Literal['SINGLE_VALUED', 'DATE_RANGE'] = 'DATE_RANGE', control_id: str | AutoResolved = AUTO) -> None
FilterCrossSheet
dataclass
¶
Cross-sheet filter control — surfaces the filter on multiple sheets via the same bound filter.
No title; the Cross-Sheet control inherits its UI from the underlying filter's primary control.
parameters ¶
Typed ParameterDecl subtypes — one per models.py declaration variant.
StringParam / IntegerParam / DateTimeParam map to the
three declaration types in models.py. Each carries its own
ParameterName at the constructor (single construction site);
controls and filter parameter bindings reference the parameter by
object ref.
Each variant optionally carries a list of (Dataset, str) tuples in
mapped_dataset_params. Each tuple binds the analysis-level
parameter to a dataset-level parameter declared inside the
referenced Dataset's CustomSql (substituted via <<$paramName>>
at QS query time). Use this to bridge an analysis param into one or
more parameterized datasets — the cascading-filter pattern that
M.3.10c established.
ParameterDeclLike ¶
Bases: Protocol
Structural type for parameter declaration tree nodes.
StringParam
dataclass
¶
String-valued parameter declaration.
Default values are passed as a list — single-valued parameters
use [] for "no default" or ["value"] for one default;
multi-valued use ["a", "b", "c"].
mapped_dataset_params: optional list of (Dataset, name)
pairs binding this analysis parameter to one or more dataset-level
parameters substituted via <<$name>> in the dataset's
CustomSql.
mapped_dataset_params
class-attribute
instance-attribute
¶
mapped_dataset_params: list[DatasetParamMapping] | None = None
__init__ ¶
__init__(name: ParameterName, default: list[str] = list[str](), multi_valued: bool = False, mapped_dataset_params: list[DatasetParamMapping] | None = None) -> None
IntegerParam
dataclass
¶
Integer-valued parameter declaration.
mapped_dataset_params
class-attribute
instance-attribute
¶
mapped_dataset_params: list[DatasetParamMapping] | None = None
__init__ ¶
__init__(name: ParameterName, default: list[int] = list[int](), multi_valued: bool = False, mapped_dataset_params: list[DatasetParamMapping] | None = None) -> None
DateTimeParam
dataclass
¶
DateTime parameter declaration.
Pass time_granularity="DAY" | "HOUR" | "MINUTE" | … to bound
the picker's resolution. default is required —
DateTimeDefaultValues with one of StaticValues / DynamicValue /
RollingDate populated. Common rolling default for "today":
DateTimeDefaultValues(RollingDate={"Expression":
"truncDate('DD', now())"}).
Why default is required (M.4.4.10d): without one, QS UI's date picker initializes with no value and crashes on editor open with "epochMilliseconds must be a number, you gave: null". Making the field type-required prevents the bug class from recurring at the wiring site.
time_granularity
class-attribute
instance-attribute
¶
time_granularity: TimeGranularity | None = None
mapped_dataset_params
class-attribute
instance-attribute
¶
mapped_dataset_params: list[DatasetParamMapping] | None = None
__init__ ¶
__init__(name: ParameterName, default: DateTimeDefaultValues, time_granularity: TimeGranularity | None = None, mapped_dataset_params: list[DatasetParamMapping] | None = None) -> None