Skip to content

user_input

user_input #

Procedures that collect data directly from users via UI elements.

Procedures that present user interface elements to collect data directly from users. All user input procedures require user interaction and pause workflow execution until the user provides the requested input.

Example
import capturegraph as cg


class Survey(cg.Struct):
    notes: cg.String
    satisfied: cg.Bool


class Daily(cg.Struct):
    sessions: cg.Map[cg.Date, Survey]


@cg.procedure(Daily)
def daily_survey(root: cg.Procedure[cg.Path[Daily]]):
    session = root.sessions[cg.CaptureTime()]
    session.notes &= cg.UserInputString(label="How are you feeling today?")
    session.satisfied &= cg.UserInputBool(
        label="Are you satisfied?",
        true_text="Yes",
        false_text="No",
    )

ShowInstructions #

Bases: Procedure[Bool]

Display instructions to the user and wait for acknowledgement.

Shows instruction text with an optional image to guide the user through a capture workflow. Returns True when the user acknowledges they have read and understood the instructions. Useful for collaborative capture scenarios where users need clear guidance before proceeding.

Attributes:

Name Type Description
text Input[String]

The instruction text to display to the user.

image Input[Image]

Optional image procedure to display alongside the instructions (defaults to a null image).

Note

The default image is built per instance (each gets its own NullProcedure node) and lazily, at construction time, so it is created inside the recording context rather than at module import.

Source code in capturegraph-lib/capturegraph/procedures/nodes/collection/user_input.py
@make_procedure
class ShowInstructions(Procedure[Bool]):
    """Display instructions to the user and wait for acknowledgement.

    Shows instruction text with an optional image to guide the user through
    a capture workflow. Returns True when the user acknowledges they have
    read and understood the instructions. Useful for collaborative capture
    scenarios where users need clear guidance before proceeding.

    Attributes:
        text: The instruction text to display to the user.
        image: Optional image procedure to display alongside the
            instructions (defaults to a null image).

    Note:
        The default ``image`` is built per instance (each gets its own
        ``NullProcedure`` node) and lazily, at construction time, so it is created
        inside the recording context rather than at module import.
    """

    text: Input[String]
    image: Input[Image] = field(
        default_factory=lambda: NullProcedure(output_type=Image),
    )

ShowLocationGuide #

Bases: Procedure[Location]

Guide the user to a target location and record where they arrived.

Displays the user's current location and the target. The user must confirm arrival explicitly (the confirmation arms once within threshold_meters), and the location they confirm is returned — typically more accurate than the author-specified target, especially when captured with ARKit precision. Unlike ShowInstructions, this saves no acknowledgement state; arrival is the confirmed location.

Attributes:

Name Type Description
target Input[Location]

The target location to guide the user to.

threshold_meters Input[Number]

Distance in meters within which the user may confirm arrival (default: 25.0).

Source code in capturegraph-lib/capturegraph/procedures/nodes/collection/user_input.py
@make_procedure
class ShowLocationGuide(Procedure[Location]):
    """Guide the user to a target location and record where they arrived.

    Displays the user's current location and the target. The user must confirm
    arrival explicitly (the confirmation arms once within ``threshold_meters``),
    and the location they confirm is returned — typically more accurate than the
    author-specified ``target``, especially when captured with ARKit precision.
    Unlike ShowInstructions, this saves no acknowledgement state; arrival is the
    confirmed location.

    Attributes:
        target: The target location to guide the user to.
        threshold_meters: Distance in meters within which the user may confirm
            arrival (default: 25.0).
    """

    target: Input[Location]
    threshold_meters: Input[Number] = 25.0

ShowMetronome #

Bases: Procedure[Void]

Display a flashing visual metronome at a specified BPM.

Flashes the screen between white and black at the configured beats per minute. Returns Void immediately (fire-and-forget visual cue). Useful for timing actions like CPR compressions or other rhythmic activities.

The default BPM of 103 matches the tempo of "Staying Alive" by the Bee Gees, which is commonly used for CPR training.

Attributes:

Name Type Description
tempo_bpm Input[Number]

Beats per minute for the flashing rate (default: 103.0).

Example
# Use in a medical protocol to guide CPR compressions
cg.do(cg.ShowMetronome(label="CPR Pace", tempo_bpm=103))

