Metadata-Version: 2.4
Name: stooge
Version: 0.1.0
Summary: A simple project framework to keep you from getting burned
Author-email: Derrick Chambers <chambers.ja.derrick@gmail.com>
License: MIT License
        
        Copyright (c) 2023 Derrick Chambers
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
        
Project-URL: Bug Tracker, https://github.com/d-chambers/port/issues
Project-URL: Documentation, https://github.com/d-chambers/port
Project-URL: Homepage, https://github.com/d-chambers/port
Keywords: workflow,projects
Classifier: Development Status :: 4 - Beta
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Scientific/Engineering
Requires-Python: >=3.13
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: typer
Requires-Dist: rich
Requires-Dist: jinja2
Requires-Dist: toml
Requires-Dist: pdbpp>=0.12.0.post1
Provides-Extra: test
Requires-Dist: pytest; extra == "test"
Requires-Dist: pre-commit; extra == "test"
Requires-Dist: ruff; extra == "test"
Requires-Dist: scikit-learn; extra == "test"
Provides-Extra: dev
Requires-Dist: stooge[test]; extra == "dev"
Dynamic: license-file

# port

A simple project framework.

`port` facilitates rapid, reproducible development for local research projects.

## Project structure

port requires a specific project structure.

An example project directory looks like this:

my_project
-> inputs/
---> some_file.csv
-> outputs/
-> local.py
-> environment.yml
-> a010_clean_data.py
-> a020_calculate.py
-> a030_visualize.py

Each script has an ID (the part of the name before the first `_`).

The file called `local.py` defines the inputs and outputs of the scripts. In this file, outputs are also given the same prefix.

For example:

```python
from pathlib import Path

input_path = Path("inputs")
output_path = Path("outputs")

raw_data_path = input_path / "raw data.csv"

a010_clean_data_path = output_path / "a010_cleaned_outputs.csv"
a020_calculated_data_path = output_path / "a020_calculated_results.csv"
a030_result_plot = output_path / "a030_result_plot.png"
```

This provides port with all the required information to figure out the relationships between scripts and their outputs.

## Init
Creates a port project skeleton.

This provides a small Rich interface to get information about the project name and backend, or they can be provided via command-line flags.

Supported backends are:
- [uv](https://docs.astral.sh/uv/)
- [miniforge](https://github.com/conda-forge/miniforge)
- [marimo](https://marimo.io/)
- python (use system python or provided interpreter path)

```bash
port init test_project --backend uv
```

## Run

`port run` runs the entire project up to and including a target ID. It automatically calculates stale or missing results that `a030` depends on.

For example:

```bash
port run a030
```

This first gets the directed acyclic graph (DAG) that defines `a030`'s dependencies. It then uses file output mtime values to determine if any results need to be re-run. This includes:

- Requiring that, for a given output, all dependency outputs have an mtime less than or equal to the current output.
- Requiring all outputs to have an mtime greater than or equal to the script that creates them.

Flags include:
- `--force`: rerun the specified task.
- `--force-all`: rerun all affected tasks.
- `--debug`: If true, drop into a pdb debugger on failure.

## Remove

Remove results from specified tasks.

```bash
port remove a020  # removes the results for a020
```

## Parse

Although typically called automatically by other commands, it can be used manually to parse script structure/dependencies and update timestamps.

```bash
port parse  # parse current directory, or pass a path
```

The flag `--dryrun` can be used to simply validate the project structure.


# Guiding principles
- `port` is always optional. A project can be fully executed by running the scripts in order. It is there when you want it, and it gets out of your way when you don't.
