Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
22 changes: 19 additions & 3 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,35 @@ on:
push:
tags: ["v*"]

permissions:
id-token: write # required for PyPI Trusted Publishing

jobs:
publish:
runs-on: ubuntu-latest

environment:
name: release
url: https://pypi.org/p/iolaus

permissions:
contents: read
id-token: write # required for PyPI Trusted Publishing

steps:
- uses: actions/checkout@v4

- uses: astral-sh/setup-uv@v5

- run: uv sync --all-extras

- name: Check tag matches package version
run: |
TAG="${GITHUB_REF_NAME#v}"
VERSION=$(uv run python -c "import tomllib, pathlib; print(tomllib.loads(pathlib.Path('pyproject.toml').read_text())['project']['version'])")
if [ "$TAG" != "$VERSION" ]; then
echo "::error::Tag $GITHUB_REF_NAME does not match pyproject.toml version $VERSION"
exit 1
fi
echo "Tag $GITHUB_REF_NAME matches version $VERSION"

- name: Run tests
run: uv run pytest

Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -205,3 +205,6 @@ cython_debug/
marimo/_static/
marimo/_lsp/
__marimo__/

# macOS
.DS_Store
17 changes: 16 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,21 @@

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

- Initial project scaffolding
## [0.1.0] - 2026-08-22

Initial release.

### Added

- `command()` decorator factory that registers a function as a Typer command and wires in configuration and run logging.
- Configuration merging via Dynaconf: base settings, extra config files passed with `--config`, and individual key overrides passed with `--set` (using `__` for nested keys).
- Timestamped run directories under `outputs/<command>/<date>/<time>/`, each containing a `run.log` and a `config.json` snapshot of the merged configuration.
- Opt-in injection of `settings` and `run_dir`, only for functions that declare them in their signature.
- Type annotations throughout, with a `py.typed` marker for downstream type checkers.

[Unreleased]: https://github.com/vgreg/iolaus/compare/v0.1.0...HEAD
[0.1.0]: https://github.com/vgreg/iolaus/releases/tag/v0.1.0
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

A lightweight Python framework for research data analysis projects. Iolaus wires together [Dynaconf](https://www.dynaconf.com/), [Typer](https://typer.tiangolo.com/), and a custom run-logging system into a single decorator-based API that adds automatic configuration management and reproducible run artifacts on every invocation.

**Documentation:** [www.vincentgregoire.com/iolaus](https://www.vincentgregoire.com/iolaus/)

## Features

- **Decorator-based API** — feels like FastAPI/Typer, with zero boilerplate
Expand Down Expand Up @@ -80,6 +82,12 @@ uv sync --all-extras
uv run pytest
```

## Relationship to Hydra

Iolaus is inspired by [Hydra](https://hydra.cc/), which established the pattern of composable configuration files combined with timestamped output directories for research code. Iolaus is deliberately a lightweight alternative implementing only the subset of Hydra's features that I actually use in my own projects, built on Dynaconf and Typer rather than on OmegaConf.

If Iolaus is not flexible enough, or if you need something it does not provide (config groups, multirun parameter sweeps, structured configs, object instantiation, or launcher plugins for clusters), you should use Hydra instead. It is a mature and well-documented project, and Iolaus makes no attempt to match its scope.

## License

MIT
19 changes: 19 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,25 @@ outputs/
└── config.json
```

## Relationship to Hydra

Iolaus is inspired by [Hydra](https://hydra.cc/), which established the pattern of composable configuration files combined with timestamped output directories for research code. Iolaus is deliberately a lightweight alternative implementing only the subset of Hydra's features that I actually use in my own projects, built on [Dynaconf](https://www.dynaconf.com/) and [Typer](https://typer.tiangolo.com/) rather than on OmegaConf.

The trade-off is scope. Iolaus gives you a decorator, config merging, and a run directory, and nothing else. Hydra gives you a much larger system:

| | Iolaus | Hydra |
| --- | --- | --- |
| Config merging from files | Yes | Yes |
| CLI key overrides | Yes | Yes |
| Timestamped run directories | Yes | Yes |
| Config groups and defaults lists | No | Yes |
| Multirun and parameter sweeps | No | Yes |
| Structured (typed) configs | No | Yes |
| Object instantiation from config | No | Yes |
| Launcher plugins (Slurm, Ray, etc.) | No | Yes |

If Iolaus is not flexible enough, or if you need any of the features in the right-hand column, you should use Hydra instead. It is a mature and well-documented project, and Iolaus makes no attempt to match its scope.

## Next steps

- [Getting Started](getting-started.md) — installation and first project
Expand Down
2 changes: 2 additions & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
site_name: Iolaus
site_description: Decorator-based CLI, config, and logging framework for research projects.
site_url: https://www.vincentgregoire.com/iolaus/
repo_url: https://github.com/vgreg/iolaus
repo_name: vgreg/iolaus

Expand Down Expand Up @@ -39,6 +40,7 @@ nav:
- API Reference: api-reference.md

markdown_extensions:
- tables
- pymdownx.highlight
- pymdownx.superfences
- admonition
Expand Down
43 changes: 42 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,36 @@ version = "0.1.0"
description = "Decorator-based CLI + config + logging framework for research projects."
readme = "README.md"
requires-python = ">=3.11"
license = { text = "MIT" }
license = "MIT"
license-files = ["LICENSE"]
authors = [
{ name = "Vincent Grégoire", email = "vincent.gregoire@gmail.com" },
]
keywords = [
"cli",
"configuration",
"logging",
"research",
"reproducibility",
"data-analysis",
"dynaconf",
"typer",
]
classifiers = [
"Development Status :: 3 - Alpha",
"Environment :: Console",
"Intended Audience :: Developers",
"Intended Audience :: Science/Research",
"Operating System :: OS Independent",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
"Topic :: Scientific/Engineering",
"Topic :: Software Development :: Libraries :: Python Modules",
"Typing :: Typed",
]
dependencies = [
"dynaconf>=3.2",
"typer>=0.12",
Expand All @@ -24,6 +53,13 @@ docs = [
"mkdocstrings[python]",
]

[project.urls]
Homepage = "https://github.com/vgreg/iolaus"
Documentation = "https://www.vincentgregoire.com/iolaus/"
Repository = "https://github.com/vgreg/iolaus"
Issues = "https://github.com/vgreg/iolaus/issues"
Changelog = "https://github.com/vgreg/iolaus/blob/main/CHANGELOG.md"

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
Expand All @@ -50,3 +86,8 @@ tag = true
filename = "pyproject.toml"
search = 'version = "{current_version}"'
replace = 'version = "{new_version}"'

[[tool.bumpversion.files]]
filename = "src/iolaus/__init__.py"
search = '__version__ = "{current_version}"'
replace = '__version__ = "{new_version}"'
Loading