# Slower pace for breathing exercises
cg.do(cg.ShowMetronome(label="Breathing Guide", tempo_bpm=12))
Source code in capturegraph-lib/capturegraph/procedures/nodes/collection/user_input.py
@make_procedure
class ShowMetronome(Procedure[Void]):
    """Display a flashing visual metronome at a specified BPM.

    Flashes the screen between white and black at the configured beats per minute.
    Returns Void immediately (fire-and-forget visual cue). Useful for timing
    actions like CPR compressions or other rhythmic activities.

    The default BPM of 103 matches the tempo of "Staying Alive" by the Bee Gees,
    which is commonly used for CPR training.

    Attributes:
        tempo_bpm: Beats per minute for the flashing rate (default: 103.0).

    Example:
        ```python
        # Use in a medical protocol to guide CPR compressions
        cg.do(cg.ShowMetronome(label="CPR Pace", tempo_bpm=103))

        # Slower pace for breathing exercises
        cg.do(cg.ShowMetronome(label="Breathing Guide", tempo_bpm=12))
        ```
    """

    tempo_bpm: Input[Number] = 103.0

UserInputBool #

Bases: Procedure[Bool]

Prompt the user to select between true/false options.

Displays a boolean choice interface with customizable text for the true and false options. Useful for yes/no questions, feature toggles, or binary decisions in data collection workflows.

Attributes:

Name Type Description
true_text Input[String]

Text to display for the true option (default: "True").

false_text Input[String]

Text to display for the false option (default: "False").

Example
# Cache a user preference once (|= skips if already set)
root.raw_setting |= cg.UserInputBool(
    label="Capture in RAW format?",
    true_text="Yes - RAW",
    false_text="No - HEIC",
)
Source code in capturegraph-lib/capturegraph/procedures/nodes/collection/user_input.py
@make_procedure
class UserInputBool(Procedure[Bool]):
    """Prompt the user to select between true/false options.

    Displays a boolean choice interface with customizable text for
    the true and false options. Useful for yes/no questions, feature
    toggles, or binary decisions in data collection workflows.

    Attributes:
        true_text: Text to display for the true option (default: "True").
        false_text: Text to display for the false option (default: "False").

    Example:
        ```python
        # Cache a user preference once (|= skips if already set)
        root.raw_setting |= cg.UserInputBool(
            label="Capture in RAW format?",
            true_text="Yes - RAW",
            false_text="No - HEIC",
        )
        ```
    """

    true_text: Input[String] = "True"
    false_text: Input[String] = "False"

UserInputChoice #

Bases: Procedure[T]

Prompt the user to pick one case of an Enum type.

The wire carries the enum type in return_type; an executing client resolves that name to its own implementation of the enum and renders the picker from that type's case set — no per-case display text travels (clients prettify the case strings). Typically wrapped in .preload(...) so the option starts pre-answered with a sensible default the user may still adjust.

Attributes:

Name Type Description
output_type Setting[type[T]]

The Enum subclass this procedure returns. Consumed at construction — __post_init__ moves it into the node's return type and resets the field to None, so it is never serialized as a setting (the type is recoverable from return_type).

Example
cg.CaptureVideo(
    format=cg.UserInputChoice(
        output_type=cg.VideoFormat,
        label="Format",
    ).preload(cg.VideoFormat.RESOLUTION),
)
Source code in capturegraph-lib/capturegraph/procedures/nodes/collection/user_input.py
@make_procedure
class UserInputChoice[T: Enum](Procedure[T]):
    """Prompt the user to pick one case of an ``Enum`` type.

    The wire carries the enum type in ``return_type``; an executing client
    resolves that name to its own implementation of the enum and renders the
    picker from that type's case set — no per-case display text travels
    (clients prettify the case strings). Typically wrapped in ``.preload(...)``
    so the option starts pre-answered with a sensible default the user may
    still adjust.

    Attributes:
        output_type: The ``Enum`` subclass this procedure returns. Consumed at
            construction — ``__post_init__`` moves it into the node's return
            type and resets the field to ``None``, so it is never serialized
            as a setting (the type is recoverable from ``return_type``).

    Example:
        ```python
        cg.CaptureVideo(
            format=cg.UserInputChoice(
                output_type=cg.VideoFormat,
                label="Format",
            ).preload(cg.VideoFormat.RESOLUTION),
        )
        ```
    """

    output_type: Setting[type[T]]

    def __post_init__(self) -> None:
        """Consume ``output_type`` into ``_return_type`` and clear the setting."""
        if not (isinstance(self.output_type, type) and issubclass(self.output_type, Enum)):
            raise TypeError(
                f"UserInputChoice.output_type must be an Enum subclass, got {self.output_type!r}"
            )
        object.__setattr__(self, "_return_type", self.output_type)
        object.__setattr__(self, "output_type", None)
        super().__post_init__()

__post_init__() #

Consume output_type into _return_type and clear the setting.

Source code in capturegraph-lib/capturegraph/procedures/nodes/collection/user_input.py
def __post_init__(self) -> None:
    """Consume ``output_type`` into ``_return_type`` and clear the setting."""
    if not (isinstance(self.output_type, type) and issubclass(self.output_type, Enum)):
        raise TypeError(
            f"UserInputChoice.output_type must be an Enum subclass, got {self.output_type!r}"
        )
    object.__setattr__(self, "_return_type", self.output_type)
    object.__setattr__(self, "output_type", None)
    super().__post_init__()

