rair 0.1.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: rair
|
|
3
|
+
Version: 0.1.2
|
|
4
|
+
Summary: Simple data versioning
|
|
5
|
+
Classifier: Programming Language :: Python :: 3
|
|
6
|
+
Classifier: Operating System :: OS Independent
|
|
7
|
+
Requires-Python: >=3.10
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Requires-Dist: typer>=0.12.0
|
|
11
|
+
Requires-Dist: tomli>=2.0.0; python_version < "3.11"
|
|
12
|
+
Provides-Extra: dev
|
|
13
|
+
Requires-Dist: pytest>=8.0.0; extra == "dev"
|
|
14
|
+
Requires-Dist: pytest-cov>=5.0.0; extra == "dev"
|
|
15
|
+
Requires-Dist: pytest-mock>=3.12.0; extra == "dev"
|
|
16
|
+
Requires-Dist: mypy>=1.8.0; extra == "dev"
|
|
17
|
+
Dynamic: license-file
|
|
18
|
+
|
|
19
|
+
# Rair - Research Archival & Integrity Recorder
|
|
20
|
+
|
|
21
|
+
Rair is a CLI-tool for simple data versioning.
|
|
22
|
+
|
|
23
|
+
When running experiments, model parameters and model details needs to be tweaked
|
|
24
|
+
frequently. Committing minimal changes clutters the git history and makes it hard to track
|
|
25
|
+
actual program modifications. Rair allows to link computation results to exact code versions
|
|
26
|
+
without the need to commit all changes to git. Therefore it stores code diffs alongside the git commit
|
|
27
|
+
reference. It tracks input and intermediate data as well to guarantee full reproducibility for every run.
|
|
28
|
+
|
|
29
|
+
Using heuristics, Rair can be used in many scenarios without any manual configuration.
|
|
30
|
+
|
|
31
|
+
## Usage example
|
|
32
|
+
|
|
33
|
+
Suppose you have a simple script `mymodel.py` committed to git, looking like this:
|
|
34
|
+
|
|
35
|
+
```python
|
|
36
|
+
import time
|
|
37
|
+
|
|
38
|
+
print('Test text output to stdio')
|
|
39
|
+
p1 = 5.9
|
|
40
|
+
p2 = 9.5
|
|
41
|
+
|
|
42
|
+
with open("test_result.txt", "w") as f:
|
|
43
|
+
current_time = time.strftime("%Y-%m-%d %H:%M:%S")
|
|
44
|
+
f.write(f"Current time: {current_time}\n")
|
|
45
|
+
f.write(f"result = {p1 + p2}\n")
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
You tune some parameters (here `p1` and `p2`) without committing the changes to git.
|
|
49
|
+
|
|
50
|
+
Now you run your script like this:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
rair mymodel.py
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Rair runs the script and creates an archive with the following structure:
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
rairarchive/
|
|
60
|
+
├── data/
|
|
61
|
+
│ └── 9157ce88256e95668977_test_result.txt # deduplicated data file
|
|
62
|
+
└── runs/
|
|
63
|
+
└── 20260603-001-023aa51f/
|
|
64
|
+
├── info.md # human-readable run overview
|
|
65
|
+
├── run.json # machine-readable run metadata
|
|
66
|
+
├── out.txt # captured stdout/stderr
|
|
67
|
+
├── git_diff.patch # uncommitted changes (patch format)
|
|
68
|
+
└── test_result.txt # output file (hardlink)
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
The file `info.md` gives an overview of the run:
|
|
72
|
+
|
|
73
|
+
```markdown
|
|
74
|
+
# Run Information
|
|
75
|
+
- Start time: 2026-06-03 11:53:09
|
|
76
|
+
- Execution time: 0.185 s
|
|
77
|
+
- Command: `python mymodel.py`
|
|
78
|
+
- Run hash: `023aa51fa4981ebe097f2045947d2108cff014c42332d5f6ef5a9d71cbf5273b`
|
|
79
|
+
|
|
80
|
+
## Git Information
|
|
81
|
+
- Commit: `95aa8c491f8a3e5c44890ea3c6616e123692c4cd`
|
|
82
|
+
- Short git hash: `95aa8c4`
|
|
83
|
+
- Branch: `main`
|
|
84
|
+
- Tracking URL: `no-upstream`
|
|
85
|
+
|
|
86
|
+
## Uncommitted Changes
|
|
87
|
+
in mymodel.py:
|
|
88
|
+
p1 = 7.1
|
|
89
|
+
p2 = 3.3
|
|
90
|
+
|
|
91
|
+
## Output Files
|
|
92
|
+
- `test_result.txt` -> `rairarchive/data/9157ce88256e95668977_test_result.txt` (hash: `9157ce88`)
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
The "Run hash" captures the git hash, code diff, command line parameters and input file content.
|
|
96
|
+
|
|
97
|
+
## Install
|
|
98
|
+
|
|
99
|
+
Rair can be installed with pip. Its tested on Windows and Unix:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
pip install rair
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Features
|
|
106
|
+
|
|
107
|
+
- **Auto-discovery**: Automatically discover input/output files using hash-based change detection for outputs
|
|
108
|
+
- **Hash caching**: Cache hash calculations in `.rair_cache/` for fast operation on large data files
|
|
109
|
+
- **Git diff tracking**: Track uncommitted changes alongside git commits
|
|
110
|
+
- **Archive format**: Human-readable markdown and machine-readable JSON
|
|
111
|
+
- **Flexible configuration**: Configure via CLI, or config file `.rair.toml`, or `pyproject.toml`
|
|
112
|
+
- **Output capture**: Captures stdout/stderr to a file
|
|
113
|
+
- **Deduplication**: Avoids storing duplicate data files by using content hashes
|
|
114
|
+
- **Selective tracking**: Use `--no-auto-discover` to require explicit `--input`/`--output`
|
|
115
|
+
- **Output hardlinks**: `--output-files-in-run` creates hardlinks for easy access
|
|
116
|
+
- **Default command**: Configure a default command to run when no script specified
|
|
117
|
+
- **Hierarchical config**: Local configs override project settings
|
|
118
|
+
|
|
119
|
+
## Running Rair
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
# Run a Python script with automatic tracking of all data files
|
|
123
|
+
# in the project directory
|
|
124
|
+
rair myscript.py
|
|
125
|
+
|
|
126
|
+
# Run a Python script with script arguments
|
|
127
|
+
rair myscript.py arg1 arg2
|
|
128
|
+
|
|
129
|
+
# Run with explicit command
|
|
130
|
+
rair python3 mymodel.py arg1 arg2
|
|
131
|
+
|
|
132
|
+
# The first argument can be a Python script or any arbitrary command
|
|
133
|
+
rair make --all
|
|
134
|
+
|
|
135
|
+
# Manually specify which files to track
|
|
136
|
+
rair --input "data/*.csv" --output "results/*.json" myscript.py
|
|
137
|
+
|
|
138
|
+
# If only input files are specified, outputs are auto-discovered
|
|
139
|
+
rair --input "data/*.csv" --input parameters.txt myscript.py
|
|
140
|
+
|
|
141
|
+
# Selective tracking - specify exactly which files to track
|
|
142
|
+
# Use --no-auto-discover to require explicit --input and --output
|
|
143
|
+
rair --no-auto-discover --input "data/*.csv" --output "results/*.json" myscript.py
|
|
144
|
+
|
|
145
|
+
# Run the default command set in config file and add
|
|
146
|
+
# a comment that is stored with the results
|
|
147
|
+
rair --comment "experiment 1"
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### All CLI flags
|
|
151
|
+
|
|
152
|
+
```
|
|
153
|
+
--config FILE Path to config file
|
|
154
|
+
--input TEXT Glob pattern for input files to track
|
|
155
|
+
--output TEXT Glob pattern for output files to track
|
|
156
|
+
--exclude TEXT Glob pattern to exclude from tracking
|
|
157
|
+
--archive-dir DIRECTORY Directory for archive data (default: rairarchive)
|
|
158
|
+
--autodata DIRECTORY Directory for auto-discovering input/output files
|
|
159
|
+
--capture-output/--no-capture-output
|
|
160
|
+
Capture stdout to out.txt [default: enabled]
|
|
161
|
+
--auto-discover/--no-auto-discover
|
|
162
|
+
Enable/disable auto-discovery [default: enabled]
|
|
163
|
+
--output-files-in-run Create hardlinks to output files in run folder
|
|
164
|
+
--comment TEXT Add a comment to the run
|
|
165
|
+
--setup Run interactive setup dialog
|
|
166
|
+
--help Show help message
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## Configuration
|
|
170
|
+
|
|
171
|
+
As alternative to CLI parameters, configuration can be provided via a `.rair.toml` file or in `pyproject.toml` under `[tool.rair]`:
|
|
172
|
+
|
|
173
|
+
**.rair.toml:**
|
|
174
|
+
```toml
|
|
175
|
+
archive_dir = "rairarchive"
|
|
176
|
+
input_glob = ["data/*.csv", "cache/*.pkl"]
|
|
177
|
+
output_glob = ["results/*.json", "logs/*.txt"]
|
|
178
|
+
exclude_glob = ["data/temp/*"]
|
|
179
|
+
autodata_dir = "./data"
|
|
180
|
+
capture_output = true
|
|
181
|
+
auto_discover = true # Enable auto-discovery (default)
|
|
182
|
+
output_files_in_run = false # Create hardlinks to outputs in run folder
|
|
183
|
+
default_command = "make" # Default command when no script specified
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
**pyproject.toml:**
|
|
187
|
+
```toml
|
|
188
|
+
[tool.rair]
|
|
189
|
+
archive_dir = "rairarchive"
|
|
190
|
+
input = ["data/*.csv", "cache/*.pkl"]
|
|
191
|
+
output = ["results/*.json", "logs/*.txt"]
|
|
192
|
+
exclude = ["data/temp/*"]
|
|
193
|
+
autodata_dir = "./data"
|
|
194
|
+
capture_output = true
|
|
195
|
+
auto_discover = true # Enable auto-discovery
|
|
196
|
+
output_files_in_run = false # Create hardlinks to outputs in run folder
|
|
197
|
+
default_command = "make" # Default command when no script specified
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### Hierarchical Configuration
|
|
201
|
+
|
|
202
|
+
You can have different configurations for different directories:
|
|
203
|
+
|
|
204
|
+
- A `.rair.toml` in the current directory overrides project-level config
|
|
205
|
+
- Use `rair --setup` in subdirectories to create local configs
|
|
206
|
+
- Run `rair --setup` and choose "(c)urrent directory" or "(p)roject"
|
|
207
|
+
|
|
208
|
+
Example directory structure:
|
|
209
|
+
```
|
|
210
|
+
project/
|
|
211
|
+
├── .rair.toml # Project config
|
|
212
|
+
└── experiments/
|
|
213
|
+
├── .rair.toml # Pverrides project config
|
|
214
|
+
└── train.py
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
## Developer Guide
|
|
218
|
+
|
|
219
|
+
Feedback and contributions are welcome - please open an issue or submit a pull request on GitHub.
|
|
220
|
+
|
|
221
|
+
To get started with development, first clone the repository:
|
|
222
|
+
|
|
223
|
+
```bash
|
|
224
|
+
git clone https://github.com/DLR-Institute-of-Future-Fuels/rair.git
|
|
225
|
+
cd rair
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
You may set up a virtual environment:
|
|
229
|
+
|
|
230
|
+
```bash
|
|
231
|
+
python -m venv .venv
|
|
232
|
+
source .venv/bin/activate # On Windows: `.venv\Scripts\activate`
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
Build and install the package and dev dependencies:
|
|
236
|
+
|
|
237
|
+
```bash
|
|
238
|
+
pip install -e .[dev]
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
Run the tests:
|
|
242
|
+
|
|
243
|
+
```bash
|
|
244
|
+
pytest
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
## License
|
|
248
|
+
|
|
249
|
+
This project is licensed under the MIT license - see the [LICENSE](LICENSE) file for details.
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
rair-0.1.2.dist-info/licenses/LICENSE,sha256=-44BEhO9o75N0ZvyN6c419uw66FZwoeNPZglG1md8JE,1100
|
|
2
|
+
rair-0.1.2.dist-info/METADATA,sha256=brSEURuujPJ8am37FInFASCiZ9mIwhxl3T8lOl5zybU,7979
|
|
3
|
+
rair-0.1.2.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
4
|
+
rair-0.1.2.dist-info/entry_points.txt,sha256=XBFNCDzstOLRtTXB_ozhIJEnqLGeurklA-gCeUCu99w,38
|
|
5
|
+
rair-0.1.2.dist-info/top_level.txt,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
6
|
+
rair-0.1.2.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Nicolas Kruse, German Aerospace Center (DLR)
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|