Skip to main content
Class for creating numeric input parameter widgets that allow users to enter a single numeric value. This class can be imported from the squirrels.parameters or the squirrels module.

Factory methods

Factory methods are class methods that create and configure parameter instances. These methods are typically used in the pyconfigs/parameters.py file to create the parameter configurations (which describes the “shape” of the parameter but does not include the realtime user selections).

create_simple()

Decorator for creating a simple numeric parameter that doesn’t involve user attributes or parent parameters. The body of the decorated function does not need to return anything (i.e., it can simply be pass).
@classmethod
def create_simple(
    cls, name: str, label: str, min_value: decimal.Decimal | int | float | str, 
    max_value: decimal.Decimal | int | float | str,
    *, description: str = "", increment: decimal.Decimal | int | float | str = 1, 
    default_value: decimal.Decimal | int | float | str | None = None
) -> Callable:

create_with_options()

Decorator for creating a parameter with options that can vary based on user attributes or parent parameter selections. The decorated function must return a list of NumberParameterOption objects.
@classmethod
def create_with_options(
    cls, name: str, label: str, 
    *, description: str = "", user_attribute: str | None = None, 
    parent_name: str | None = None
) -> Callable:

create_from_source()

Decorator for creating a parameter populated from a database table or query using a NumberDataSource. The decorated function must return a NumberDataSource object.
@classmethod
def create_from_source(
    cls, name: str, label: str, 
    *, description: str = "", user_attribute: str | None = None, 
    parent_name: str | None = None
) -> Callable:

Instance methods

Instance methods are available on parameter instances at query time (in context.py or data models) to retrieve selected values.

get_selected_value()

Gets the selected numeric value as a float.
def get_selected_value(self) -> float:
returns
float
The selected numeric value converted from Decimal to float.

is_enabled()

Returns True if the parameter has a valid option after applying user attribute and parent parameter selections, False otherwise.
def is_enabled(self) -> bool:
returns
bool
True if the parameter has a valid option, False otherwise.

Examples for factory methods

All examples below are defined in the pyconfigs/parameters.py file.

Using create_simple for basic numeric input

For parameters that only need a single set of constraints, use create_simple. The numeric parameters are passed directly to the decorator.
from squirrels import parameters as p

@p.NumberParameter.create_simple(
    name="threshold", 
    label="Threshold Value",
    min_value=0,
    max_value=1000,
    increment=10,
    default_value=100,
    description="Enter threshold value"
)
def threshold_default():
    pass

Number parameter with decimal precision

This example uses decimal values for precise numeric input. Regardless of whether Decimal, float, or string values are used, the exact precision will always be maintained (without floating point errors).
from squirrels import parameters as p
from decimal import Decimal

@p.NumberParameter.create_simple(
    name="price_multiplier", 
    label="Price Multiplier",
    min_value="0.1",
    max_value="2.0",
    increment=0.1,
    default_value=Decimal("1.2"),
    description="Enter price multiplier (0.1 to 2.0)"
)
def price_multiplier_default():
    pass

Cascading number parameters

This example shows how numeric constraints can vary based on a parent parameter selection.
from squirrels import parameters as p, parameter_options as po

# Parent parameter
@p.SingleSelectParameter.create_with_options(
    name="product_type", 
    label="Product Type",
    description="Select product type"
)
def product_type_options():
    return [
        po.SelectParameterOption(id="small", label="Small Items"),
        po.SelectParameterOption(id="large", label="Large Items"),
    ]

# Child number parameter with varying constraints
@p.NumberParameter.create_with_options(
    name="order_quantity", 
    label="Order Quantity",
    description="Enter quantity based on product type",
    parent_name="product_type"
)
def order_quantity_options():
    return [
        po.NumberParameterOption(
            default_value=10,
            min_value=1,
            max_value=100,
            increment=1,
            parent_option_ids="small"
        ),
        po.NumberParameterOption(
            default_value=5,
            min_value=1,
            max_value=20,
            increment=1,
            parent_option_ids="large"
        ),
    ]