UserInputElapsedTime #

Bases: Procedure[Number]

Record how long something takes with a stopwatch interface.

Displays a stopwatch with start/stop controls. The user can start timing, stop when the action is complete, and submit the recorded duration. Returns the elapsed time as a number in seconds.

Useful for timing procedures, measuring reaction times, or recording the duration of observations in data collection workflows.

Example
# Record how long a task takes
session.task_duration &= cg.UserInputElapsedTime(label="Time the procedure")

# Measure reaction time
session.reaction_time &= cg.UserInputElapsedTime(label="Press stop when you see the signal")
Source code in capturegraph-lib/capturegraph/procedures/nodes/collection/user_input.py
@make_procedure
class UserInputElapsedTime(Procedure[Number]):
    """Record how long something takes with a stopwatch interface.

    Displays a stopwatch with start/stop controls. The user can start
    timing, stop when the action is complete, and submit the recorded
    duration. Returns the elapsed time as a number in seconds.

    Useful for timing procedures, measuring reaction times, or recording
    the duration of observations in data collection workflows.

    Example:
        ```python
        # Record how long a task takes
        session.task_duration &= cg.UserInputElapsedTime(label="Time the procedure")

        # Measure reaction time
        session.reaction_time &= cg.UserInputElapsedTime(label="Press stop when you see the signal")
        ```
    """

UserInputLocation #

Bases: Procedure[Location]

Prompt the user to select or input a location.

Displays a location picker interface that may use maps, GPS, or manual coordinate entry. Users can specify geographic locations for data collection or analysis.

Source code in capturegraph-lib/capturegraph/procedures/nodes/collection/user_input.py
@make_procedure
class UserInputLocation(Procedure[Location]):
    """Prompt the user to select or input a location.

    Displays a location picker interface that may use maps, GPS,
    or manual coordinate entry. Users can specify geographic
    locations for data collection or analysis.
    """

UserInputLocationSequence #

Bases: Procedure[Array[Location]]

Prompt the user to select an ordered sequence of locations.

Displays a map where the user can add points by picking them on the map or by using their current location. Useful for tracing an area boundary (e.g., the bounds of a survey region) without relying on possibly outdated map imagery.

Example
# Capture survey bounds once on first execution (|= skips if present)
root.bounds |= cg.UserInputLocationSequence(label="Walk the survey boundary")
Source code in capturegraph-lib/capturegraph/procedures/nodes/collection/user_input.py
@make_procedure
class UserInputLocationSequence(Procedure[Array[Location]]):
    """Prompt the user to select an ordered sequence of locations.

    Displays a map where the user can add points by picking them on the
    map or by using their current location. Useful for tracing an area
    boundary (e.g., the bounds of a survey region) without relying on
    possibly outdated map imagery.

    Example:
        ```python
        # Capture survey bounds once on first execution (|= skips if present)
        root.bounds |= cg.UserInputLocationSequence(label="Walk the survey boundary")
        ```
    """

UserInputNumber #

Bases: Procedure[Number]

Prompt the user to enter a numeric value.

Displays a number input interface with optional constraints for minimum/maximum values and step increments.

Attributes:

Name Type Description
min_value Input[Number]

Minimum allowed value (optional).

max_value Input[Number]

Maximum allowed value (optional).

step Input[Number]

Increment step for number picker (optional).

Example
# Collect a temperature reading with constraints
session.temperature &= cg.UserInputNumber(
    label="Temperature (°F)",
    min_value=32.0,
    max_value=120.0,
    step=0.5,
)
Source code in capturegraph-lib/capturegraph/procedures/nodes/collection/user_input.py
@make_procedure
class UserInputNumber(Procedure[Number]):
    """Prompt the user to enter a numeric value.

    Displays a number input interface with optional constraints for
    minimum/maximum values and step increments.

    Attributes:
        min_value: Minimum allowed value (optional).
        max_value: Maximum allowed value (optional).
        step: Increment step for number picker (optional).

    Example:
        ```python
        # Collect a temperature reading with constraints
        session.temperature &= cg.UserInputNumber(
            label="Temperature (°F)",
            min_value=32.0,
            max_value=120.0,
            step=0.5,
        )
        ```
    """

    # Always-present, deterministic defaults (no optional inputs on the wire):
    # an empty range (max <= min) means unbounded, a zero step means free entry.
    min_value: Input[Number] = 0.0
    max_value: Input[Number] = 0.0
    step: Input[Number] = 0.0

UserInputRating #

Bases: Procedure[Number]

Prompt the user to select a star rating.

Displays an interactive star rating interface with max_stars stars. Returns the selected rating as a number from 1 to max_stars. Useful for quality assessments, ratings, or any scale-based input.

