Metadata-Version: 2.4
Name: naranhi
Version: 0.1.8
Summary: Node-centric Async Runtime for Atomic Networked Hierarchical Infrastructure
Author-email: jihoonkim2100 <kimjihoon2100@gmail.com>
Requires-Python: <3.12,>=3.11
Requires-Dist: joblib==1.5.3
Requires-Dist: tqdm==4.67.3
Description-Content-Type: text/markdown

# Naranhi
## Side-by-Side Orchestration
*Naranhi* (Korean for "Side-by-Side") is a lightweight, declarative framework designed to bridge the gap between local development and massive 2,500+ subject cluster execution. By maintaining a strict boundary between Infrastructure and Science, Naranhi ensures your pipelines are dataset-agnostic, reproducible, and "cluster-aware" without being "cluster-dependent."

## 🏛️ The Orchestral Philosophy
### 1. The Score (`sinfonia.yaml`)
The declarative blueprint defining sensitive information, tasks, and communication channels.
- **Decoupled metadata**: Keep processing parameters via `pipeline_metadata` seprate from execution logic.
- **Integrated Communication**: Built-in Slack notifications via `communication` to monitor swarms in real-time.

### 2. The Maestro (`Conductor`)
A sequential, signal-based controller that manages "Wave Barriers".
- **The Great Freeze**: Automatically clones and anchors your configuration to every analysis session for perfect provenance.
- **Wave Synchronization**: Ensures all parallel "Performers" in a wave finish successfully before proceeding to the next movement.

### 3. The Performer (`src/task/*.py`)
Pure, CLI-ready Python scripts. Using the `TaskContext` manager or `Performer`, your science logic remains clean while Naranhi handles the heavy lifting:
- **Atomic Logging**: Flat-file logging _(O(1) I/O)_ optimized for high-performance filesystems.
- **Automatic Signaling**: Transparently emits `task.finish` or `task.fatal` signals to the Maestro.
- **Error Propagation**: Immediate Slack alerts if a soloist fails in the middle of a swarm.

---
## 🚀 Quick Start(0.1.8)
### 1. Define your Score (`config/the.yaml`)
```yaml
pipeline_metadata:
  name: "ANALYSIS"

communication:
  slack_webhook: "https://hooks.slack.com/..."

analysis_metadata:
  paths:
    root: "/data/project/the_project"

tasks:
  - id: "00"
    name: "load_data"
    script: "the.py"
    wave: 1
```
### 2. Write your Soloist (`src/tasks/the.py`)
option 1. using `@nrh.Performer`
```python
import naranhi as nrh
@nrh.Performer()
def main(logger, config, log_dir):
    ...
```

option 2. using `with nrh.TaskContext() as (logger, config, log_dir):` statement
```python
import naranhi as nrh

def main():
    # The TaskContext handles logging, signals, and Slack automatically
    with nrh.TaskContext() as (logger, config, log_dir):
        logger.info("Performing Science...")
        # Your neuroimaging logic here
        
if __name__ == "__main__":
    main()
```
### 3. Conduct the Symphony
```python
import naranhi as nrh

# Initialize the Maestro with your score
Maestro = nrh.Conductor("config/the.yaml")
Maestro.setup()
Maestro.play()
```
---
## 🛠️ Installation
```bash
uv pip install naranhi
```
---
## ⚖️ License

Copyright (c) 2026 JiHoon Kim. All rights reserved.
Proprietary and confidential.