> built 2026-09-22 15:36 UTC from 2b6bcfa (master) · dagapp 0.1.22. Details: build_info.json

# index.html.md

<!-- generated by epythet -->

# dagapp

Making apps from DAGs by just snapping your fingers

To install:	`pip install dagapp`

[What’s a DAG?](https://en.wikipedia.org/wiki/Directed_acyclic_graph)

[What’s an app?](https://www.amazon.com/Life-Real-Dummies-Clueless-1996-10-03/dp/B01F81N4D0)

This is a beautiful example of a DAG app woven into to an article: [rent-or-buy article+app](https://www.nytimes.com/interactive/2024/upshot/buy-rent-calculator.html)
The app serves as an illustration of the article and the article as the documentation of the app. (Note: It was a lot more “beautiful” in 2014, but they changed the graphic now! Boo!)

Here’s [another example of interactive calculators](https://www.mottomortgage.com/offices/makers-chattanooga/mortgage-calculators).

What `dagapp` wants to become is a framework to generate such effective communication, effortlessly.

Enough theory. Here’s how it works…

## A simple example

### First make a DAG

```python
from meshed.dag import DAG


def b(a):
    return 2**a


def d(c):
    return 10 - (5**c)


def result(b, d):
    return b * d


dag = DAG((b, d, result))
```

### Then make an app

```python
from dagapp.base import dag_app
from functools import partial

dags = [dag]

if __name__ == "__main__":
    app = partial(dag_app, dags=dags)
    app()
```

### Then run the app

```default
>>> streamlit run example.py
```

### … and this is what you get

![png](https://github.com/i2mint/dagapp/blob/master/docs/images/simple_example.png?raw=true)

## A more complicated example

Let’s say we want to create two different DAGs and view them on the same streamlit page, keep all the non-root nodes static and represent the number inputs for one of the DAGs as sliders. We will use functions defined in `configs_example.py` for this example.

### Define the DAGs

To start we can create our DAGs just like in the previous example.

```python
profit_dag = DAG((user_clicks, rev, cost, profit))
revenue_dag = DAG((partners, clicks, revenue))

dags = [profit_dag, revnue_dag]
```

### Define the configs

Next we can define some configs for these DAGs. These configs should be a list of dictionaries, with each dictionary representing the configs for each DAG. Each config must contain a dictionary `arg_types` that matches each of the root nodes in the DAG to an input type (currently the options are: num, slider, text, list, dict). If `arg_types` is not explicitly defined, then it will try to infer from type annotations in the function definitions, and then default to num. If slider is defined as the `arg_type` for any of the root nodes, then another dictionary `ranges` must be defined that matches each of the nodes designated to be slider with a min and max value for that slider. The configs for this example can be seen below.

```python
configs = [
    dict(
        arg_types=dict(
            a="num",
            b="num",
            cost_per_click="num",
            revenue_per_click="num",
        ),
    ),
    dict(
        arg_types=dict(
            max_partners="slider",
            cost_per_click="slider",
            price_elasticity="slider",
            partners="slider",
            clicks_per_partner="slider",
        ),
        ranges=dict(
            max_partners=[0, 2000],
            cost_per_click=[0.0, 1.0],
            price_elasticity=[0, 200],
            partners=[0, 1500],
            clicks_per_partner=[0.0, 10.0],
        ),
    ),
]
```

### Make the app

We can now make our app in a similar manner as the previous example, this time defining our configs, as well as defining `StaticPageFunc` as our page factory to keep all non-root nodes static.

```default
from dagapp.page_funcs import StaticPageFunc

if __name__ == "__main__":
    app = partial(dag_app, dags=dags, page_factory=StaticPageFunc, configs=configs)
    app()
```

### Run the app

```default
>>> streamlit run configs_example.py
```

### … and this is what you get

![png](https://github.com/i2mint/dagapp/blob/master/docs/images/configs_example_1.png?raw=true)
![png](https://github.com/i2mint/dagapp/blob/master/docs/images/configs_example_2.png?raw=true)

<p class="epythet-aggregates">This documentation as a single file: <a href="dagapp.md">dagapp.md</a> (Markdown, for agents).</p>


# _autosummary/dagapp.base.html.md

# dagapp.base

The base components for making apps from DAGs

### Functions

| `dag_app`(dags[, page_factory, configs])                                                      |                                                          |
|-----------------------------------------------------------------------------------------------|----------------------------------------------------------|
| `dag_to_page_name`(dag)                                                                       |                                                          |
| `get_page_callbacks`(dags, page_names, ...)                                                   |                                                          |
| [`get_pages_specs`](_autosummary/dagapp.base.html.md#dagapp.base.get_pages_specs)(dags, page_factory, configs) | Return a mapping of page names to page callback objects. |

### dagapp.base.get_pages_specs(dags, page_factory, configs)

Return a mapping of page names to page callback objects.

The `configs` argument is an iterable of per-dag config dicts. If a config
provides `page_name` or `page_title` that string will be used as the page
name (and as the page title passed to the page factory). Otherwise a name
is autogenerated from the dag via `dag_to_page_name`.


# _autosummary/dagapp.html.md

# dagapp

Making apps from DAGs

### Modules

| [`base`](_autosummary/dagapp.base.html.md#module-dagapp.base)             | The base components for making apps from DAGs     |
|--------------------------------------------------------------------------------------|---------------------------------------------------|
| [`page_funcs`](_autosummary/dagapp.page_funcs.html.md#module-dagapp.page_funcs) | Different page functions used to turn dags to app |
| [`utils`](_autosummary/dagapp.utils.html.md#module-dagapp.utils)           | Utils                                             |


# _autosummary/dagapp.page_funcs.html.md

# dagapp.page_funcs

Different page functions used to turn dags to app

### Classes

| `BasePageFunc`(dag[, page_title])      |    |
|----------------------------------------|----|
| `SimplePageFunc`(dag[, page_title])    |    |
| `StaticPageFunc`(dag[, page_title])    |    |
| `VectorizePageFunc`(dag[, page_title]) |    |


# _autosummary/dagapp.utils.html.md

# dagapp.utils

Utils

### Functions

| [`check_configs`](_autosummary/dagapp.utils.html.md#dagapp.utils.check_configs)(dags, configs)                    | Checks the user defined configs to prevent errors                                             |
|--------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------|
| [`display_factory`](_autosummary/dagapp.utils.html.md#dagapp.utils.display_factory)(dag, nodes, funcs, values, ...) | Display the nodes of a dag with number of slider inputs                                       |
| [`display_node`](_autosummary/dagapp.utils.html.md#dagapp.utils.display_node)(node, arg_types, ranges, ...)      | Displays the given node based on the argument type                                            |
| [`display_vec_node`](_autosummary/dagapp.utils.html.md#dagapp.utils.display_vec_node)(node, funcs, args)             | Displays a non-root-node for vectorized input                                                 |
| [`get_args`](_autosummary/dagapp.utils.html.md#dagapp.utils.get_args)(dag, node, funcs)                      | Returns the arguments for a vectorized FuncNode                                               |
| [`get_default_configs`](_autosummary/dagapp.utils.html.md#dagapp.utils.get_default_configs)(dags)                       | Returns default configs based on dags if the user did not provide them                        |
| [`get_from_configs`](_autosummary/dagapp.utils.html.md#dagapp.utils.get_from_configs)(configs)                       | Obtains information from user defined configs                                                 |
| [`get_func_values`](_autosummary/dagapp.utils.html.md#dagapp.utils.get_func_values)(defaults, funcs)                | Returns the default values for all the FuncNodes in funcs using the root defaults in defaults |
| [`get_funcs`](_autosummary/dagapp.utils.html.md#dagapp.utils.get_funcs)(dag)                                  | Returns the names of all the FuncNodes found in dag                                           |
| [`get_kwargs`](_autosummary/dagapp.utils.html.md#dagapp.utils.get_kwargs)(node, funcs)                         | Get keyword arguments for a FuncNode                                                          |
| [`get_nodes`](_autosummary/dagapp.utils.html.md#dagapp.utils.get_nodes)(dag)                                  | Returns the names of all nodes found in dag                                                   |
| [`get_root_values`](_autosummary/dagapp.utils.html.md#dagapp.utils.get_root_values)(dag)                            | Returns the default values for all the root nodes found in dag                                |
| [`get_values`](_autosummary/dagapp.utils.html.md#dagapp.utils.get_values)(dag, funcs)                          | Returns default values for all the nodes found in dag                                         |
| [`get_vec_input`](_autosummary/dagapp.utils.html.md#dagapp.utils.get_vec_input)(node)                             | Returns a vectorized input defined by a double slider                                         |
| [`mk_double_slider`](_autosummary/dagapp.utils.html.md#dagapp.utils.mk_double_slider)(node, st_kwargs, col)          | Create a double slider for a given node                                                       |
| [`reload_nodes`](_autosummary/dagapp.utils.html.md#dagapp.utils.reload_nodes)(dag, funcs)                        | Updates all nodes based on the values of the root nodes                                       |
| [`st_error`](_autosummary/dagapp.utils.html.md#dagapp.utils.st_error)(message)                               | Raises a streamlit error with the given message                                               |
| [`static_factory`](_autosummary/dagapp.utils.html.md#dagapp.utils.static_factory)(dag, nodes, funcs, values, ...)  | Displays the root nodes of a dag                                                              |
| [`update_nodes`](_autosummary/dagapp.utils.html.md#dagapp.utils.update_nodes)(dag, node_ch, funcs)               | Updates successors of a changed node                                                          |
| [`update_static_nodes`](_autosummary/dagapp.utils.html.md#dagapp.utils.update_static_nodes)(dag, nodes, funcs, col)     | Updates the non-root nodes for a static DAG factory                                           |
| [`update_vec_nodes`](_autosummary/dagapp.utils.html.md#dagapp.utils.update_vec_nodes)(dag, nodes, funcs, col)        | Update non root-nodes for vectorized DAG factory                                              |
| [`vector_factory`](_autosummary/dagapp.utils.html.md#dagapp.utils.vector_factory)(dag, nodes, funcs, col)          | Displays the root nodes of a vectorized DAG as double sliders                                 |

### dagapp.utils.check_configs(dags, configs)

Checks the user defined configs to prevent errors

### dagapp.utils.display_factory(dag, nodes, funcs, values, arg_types, ranges, col)

Display the nodes of a dag with number of slider inputs

### dagapp.utils.display_node(node, arg_types, ranges, values, st_kwargs)

Displays the given node based on the argument type

### dagapp.utils.display_vec_node(node, funcs, args)

Displays a non-root-node for vectorized input

### dagapp.utils.get_args(dag, node, funcs)

Returns the arguments for a vectorized FuncNode

### dagapp.utils.get_default_configs(dags)

Returns default configs based on dags if the user did not provide them

### dagapp.utils.get_from_configs(configs)

Obtains information from user defined configs

### dagapp.utils.get_func_values(defaults, funcs)

Returns the default values for all the FuncNodes in funcs using the root defaults in defaults

### dagapp.utils.get_funcs(dag)

Returns the names of all the FuncNodes found in dag

### dagapp.utils.get_kwargs(node, funcs)

Get keyword arguments for a FuncNode

### dagapp.utils.get_nodes(dag)

Returns the names of all nodes found in dag

### dagapp.utils.get_root_values(dag)

Returns the default values for all the root nodes found in dag

### dagapp.utils.get_values(dag, funcs)

Returns default values for all the nodes found in dag

### dagapp.utils.get_vec_input(node)

Returns a vectorized input defined by a double slider

### dagapp.utils.mk_double_slider(node, st_kwargs, col)

Create a double slider for a given node

### dagapp.utils.reload_nodes(dag, funcs)

Updates all nodes based on the values of the root nodes

### dagapp.utils.st_error(message)

Raises a streamlit error with the given message

### dagapp.utils.static_factory(dag, nodes, funcs, values, arg_types, ranges, col)

Displays the root nodes of a dag

### dagapp.utils.update_nodes(dag, node_ch, funcs)

Updates successors of a changed node

### dagapp.utils.update_static_nodes(dag, nodes, funcs, col)

Updates the non-root nodes for a static DAG factory

### dagapp.utils.update_vec_nodes(dag, nodes, funcs, col)

Update non root-nodes for vectorized DAG factory

### dagapp.utils.vector_factory(dag, nodes, funcs, col)

Displays the root nodes of a vectorized DAG as double sliders


# about-this-build.html.md

<!-- generated by epythet -->

# About this build

This documentation was built on **2026-09-22 15:36 UTC** from commit <a href="https://github.com/i2mint/dagapp/commit/2b6bcfa5d7a3ee4d6c2488e374a4f95ae5f2c03e"><code>2b6bcfa</code></a> on branch <code>master</code>, for **dagapp 0.1.22** (from <code>pyproject.toml</code>).

#### WARNING
The documentation and the package may be misaligned:

- The documented version (0.1.22) is behind the latest release on PyPI (0.1.23): `pip install dagapp` gives newer code than these docs describe.

## Source

|                     |                                                                                                                                                      |
|---------------------|------------------------------------------------------------------------------------------------------------------------------------------------------|
| Commit              | <a href="https://github.com/i2mint/dagapp/commit/2b6bcfa5d7a3ee4d6c2488e374a4f95ae5f2c03e"><code>2b6bcfa5d7a3ee4d6c2488e374a4f95ae5f2c03e</code></a> |
| Branch              | <code>master</code>                                                                                                                                  |
| Tags at this commit | none                                                                                                                                                 |
| Working tree        | clean                                                                                                                                                |
| Remote              | <code>https://github.com/i2mint/dagapp</code>                                                                                                        |

## Continuous integration

|              |                                                                                            |
|--------------|--------------------------------------------------------------------------------------------|
| Repository   | <code>i2mint/dagapp</code>                                                                 |
| Run          | <a href="https://github.com/i2mint/dagapp/actions/runs/35748321760">35748321760</a>        |
| Ref          | <code>refs/heads/master</code>                                                             |
| Event commit | <code>2b6bcfa5d7a3ee4d6c2488e374a4f95ae5f2c03e</code> (in the history of the built commit) |

## Tools

|          |         |
|----------|---------|
| epythet  | 0.2.12  |
| Sphinx   | 9.1.0   |
| docutils | 0.22.4  |
| Python   | 3.12.14 |

## Configuration as resolved

|               |                                                                   |
|---------------|-------------------------------------------------------------------|
| theme         | <code>auto</code> (Sphinx theme <code>pydata_sphinx_theme</code>) |
| accent        | <code>#92323d</code>                                              |
| api_generator | <code>autosummary</code>                                          |
| ignore        | <code>tests/</code>, <code>scrap/</code>, <code>examples/</code>  |
| agent_outputs | <code>true</code>                                                 |
| aggregates    | <code>md</code>                                                   |
| ai_artifacts  | <code>true</code>                                                 |

## Package on PyPI

Latest release: <a href="https://pypi.org/project/dagapp/0.1.23/">0.1.23</a>, newer than the documented version (0.1.22).

## Reproduce

```bash
git clone https://github.com/i2mint/dagapp && cd dagapp
git checkout 2b6bcfa5d7a3ee4d6c2488e374a4f95ae5f2c03e
pip install "epythet==0.2.12"
epythet quickstart . --ignore tests/ scrap/ examples/
```

The same data, for machines: <a href="build_info.json"><code>build_info.json</code></a> (schema version 1).


# api.html.md

# API reference

| [`dagapp`](_autosummary/dagapp.html.md#module-dagapp)   | Making apps from DAGs   |
|-------------------------------------------------------------------------|-------------------------|