Attributes:

Name Type Description
max_stars Input[Number]

Maximum number of stars (default: 5).

bad_text Input[String]

Optional adjective shown on the left side (low rating), e.g., "Bad".

good_text Input[String]

Optional adjective shown on the right side (high rating), e.g., "Good".

Source code in capturegraph-lib/capturegraph/procedures/nodes/collection/user_input.py
@make_procedure
class UserInputRating(Procedure[Number]):
    """Prompt the user to select a star rating.

    Displays an interactive star rating interface with ``max_stars`` stars.
    Returns the selected rating as a number from 1 to ``max_stars``. Useful
    for quality assessments, ratings, or any scale-based input.

    Attributes:
        max_stars: Maximum number of stars (default: 5).
        bad_text: Optional adjective shown on the left side (low rating),
            e.g., "Bad".
        good_text: Optional adjective shown on the right side (high rating),
            e.g., "Good".
    """

    max_stars: Input[Number] = 5
    # Always present (no optional inputs on the wire): an empty label is hidden.
    bad_text: Input[String] = ""
    good_text: Input[String] = ""

UserInputSelectString #

Bases: Procedure[String]

Prompt the user to select from a list of predefined text options.

Displays a dropdown or selection interface with customizable options. Useful for collecting specific values like categories, tags, or other predefined text inputs.

Attributes:

Name Type Description
options Setting[list[str]]

The string options the user can choose from.

Source code in capturegraph-lib/capturegraph/procedures/nodes/collection/user_input.py
@make_procedure
class UserInputSelectString(Procedure[String]):
    """Prompt the user to select from a list of predefined text options.

    Displays a dropdown or selection interface with customizable options.
    Useful for collecting specific values like categories, tags, or
    other predefined text inputs.

    Attributes:
        options: The string options the user can choose from.
    """

    options: Setting[list[str]]

UserInputString #

Bases: Procedure[String]

Prompt the user to enter free-form text.

Displays a text input field where users can type free-form text. Useful for collecting names, descriptions, notes, or any other textual data during the procedure execution.

Example
session.notes &= cg.UserInputString(label="Observations")
Source code in capturegraph-lib/capturegraph/procedures/nodes/collection/user_input.py
@make_procedure
class UserInputString(Procedure[String]):
    """Prompt the user to enter free-form text.

    Displays a text input field where users can type free-form text.
    Useful for collecting names, descriptions, notes, or any other
    textual data during the procedure execution.

    Example:
        ```python
        session.notes &= cg.UserInputString(label="Observations")
        ```
    """

UserInputTime #

Bases: Procedure[Time]

Prompt the user to select a specific date and time.

Displays a date/time picker interface for selecting timestamps. Can be configured to round selections to day boundaries for simplified date-only input.

Attributes:

Name Type Description
round_to_days Input[Bool]

Whether to round the selection to day boundaries (default: False).

Source code in capturegraph-lib/capturegraph/procedures/nodes/collection/user_input.py
@make_procedure
class UserInputTime(Procedure[Time]):
    """Prompt the user to select a specific date and time.

    Displays a date/time picker interface for selecting timestamps.
    Can be configured to round selections to day boundaries for
    simplified date-only input.

    Attributes:
        round_to_days: Whether to round the selection to day boundaries
            (default: False).
    """

    round_to_days: Input[Bool] = False

UserInputTimeInterval #

Bases: Procedure[Number]

Prompt the user to enter a time duration or interval.

Displays an interface for selecting time durations (e.g., "2 hours", "30 minutes"). Returns the interval as a number in seconds.

Attributes:

Name Type Description
round_to_days Input[Bool]

Whether to round the interval to day boundaries (default: False).

Source code in capturegraph-lib/capturegraph/procedures/nodes/collection/user_input.py
@make_procedure
class UserInputTimeInterval(Procedure[Number]):
    """Prompt the user to enter a time duration or interval.

    Displays an interface for selecting time durations (e.g., "2 hours",
    "30 minutes"). Returns the interval as a number in seconds.

    Attributes:
        round_to_days: Whether to round the interval to day boundaries (default: False).
    """

    round_to_days: Input[Bool] = False

UserInputTimeOfDay #

Bases: Procedure[Number]

Prompt the user to select a time of day (hours and minutes only).

Displays a time picker for selecting the time portion only, without date information. Returns the time as seconds since midnight (0-86399).

Source code in capturegraph-lib/capturegraph/procedures/nodes/collection/user_input.py
@make_procedure
class UserInputTimeOfDay(Procedure[Number]):
    """Prompt the user to select a time of day (hours and minutes only).

    Displays a time picker for selecting the time portion only,
    without date information. Returns the time as seconds since
    midnight (0-86399).
    """