Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
ae68cf6
Allow passing return type of aggregation or try to infer it.
hmgaudecker Jan 11, 2026
74eecc9
Clarify that tier 3 inference is a heuristic
hmgaudecker Jan 11, 2026
2ceed08
Add tests for set_annotations=False with aggregator
hmgaudecker Jan 11, 2026
dbd938d
Drop Python 3.10 support in order to be able to use networkx 3.6 (whi…
hmgaudecker Jan 12, 2026
94c3b07
Fix ruff erorr.
hmgaudecker Jan 12, 2026
84b3edb
Build docs using pixi.
hmgaudecker Jan 12, 2026
6784292
Merge branch 'main' into buid-docs-using-pixi
hmgaudecker Jan 13, 2026
dbf0cb7
Improve docs.
hmgaudecker Jan 13, 2026
22480ec
Merge branch 'buid-docs-using-pixi' of github.com:OpenSourceEconomics…
hmgaudecker Jan 13, 2026
d1f1e06
Merge branch 'main' into buid-docs-using-pixi
hmgaudecker Jan 13, 2026
78f4fd4
Tiny improvement to start page.
hmgaudecker Jan 13, 2026
7aa32fe
Improve documentation of usage patterns.
hmgaudecker Jan 16, 2026
cf881f5
Use Jupyter Book for documentation.
hmgaudecker Jan 16, 2026
cebef20
Re-apply changes from #63.
hmgaudecker Jan 16, 2026
c30f433
Make examples executable.
hmgaudecker Jan 16, 2026
222b27e
Fix ty and pre-commit errors.
hmgaudecker Jan 16, 2026
23af9e8
Make notebook executable. (?)
hmgaudecker Jan 16, 2026
9ab9025
Try with micropip.
hmgaudecker Jan 16, 2026
e795018
Next try.
hmgaudecker Jan 16, 2026
d97727f
Try with binder.
hmgaudecker Jan 16, 2026
b25555e
Try gesis binder.
hmgaudecker Jan 16, 2026
0bd7bb5
Launch on mybinder?
hmgaudecker Jan 16, 2026
4c8132e
Improve docs and simplify build process.
hmgaudecker Jan 17, 2026
a531c45
Fix rtd build?
hmgaudecker Jan 17, 2026
0bac915
Fix BASE_URL
hmgaudecker Jan 17, 2026
b933f86
Add llms.txt
hmgaudecker Jan 17, 2026
696894f
Change typing so that we allow Sequences in user-facing code where we…
hmgaudecker Feb 10, 2026
c145a61
Use pyproject-fmt instead of tox-toml-fmt, add nbstripout.
hmgaudecker Feb 10, 2026
f040261
Bump prefix-dev/setup-pixi in the github-actions group (#69)
dependabot[bot] Feb 10, 2026
a49e8b2
Remove 'if TYPE_CHECKING' blocks. Just distracting and they will beco…
hmgaudecker Feb 10, 2026
0771ad4
Changes.
hmgaudecker Feb 10, 2026
95b1ed3
Merge branch 'allow-sequence-in-with_signature' into chore-boilerplat…
hmgaudecker Feb 10, 2026
d08285b
Changes.
hmgaudecker Feb 10, 2026
70e1d46
Merge branch 'chore-boilerplate-update' into use-jb-for-docs
hmgaudecker Feb 10, 2026
d4a5bb8
Merge branch 'allow-sequence-in-with_signature' into typing-allow-seq…
hmgaudecker Feb 10, 2026
6f592a4
Merge branch 'typing-allow-sequence-instead-of-list-only' into chore-…
hmgaudecker Feb 10, 2026
3dd99ac
Merge branch 'chore-boilerplate-update' into use-jb-for-docs
hmgaudecker Feb 10, 2026
66a2499
Execute notebooks during build
hmgaudecker Feb 10, 2026
3f48a99
Merge branch 'main' into use-jb-for-docs
hmgaudecker Feb 11, 2026
e6bd88b
Actually keep the outputs -- requires not deleting kernelspec with nb…
hmgaudecker Feb 11, 2026
0ac1675
Clean up typing/future imports. Auto-update prek.
hmgaudecker Feb 13, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -137,3 +137,7 @@ venv.bak/


src/dags/_version.py
docs/_build/

# MyST build outputs
_build
8 changes: 4 additions & 4 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ repos:
- id: check-hooks-apply
- id: check-useless-excludes
- repo: https://github.com/tox-dev/pyproject-fmt
rev: v2.12.1
rev: v2.16.0
hooks:
- id: pyproject-fmt
- repo: https://github.com/lyz-code/yamlfix
Expand Down Expand Up @@ -47,7 +47,7 @@ repos:
hooks:
- id: yamllint
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.15.0
rev: v0.15.1
hooks:
- id: ruff-check
args:
Expand All @@ -62,12 +62,12 @@ repos:
- pyi
- python
- repo: https://github.com/kynan/nbstripout
rev: 0.8.2
rev: 0.9.0
hooks:
- id: nbstripout
args:
- --extra-keys
- metadata.kernelspec metadata.language_info.version metadata.vscode
- metadata.language_info.version metadata.vscode
- repo: https://github.com/executablebooks/mdformat
rev: 1.0.0
hooks:
Expand Down
20 changes: 20 additions & 0 deletions .readthedocs.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
version: 2
build:
os: ubuntu-24.04
tools:
python: '3.13'
nodejs: '20'
jobs:
create_environment:
- asdf plugin add pixi
- asdf install pixi latest
- asdf global pixi latest
install:
- pixi install -e docs
post_build:
# Jupyter Book 2.0 builds site content to _build/html.
# For ReadTheDocs, we build and then copy to the expected output location.
- mkdir --parents $READTHEDOCS_OUTPUT/html/
- BASE_URL="/$READTHEDOCS_LANGUAGE/$READTHEDOCS_VERSION" pixi run -e docs docs
- cp -a docs/_build/html/. "$READTHEDOCS_OUTPUT/html" && rm -r docs/_build
12 changes: 0 additions & 12 deletions .readthedocs.yml

This file was deleted.

2 changes: 2 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ releases are available on [conda-forge](https://anaconda.org/conda-forge/dags).

## 0.5.0

- :gh:`65` Update docs and use Jupyter Book for documentation (:ghuser:`hmgaudecker`).

- :gh:`72` Remove type checking blocks (:ghuser:`hmgaudecker`).

- :gh:`71` Change `list` annotations to `Sequence`, improve pre-commit hooks
Expand Down
2 changes: 2 additions & 0 deletions binder/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
dags
numpy
20 changes: 0 additions & 20 deletions docs/Makefile

This file was deleted.

File renamed without changes.
File renamed without changes
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
164 changes: 164 additions & 0 deletions docs/getting_started.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
# Getting Started

This guide introduces the core concepts of dags and shows you how to get started.

## Core Concept

dags works by analyzing function signatures to build a dependency graph. If a function has a parameter named `x`, and another function is named `x`, then the first function depends on the second.

```python
def x():
return 1

def y(x): # depends on x because parameter is named "x"
return x + 1
```

## Basic Usage

### Creating a Combined Function

The main entry point is `concatenate_functions`:

```python
import dags

def income():
return 50000

def tax_rate():
return 0.3

def tax(income, tax_rate):
return income * tax_rate

def net_income(income, tax):
return income - tax

# Combine all functions
combined = dags.concatenate_functions(
functions={"income": income, "tax_rate": tax_rate, "tax": tax, "net_income": net_income},
targets=["net_income", "tax"],
return_type="dict",
)

result = combined()
# result = {"net_income": 35000.0, "tax": 15000.0}
```

### Providing External Inputs

Functions can have parameters that are not provided by other functions. These become inputs to the combined function:

```python
def tax(income, tax_rate):
return income * tax_rate

def net_income(income, tax):
return income - tax

combined = dags.concatenate_functions(
functions={"tax": tax, "net_income": net_income},
targets=["net_income"],
return_type="dict",
)

# income and tax_rate are external inputs
result = combined(income=50000, tax_rate=0.3)
# result = {"net_income": 35000.0}
```

### Return Types

By default, `concatenate_functions` returns a tuple. You can also get a dictionary:

```python
# Default: returns tuple
combined = dags.concatenate_functions(
functions=functions,
targets=["a", "b", "c"],
)
a, b, c = combined()

# Returns dictionary with target names as keys
combined = dags.concatenate_functions(
functions=functions,
targets=["a", "b", "c"],
return_type="dict",
)
result = combined() # {"a": ..., "b": ..., "c": ...}
```

## Inspecting the DAG

Use `create_dag` to create and inspect the dependency graph:

```python
import dags

dag = dags.create_dag(
functions={"income": income, "tax": tax, "net_income": net_income},
targets=["net_income"],
)

# dag is a networkx.DiGraph
print(list(dag.nodes())) # ['income', 'tax', 'net_income']
print(list(dag.edges())) # [('income', 'tax'), ('tax', 'net_income'), ...]
```

## Finding Dependencies

Use `get_ancestors` to find all functions that a target depends on:

```python
ancestors = dags.get_ancestors(
functions=functions,
targets=["net_income"],
)
# Returns set of all function names that net_income depends on
```

## Working with Annotations

### Getting Function Arguments

`get_free_arguments` returns the parameter names of a function:

```python
def my_func(a, b, c=1):
return a + b + c

args = dags.get_free_arguments(my_func)
# args = ["a", "b", "c"]
```

### Getting Type Annotations

`get_annotations` returns type annotations:

```python
def my_func(a: int, b: float) -> float:
return a + b

annotations = dags.get_annotations(my_func)
# annotations = {"a": int, "b": float, "return": float}
```

## Renaming Arguments

Use `rename_arguments` to change parameter names:

```python
def original(x, y):
return x + y

renamed = dags.rename_arguments(original, mapper={"x": "a", "y": "b"})
# renamed now has signature (a, b) instead of (x, y)
```

This is useful when integrating functions from different sources that use different naming conventions.

## Next Steps

- Learn about [common usage patterns](usage_patterns.md) from real projects
- Explore [tree structures](tree.md) for nested data
58 changes: 58 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# dags

```{image} _static/images/logo.svg
:width: 400px
:align: center
```

**dags** is a Python library for creating executable directed acyclic graphs (DAGs) from interdependent functions. It automatically determines the execution order based on function signatures and enables efficient composition of complex computational pipelines.

## Key Features

- **Automatic dependency resolution**: Functions are ordered based on their parameter names matching other functions' names
- **Function composition**: Combine multiple functions into a single callable
- **Tree structures**: Work with nested dictionaries using qualified names
- **Signature manipulation**: Rename arguments and manage function signatures

## Quick Example

```python
import dags

def a(x):
return x ** 2

def b(a):
return a + 1

def c(a, b):
return a + b

# Combine functions into one
combined = dags.concatenate_functions(
functions={"a": a, "b": b, "c": c},
targets=["c"],
return_type="dict",
)

result = combined(x=5) # Returns {"c": 51}
```

The key is that you can build the combined function at runtime, which allows you to
compose a computational pipeline in a way that you do not need to specify in advance, or
in a multitude of ways. It has proven very helpful in a framework to solve life cycle
models ([pylcm](https://github.com/OpenSourceEconomics/pylcm)) and to model the German
taxes and transfers system ([ttsim](https://github.com/ttsim-dev/ttsim) /
[gettsim](https://github.com/ttsim-dev/gettsim)).

## Installation

```bash
pip install dags
```

Or with conda:

```bash
conda install -c conda-forge dags
```
36 changes: 0 additions & 36 deletions docs/make.bat

This file was deleted.

Loading