# Streams Base

{% hint style="info" %}
This API Reference is based on DeGirum Tools version 1.2.0.
{% endhint %}

## Classes <a href="#classes" id="classes"></a>

## StreamMeta <a href="#streammeta" id="streammeta"></a>

`StreamMeta`

Stream metainfo class (metadata container).

**Overview**

* A [StreamMeta](https://docs.degirum.com/degirum-tools/streams/..#streammeta) instance is a container that holds a chronologically ordered list of metainfo objects (called "meta infos") produced by gizmos in a streaming pipeline.
* Each time a gizmo adds new metadata (e.g., inference results, resizing information), it is *appended* to the tail of this list.
* The gizmo may associate the appended metadata with one or more *tags*, so that downstream gizmos or the user can retrieve specific metadata objects by those tags.

**Appending and Tagging**

* To store new metadata, a gizmo calls `self.meta.append(meta_obj, tags)`, where `meta_obj` is the metadata to attach, and `tags` is a string or list of strings labeling that metadata (e.g., "tag\_inference", "tag\_resize").
* Internally, [StreamMeta](https://docs.degirum.com/degirum-tools/streams/..#streammeta) keeps track of a list of appended objects and a mapping of tags to the indices in that list.

**Retrieving Metadata**

* You can retrieve all metadata objects tagged with a certain tag via `find(tag)`, which returns a list of all matching objects in the order they were appended.
* You can retrieve only the most recently appended object with `find_last(tag)`.
* For example, an inference gizmo might attach an inference result with the tag `"tag_inference"`, so a downstream gizmo can do: `inference_result = stream_data.meta.find_last("tag_inference")`.
* If no metadata matches the requested tag, these methods return `[]` or `None`.

**Modifications and Cloning**

* **Important**: Never modify a received [StreamMeta](https://docs.degirum.com/degirum-tools/streams/..#streammeta) or its stored objects in-place, because it may create side effects for upstream components. Call `clone()` if you need to make changes. `clone()` creates a shallow copy of the metainfo list and a copy of the tag-index map.
* If you want to remove the most recent entry associated with a certain tag, call `remove_last(tag)` (occasionally useful in advanced pipeline scenarios).

**Typical Usage**

A typical processing pipeline might look like

1. A video source gizmo creates a new [StreamMeta](https://docs.degirum.com/degirum-tools/streams/..#streammeta), appends frame info under tag `"Video"`.
2. A resizing gizmo appends new dimension info under tag `"Resize"`.
3. An AI inference gizmo appends the inference result under tag `"Inference"`.
4. A display gizmo reads the final metadata to overlay bounding boxes, etc.

This incremental metadata accumulation is extremely flexible and allows each gizmo to contribute to a unified record of the data's journey.

**Example**:

{% code overflow="wrap" %}

```python
# In a gizmo, produce meta and append:
data.meta.append({"new_width": 640, "new_height": 480}, "Resize")

# In a downstream gizmo:
resize_info = data.meta.find_last("Resize")
if resize_info:
    w, h = resize_info["new_width"], resize_info["new_height"]
```

{% endcode %}

**CAUTION**: Never modify the existing metadata objects in place. If you need to adapt previously stored metadata for your own use, first copy the data structure or call `clone()` on the [StreamMeta](https://docs.degirum.com/degirum-tools/streams/..#streammeta).

### StreamMeta Methods <a href="#streammeta-methods" id="streammeta-methods"></a>

#### \_\_init\_\_(meta=None, ...) <a href="#init" id="init"></a>

`__init__(meta=None, tags=[])`

Constructor.

Parameters:

| Name   | Type                    | Description                                                        | Default |
| ------ | ----------------------- | ------------------------------------------------------------------ | ------- |
| `meta` | `Any`                   | Initial metainfo object. Defaults to None.                         | `None`  |
| `tags` | `Union[str, List[str]]` | Tag or list of tags to associate with the initial metainfo object. | `[]`    |

#### append(meta, ...) <a href="#append" id="append"></a>

`append(meta, tags=[])`

Append a metainfo object to this StreamMeta.

Parameters:

| Name   | Type                    | Description                                                | Default    |
| ------ | ----------------------- | ---------------------------------------------------------- | ---------- |
| `meta` | `Any`                   | The metainfo object to append.                             | *required* |
| `tags` | `Union[str, List[str]]` | Tag or list of tags to associate with the metainfo object. | `[]`       |

#### clone <a href="#clone" id="clone"></a>

`clone()`

Shallow clone this StreamMeta.

This creates a copy of the internal list and tags dictionary, but does not deep-copy the metainfo objects.

Returns:

| Name         | Type         | Description                   |
| ------------ | ------------ | ----------------------------- |
| `StreamMeta` | `StreamMeta` | A cloned StreamMeta instance. |

#### find(tag) <a href="#find" id="find"></a>

`find(tag)`

Find metainfo objects by tag.

Parameters:

| Name  | Type  | Description            | Default    |
| ----- | ----- | ---------------------- | ---------- |
| `tag` | `str` | The tag to search for. | *required* |

Returns:

| Type        | Description                                                                     |
| ----------- | ------------------------------------------------------------------------------- |
| `List[Any]` | List\[Any]: A list of metainfo objects that have the given tag (empty if none). |

#### find\_last(tag) <a href="#find_last" id="find_last"></a>

`find_last(tag)`

Find the last metainfo object with a given tag.

Parameters:

| Name  | Type  | Description            | Default    |
| ----- | ----- | ---------------------- | ---------- |
| `tag` | `str` | The tag to search for. | *required* |

Returns:

| Name  | Type       | Description                                                             |
| ----- | ---------- | ----------------------------------------------------------------------- |
| `Any` | `optional` | The last metainfo object associated with the tag, or None if not found. |

#### get(idx) <a href="#get" id="get"></a>

`get(idx)`

Get a metainfo object by index.

Parameters:

| Name  | Type  | Description                                   | Default    |
| ----- | ----- | --------------------------------------------- | ---------- |
| `idx` | `int` | The index of the metainfo object in the list. | *required* |

Returns:

| Name  | Type  | Description                                 |
| ----- | ----- | ------------------------------------------- |
| `Any` | `Any` | The metainfo object at the specified index. |

#### remove\_last(tag) <a href="#remove_last" id="remove_last"></a>

`remove_last(tag)`

Remove the last metainfo object associated with a tag.

Parameters:

| Name  | Type  | Description                                                      | Default    |
| ----- | ----- | ---------------------------------------------------------------- | ---------- |
| `tag` | `str` | The tag whose last associated metainfo object should be removed. | *required* |

## StreamData <a href="#streamdata" id="streamdata"></a>

`StreamData`

Single data element of the streaming pipeline.

### StreamData Methods <a href="#streamdata-methods" id="streamdata-methods"></a>

#### \_\_init\_\_(data, ...) <a href="#init" id="init"></a>

`__init__(data, meta=StreamMeta())`

Constructor.

Parameters:

| Name   | Type         | Description                                                                | Default        |
| ------ | ------------ | -------------------------------------------------------------------------- | -------------- |
| `data` | `Any`        | The data payload.                                                          | *required*     |
| `meta` | `StreamMeta` | The metainfo associated with the data. Defaults to a new empty StreamMeta. | `StreamMeta()` |

#### append\_meta(meta, ...) <a href="#append_meta" id="append_meta"></a>

`append_meta(meta, tags=[])`

Append an additional metainfo object to this [StreamData](https://docs.degirum.com/degirum-tools/streams/..#streamdata)'s metadata.

Parameters:

| Name   | Type        | Description                                                   | Default    |
| ------ | ----------- | ------------------------------------------------------------- | ---------- |
| `meta` | `Any`       | The metainfo object to append.                                | *required* |
| `tags` | `List[str]` | Tags to associate with this metainfo object. Defaults to \[]. | `[]`       |

## Stream <a href="#stream" id="stream"></a>

`Stream`

Bases: `Queue`

Queue-based iterable stream with optional item drop.

### Stream Methods <a href="#stream-methods" id="stream-methods"></a>

#### \_\_init\_\_(maxsize=0, ...) <a href="#init" id="init"></a>

`__init__(maxsize=0, allow_drop=False)`

Constructor.

Parameters:

| Name         | Type   | Description                                                                                  | Default |
| ------------ | ------ | -------------------------------------------------------------------------------------------- | ------- |
| `maxsize`    | `int`  | Maximum stream depth (queue size); use 0 for unlimited depth. Defaults to 0.                 | `0`     |
| `allow_drop` | `bool` | If True, allow dropping the oldest item when the stream is full on put(). Defaults to False. | `False` |

Raises:

| Type        | Description                                            |
| ----------- | ------------------------------------------------------ |
| `Exception` | If maxsize is non-zero and less than `min_queue_size`. |

#### \_\_iter\_\_ <a href="#iter" id="iter"></a>

`__iter__()`

Return an iterator over the stream's items.

#### close <a href="#close" id="close"></a>

`close()`

Close the stream by inserting a poison pill.

#### put(item, ...) <a href="#put" id="put"></a>

`put(item, block=True, timeout=None)`

Put an item into the stream, with optional dropping.

If the stream is full and `allow_drop` is True, the oldest item will be removed to make room.

Parameters:

| Name      | Type    | Description                                                                                | Default    |
| --------- | ------- | ------------------------------------------------------------------------------------------ | ---------- |
| `item`    | `Any`   | The item to put.                                                                           | *required* |
| `block`   | `bool`  | Whether to block if the stream is full (ignored if dropping is enabled). Defaults to True. | `True`     |
| `timeout` | `float` | Timeout in seconds for the blocking put. Defaults to None (no timeout).                    | `None`     |

## Gizmo <a href="#gizmo" id="gizmo"></a>

`Gizmo`

Base class for all gizmos (streaming pipeline processing blocks).

Each gizmo owns zero or more input streams that deliver data for processing (data-generating gizmos have no input stream).

A gizmo can be connected to other gizmos to receive data from them. One gizmo can broadcast data to multiple others (a single gizmo output feeding multiple destinations).

A data element moving through the pipeline is a tuple `(data, meta)` where:

* `data` is the raw data (e.g., an image, a frame, or any object),
* `meta` is a [StreamMeta](https://docs.degirum.com/degirum-tools/streams/..#streammeta) object containing accumulated metadata.

Subclasses must implement the abstract `run()` method to define a gizmo processing loop. The `run()` method is launched in a separate thread by the [Composition](https://docs.degirum.com/degirum-tools/streams/..#composition) and should run until no more data is available or until an abort signal is set.

The `run()` implementation should:

* Periodically check the `_abort` flag (set via `abort()`) to see if it should terminate.
* Handle poison pills (`Stream._poison`) if they appear in the input streams, which signal "no more data."

Below is a minimal example similar to `ResizingGizmo`. This gizmo simply reads items from its single input, processes them, and sends results downstream until either `_abort` is set or the input stream is exhausted:

{% code overflow="wrap" %}

```python
    def run(self):
        # For a single-input gizmo, iterate over all data in input #0
        for item in self.get_input(0):
            # If we were asked to abort, break out immediately
            if self._abort:
                break

            # item is a StreamData object: item.data is the image/frame, item.meta is the metadata
            input_image = item.data

            # 1) Do the resizing (your logic can use OpenCV, PIL, etc.)
            resized_image = do_resize(input_image, width=640, height=480)
            # 'do_resize' is just a placeholder; you'd implement your own resizing function.

            # 2) Update the metadata
            #    - Clone the existing metadata first.
            #    - In Python all objects are passed by reference, so if you do not clone but try A >> B and A >> C, C will receive the meta object modified by B.
            out_meta = item.meta.clone()
            out_meta.append(
                {
                    "frame_width": 640,
                    "frame_height": 480,
                    "method": "your_resize_method"
                },
                tags=self.get_tags()
            )

            # 3) Send the processed item downstream
            self.send_result(StreamData(resized_image, out_meta))
```

{% endcode %}

Class Variables

key\_gizmo (str): Key name for gizmo name in timing metadata entries. Defaults to "gizmo". key\_timestamp (str): Key name for timestamp in timing metadata entries. Defaults to "timestamp".

Notes

* If your gizmo has multiple inputs, you can call `self.get_input(i)` for each input or iterate over `self.get_inputs()` if you need to merge or synchronize multiple streams.
* Always check `_abort` periodically inside your main loop if your gizmo could run for a long time or block on I/O.
* When done, you do not need to manually send poison pills; the [Composition](https://docs.degirum.com/degirum-tools/streams/..#composition) handles closing any downstream streams once each gizmo `run()` completes.
* If, instead of `self.get_input(0)`, you use `self.get_input(0).get()` or `.get_nowait()`, you must check if you receive a poison pill.
  * In simple loops, `self.get_input(0)` will terminate the loop.
  * In multi-input gizmos where simple nested for-loops aren't usable, get\_nowait() is typically used to read input streams.
  * This way the gizmo code may query all inputs on a non-blocking manner and properly terminate loops.

### Gizmo Methods <a href="#gizmo-methods" id="gizmo-methods"></a>

#### \_\_getitem\_\_(index) <a href="#getitem" id="getitem"></a>

`__getitem__(index)`

Enable `gizmo[index]` syntax for specifying connections.

Returns a tuple `(self, input_stream)` which can be used on the right side of the `>>` operator for connecting gizmos (e.g., `source_gizmo >> target_gizmo[index]`).

Parameters:

| Name    | Type  | Description                           | Default    |
| ------- | ----- | ------------------------------------- | ---------- |
| `index` | `int` | The input stream index on this gizmo. | *required* |

Returns:

| Type              | Description                                                          |
| ----------------- | -------------------------------------------------------------------- |
| `(Gizmo, Stream)` | tuple: A tuple of (this gizmo, the Stream at the given input index). |

#### \_\_init\_\_(input\_stream\_sizes=\[]) <a href="#init" id="init"></a>

`__init__(input_stream_sizes=[])`

Constructor.

Parameters:

| Name                 | Type          | Description                                                                                                                                                                                    | Default |
| -------------------- | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
| `input_stream_sizes` | `List[tuple]` | List of (maxsize, allow\_drop) tuples for each input stream. Use an empty list for no inputs. Each tuple defines the input stream's depth (0 means unlimited) and whether dropping is allowed. | `[]`    |

#### \_\_rshift\_\_(other\_gizmo) <a href="#rshift" id="rshift"></a>

`__rshift__(other_gizmo)`

Connect another gizmo to this gizmo using the `>>` operator.

This implements the right-shift operator, allowing syntax like `source >> target` or `source >> target[input_index]`.

Parameters:

| Name          | Type             | Description                                                                                                                    | Default    |
| ------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------ | ---------- |
| `other_gizmo` | `Gizmo or tuple` | Either a Gizmo to connect (assumes input 0), or a tuple `(gizmo, inp)` where `inp` is the input index or Stream of that gizmo. | *required* |

Returns:

| Name    | Type    | Description                                                        |
| ------- | ------- | ------------------------------------------------------------------ |
| `Gizmo` | `Gizmo` | The source gizmo (other\_gizmo), enabling chaining of connections. |

#### abort(abort=True) <a href="#abort" id="abort"></a>

`abort(abort=True)`

Set or clear the abort flag to stop the run loop.

Parameters:

| Name    | Type   | Description                                                             | Default |
| ------- | ------ | ----------------------------------------------------------------------- | ------- |
| `abort` | `bool` | True to request aborting the run loop, False to clear the abort signal. | `True`  |

#### connect\_to(other\_gizmo, ...) <a href="#connect_to" id="connect_to"></a>

`connect_to(other_gizmo, inp=0)`

Connect an input stream of this gizmo to another gizmo's output.

Parameters:

| Name          | Type            | Description                                                                                  | Default    |
| ------------- | --------------- | -------------------------------------------------------------------------------------------- | ---------- |
| `other_gizmo` | `Gizmo`         | The source gizmo to connect from.                                                            | *required* |
| `inp`         | `int or Stream` | The input index of this gizmo (or an input Stream) to use for the connection. Defaults to 0. | `0`        |

Returns:

| Name    | Type    | Description                     |
| ------- | ------- | ------------------------------- |
| `Gizmo` | `Gizmo` | This gizmo (to allow chaining). |

#### get\_connected <a href="#get_connected" id="get_connected"></a>

`get_connected()`

Recursively gather all gizmos connected to this gizmo.

Returns:

| Name  | Type  | Description                                                                       |
| ----- | ----- | --------------------------------------------------------------------------------- |
| `set` | `set` | A set of Gizmo objects that are connected (directly or indirectly) to this gizmo. |

#### get\_input(inp) <a href="#get_input" id="get_input"></a>

`get_input(inp)`

Get a specific input stream by index.

Parameters:

| Name  | Type  | Description                            | Default    |
| ----- | ----- | -------------------------------------- | ---------- |
| `inp` | `int` | Index of the input stream to retrieve. | *required* |

Returns:

| Name     | Type     | Description                          |
| -------- | -------- | ------------------------------------ |
| `Stream` | `Stream` | The input stream at the given index. |

Raises:

| Type        | Description                                  |
| ----------- | -------------------------------------------- |
| `Exception` | If the requested input index does not exist. |

#### get\_inputs <a href="#get_inputs" id="get_inputs"></a>

`get_inputs()`

Get all input streams of this gizmo.

Returns:

| Type           | Description                                  |
| -------------- | -------------------------------------------- |
| `List[Stream]` | List\[Stream]: List of input stream objects. |

#### get\_tags <a href="#get_tags" id="get_tags"></a>

`get_tags()`

Get the list of meta tags for this gizmo.

Returns:

| Type        | Description                                                                    |
| ----------- | ------------------------------------------------------------------------------ |
| `List[str]` | List\[str]: Tags associated with this gizmo (by default, just its class name). |

#### require\_tags(inp) <a href="#require_tags" id="require_tags"></a>

`require_tags(inp)`

Get the list of meta tags this gizmo requires in upstream meta for a specific input.

Returns:

| Type        | Description                                                                       |
| ----------- | --------------------------------------------------------------------------------- |
| `List[str]` | List\[str]: Tags required by this gizmo in upstream meta for the specified input. |

#### run <a href="#run" id="run"></a>

`run()`

Run the gizmo's processing loop.

This method should retrieve data from input streams (if any), process it, and send results to outputs. Subclasses implement this method to define the gizmo's behavior.

Important guidelines for implementation

* Check `self._abort` periodically and exit the loop if it becomes True.
* If reading from an input stream via `get()` or `get_nowait()`, check for the poison pill (`Stream._poison`). If encountered, exit the loop.
* For example, a typical single-input loop could be:

{% code overflow="wrap" %}

```python
for data in self.get_input(0):
    if self._abort:
        break
    result = self.process(data)
    self.send_result(result)
```

{% endcode %}

There is no need to send a poison pill to outputs; the [Composition](https://docs.degirum.com/degirum-tools/streams/..#composition) will handle closing output streams.

#### send\_result(data) <a href="#send_result" id="send_result"></a>

`send_result(data)`

Send a result to all connected output streams.

Automatically adds timing metadata (gizmo name and timestamp) to each result.

Parameters:

| Name   | Type                 | Description                                                                                            | Default    |
| ------ | -------------------- | ------------------------------------------------------------------------------------------------------ | ---------- |
| `data` | `StreamData or None` | The data result to send. If None (or a poison pill) is provided, all connected outputs will be closed. | *required* |

## Composition <a href="#composition" id="composition"></a>

`Composition`

Orchestrates and runs a set of connected gizmos.

Usage

1. Add all gizmos to the composition using `add()` or by calling the composition instance.
2. Connect the gizmos together using `connect_to()` or the `>>` operator.
3. Start the execution by calling `start()`.
4. To stop the execution, call `stop()` (or use the composition as a context manager).

### Composition Methods <a href="#composition-methods" id="composition-methods"></a>

#### \_\_call\_\_(gizmo) <a href="#call" id="call"></a>

`__call__(gizmo)`

Add a gizmo to this composition (callable syntax).

Equivalent to calling `add(gizmo)`.

Parameters:

| Name    | Type    | Description       | Default    |
| ------- | ------- | ----------------- | ---------- |
| `gizmo` | `Gizmo` | The gizmo to add. | *required* |

Returns:

| Name    | Type    | Description     |
| ------- | ------- | --------------- |
| `Gizmo` | `Gizmo` | The same gizmo. |

#### \_\_enter\_\_ <a href="#enter" id="enter"></a>

`__enter__()`

Start the composition when entering a context (without waiting).

Returns:

| Name          | Type          | Description                                                         |
| ------------- | ------------- | ------------------------------------------------------------------- |
| `Composition` | `Composition` | The composition itself (so that context manager usage is possible). |

#### \_\_exit\_\_(exc\_type, ...) <a href="#exit" id="exit"></a>

`__exit__(exc_type, exc_val, exc_tb)`

On exiting a context, wait for all gizmos to finish (and raise any errors).

Automatically calls `wait()` to ensure all threads have completed.

#### \_\_init\_\_(\*gizmos) <a href="#init" id="init"></a>

`__init__(*gizmos)`

Initialize the composition with optional initial gizmos.

Parameters:

| Name      | Type                       | Description                                                                                                                                                                                                                                | Default |
| --------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------- |
| `*gizmos` | `Gizmo or Iterator[Gizmo]` | Optional gizmos (or iterables of gizmos) to add initially. If a Gizmo is provided, all gizmos connected to it (including itself) are added. If an iterator of gizmos is provided, all those gizmos (and their connected gizmos) are added. | `()`    |

#### add(gizmo) <a href="#add" id="add"></a>

`add(gizmo)`

Add a gizmo to this composition.

Parameters:

| Name    | Type    | Description       | Default    |
| ------- | ------- | ----------------- | ---------- |
| `gizmo` | `Gizmo` | The gizmo to add. | *required* |

Returns:

| Name    | Type    | Description                      |
| ------- | ------- | -------------------------------- |
| `Gizmo` | `Gizmo` | The same gizmo, for convenience. |

#### get\_bottlenecks <a href="#get_bottlenecks" id="get_bottlenecks"></a>

`get_bottlenecks()`

Get gizmos that experienced input queue bottlenecks in the last run.

For this to be meaningful, the composition must have been started with `detect_bottlenecks=True`.

Returns:

| Type         | Description                                                                                                         |
| ------------ | ------------------------------------------------------------------------------------------------------------------- |
| `List[dict]` | A list of dictionaries where each key is a gizmo name and the value is the number of frames dropped for that gizmo. |

#### get\_current\_queue\_sizes <a href="#get_current_queue_sizes" id="get_current_queue_sizes"></a>

`get_current_queue_sizes()`

Get current sizes of each gizmo's input queues. Can be used to analyze deadlocks.

Returns:

| Type         | Description                                                                                                                                                         |
| ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `List[dict]` | A list of dictionaries where each key is a gizmo name and the value is a list containing the gizmo's result count followed by the size of each of its input queues. |

#### request\_stop <a href="#request_stop" id="request_stop"></a>

`request_stop()`

Signal all gizmos in this composition to stop (abort).

This sets each gizmo's abort flag, clears all remaining items from their input queues, and sends poison pills to unblock any waiting gets. This method does not wait for threads to finish; call `wait()` to join threads.

#### start(\*, ...) <a href="#start" id="start"></a>

`start(*, wait=True, detect_bottlenecks=False)`

Start the execution of all gizmos (each in its own thread): launch run() method of every registered gizmo.

Parameters:

| Name                 | Type   | Description                                                                                                       | Default |
| -------------------- | ------ | ----------------------------------------------------------------------------------------------------------------- | ------- |
| `wait`               | `bool` | If True, wait until all gizmos have finished. Defaults to True.                                                   | `True`  |
| `detect_bottlenecks` | `bool` | If True, enable frame dropping on all streams to detect bottlenecks (see `get_bottlenecks()`). Defaults to False. | `False` |

#### stop <a href="#stop" id="stop"></a>

`stop()`

Stop the composition by aborting all gizmos and waiting for all threads to finish.

#### wait <a href="#wait" id="wait"></a>

`wait()`

Wait for all gizmo threads in the composition to finish.

Raises:

| Type        | Description                                                                                                                             |
| ----------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| `Exception` | If the composition has not been started, or if any gizmo raised an error during execution (the exception message will contain details). |

## Watchdog <a href="#watchdog" id="watchdog"></a>

`Watchdog`

Monitors activity rate and timing using tick events and a filtered TPS estimate.

Tracks the frequency of `tick()` calls and the time since the last one. The `check()` method evaluates whether the activity is recent enough and meets a minimum TPS (ticks per second) threshold, using a single-pole low-pass filter to smooth TPS estimation.

### Watchdog Methods <a href="#watchdog-methods" id="watchdog-methods"></a>

#### \_\_init\_\_(time\_limit, ...) <a href="#init" id="init"></a>

`__init__(time_limit, tps_threshold, smoothing=0.9)`

Initializes the Watchdog.

Parameters:

| Name            | Type    | Description                                                   | Default    |
| --------------- | ------- | ------------------------------------------------------------- | ---------- |
| `time_limit`    | `float` | Maximum allowed time (in seconds) since the last tick.        | *required* |
| `tps_threshold` | `float` | Minimum required filtered ticks per second.                   | *required* |
| `smoothing`     | `float` | Smoothing factor for the low-pass filter (0 < smoothing < 1). | `0.9`      |

#### check <a href="#check" id="check"></a>

`check()`

Checks whether the watchdog is within the allowed timing and TPS threshold.

Returns:

| Type                 | Description                                                                                                                                                               |
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Tuple[bool, float]` | Tuple\[bool, float]: A tuple containing: - bool: True if the watchdog is active (recent enough and meets TPS threshold), False otherwise. - float: The current TPS value. |

#### tick <a href="#tick" id="tick"></a>

`tick()`

Records the current timestamp and updates the filtered TPS estimate.

Should be called regularly to track system activity. Uses the time between ticks to calculate instantaneous TPS and applies a low-pass filter to smooth the estimate.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.degirum.com/degirum-tools/streams/streams_base.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