User-specific numeric constraints

This example provides different numeric constraints based on user access levels.
from squirrels import parameters as p, parameter_options as po

@p.NumberParameter.create_with_options(
    name="budget_limit", 
    label="Budget Limit",
    description="Set budget limit based on your access level",
    user_attribute="access_level"
)
def budget_limit_options():
    return [
        po.NumberParameterOption(
            default_value=1000,
            min_value=0,
            max_value=5000,
            increment=100,
            user_groups=["member", "guest"]
        ),
        po.NumberParameterOption(
            default_value=5000,
            min_value=0,
            max_value=50000,
            increment=1000,
            user_groups=["admin"]
        ),
    ]

Number parameter from database source

This example populates numeric constraints from a database query.
from squirrels import parameters as p, data_sources as ds

@p.NumberParameter.create_from_source(
    name="inventory_quantity", 
    label="Inventory Quantity",
    description="Enter quantity (based on current inventory)"
)
def inventory_quantity_source() -> ds.NumberDataSource:
    return ds.NumberDataSource(
        table_or_query="""
            SELECT 
                AVG(quantity) AS default_value,
                MIN(quantity) AS min_value,
                MAX(quantity) AS max_value,
                1 AS increment
            FROM inventory
        """,
        default_value_col="default_value",
        min_value_col="min_value",
        max_value_col="max_value",
        increment_col="increment"
    )

Cascading number from database source

This example shows a number parameter whose constraints come from a database and depend on a parent parameter.
from squirrels import parameters as p, data_sources as ds

# Parent parameter for projects
@p.SingleSelectParameter.create_from_source(
    name="department_id", 
    label="Department",
    description="Select a department"
)
def department_source():
    return ds.SelectDataSource(
        table_or_query="departments",
        id_col="department_id",
        options_col="department_name"
    )

@p.NumberParameter.create_from_source(
    name="allocation_amount", 
    label="Allocation Amount",
    description="Enter allocation amount for the selected department",
    parent_name="department_id"
)
def allocation_amount_source():
    return ds.NumberDataSource(
        table_or_query="""
            SELECT 
                department_id,
                budget_default AS default_value,
                budget_min AS min_value,
                budget_max AS max_value,
                100 AS increment
            FROM department_budgets
        """,
        default_value_col="default_value",
        min_value_col="min_value",
        max_value_col="max_value",
        increment_col="increment",
        parent_id_col="department_id"
    )

Examples for instance methods

Once parameters are configured, you can use instance methods in your models to access the selected values. The parameter instances are available through the context object (e.g., sqrl.prms).

Basic usage in context.py

from squirrels import ContextArgs

def main(ctx: dict[str, Any], sqrl: ContextArgs) -> None:
    if sqrl.param_exists("threshold"):
        threshold_param = sqrl.prms["threshold"]
        assert isinstance(threshold_param, p.NumberParameter)
        ctx["threshold_value"] = threshold_param.get_selected_value()

Basic usage in Jinja SQL models

The following example works but is not recommended. See tip below for why.
-- models/federates/filtered_data.sql
SELECT *
FROM products
WHERE price >= {{ prms["threshold"].get_selected_value() }}
It is generally better to only use the instance methods in context.py to transform parameter selections into context variables. Using the instance methods directly in the data models is not recommended.IDEs can provide code suggestions for the available instance methods in Python instead of having to memorize which method (such as get_selected_value) is available to use for NumberParameter objects.

Using numeric values in calculations

# In context.py
def main(ctx: dict[str, Any], sqrl: ContextArgs) -> None:
    if sqrl.param_exists("price_multiplier"):
        multiplier_param = sqrl.prms["price_multiplier"]
        assert isinstance(multiplier_param, p.NumberParameter)
        
        multiplier = multiplier_param.get_selected_value()
        ctx["adjusted_price"] = 100 * multiplier
        ctx["discount_percentage"] = (1 - multiplier) * 100