Metadata-Version: 2.4
Name: pyruns
Version: 0.1.4
Summary: Lightweight web UI for managing, running, and monitoring Python experiments.
Author-email: LthreeC <lanshiL3C@gmail.com>
License: MIT License
        
        Copyright (c) 2026 Pyruns Contributors
        
        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: Homepage, https://github.com/LthreeC/pyruns
Project-URL: Repository, https://github.com/LthreeC/pyruns
Project-URL: Documentation, https://lthreec.github.io/pyruns
Keywords: experiment-management,hyperparameter-tuning,task-runner,monitoring,nicegui,machine-learning
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Software Development :: User Interfaces
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: nicegui>=1.4
Requires-Dist: pyyaml>=5.4
Requires-Dist: psutil>=5.9
Dynamic: license-file

# pyruns

![logo](docs/assets/pyruns_logo2.png)

**[English](README-en.md) | 简体中文**

<p align="center">
  <img src="https://img.shields.io/pypi/v/pyruns.svg?style=for-the-badge&color=blue" alt="PyPI version">
  <img src="https://img.shields.io/pypi/pyversions/pyruns.svg?style=for-the-badge" alt="Python Versions">
  <img src="https://img.shields.io/badge/License-MIT-green.svg?style=for-the-badge" alt="License">
</p>

<p align="center">
  <b>Python 实验管理 Web UI 工具：参数可视化编辑、网格批量调度、实时日志流式查看与指标聚合导出</b><br>
  <sub>✅ 零侵入兼容 argparse · ✅ 命令行模式兼容任意框架 · ✅ 全流程本地运行</sub>
</p>

Pyruns 为 Python 脚本提供基于本地浏览器的图形界面。其主要功能包括：通过解析 `argparse` 生成可视化设置表单、支持特定语法实现参数网格的批量任务生成、管理并行调度队列，以及在浏览器端提供 ANSI 彩色日志的实时流式输出和跨任务的指标聚合导出。

**无需修改原生业务代码 · 无需注册账号 · 无需联网 · 所有流程均在本地执行**

```bash
pip install pyruns
pyr train.py          
```

> 💡 **仅依赖 3 个包**：`nicegui` + `pyyaml` + `psutil`，安装后即用，不会给你的环境引入"重量级"框架。

---

## 💡 解决的工程痛点

### 痛点 1：超参搜索要靠手写 Bash 循环

**没有 Pyruns 时**——你需要写这种令人头痛的嵌套脚本：
```bash
for lr in 0.001 0.01 0.1; do
  for bs in 32 64 128; do
    for opt in adam sgd; do
      python train.py --lr $lr --batch_size $bs --optimizer $opt \
        > logs/lr${lr}_bs${bs}_${opt}.log 2>&1 &
    done
  done
done
wait
```

**用 Pyruns**——两行声明就等价于上面的 18 个嵌套组合：
```yaml
lr: 0.001 | 0.01 | 0.1
batch_size: 32 | 64 | 128
optimizer: adam | sgd
```
点击 **GENERATE** → 自动创建 18 个隔离任务，每个任务有独立的配置快照和日志目录。

### 痛点 2：实验记录全靠人脑和 Excel

> *"上周跑的那组 lr=0.01 的实验，用的是哪个 batch_size 来着？结果保存在哪了？"*

Pyruns 自动为**每个任务**保存完整的参数快照（`config.yaml`）、运行时间线、PID 记录、以及你随时可以追加的实验笔记。在 Manager 界面，你可以即时搜索、筛选、复用历史任务——再也不用翻文件夹或 grep 日志了。

### 痛点 3：多任务并发时日志混成一团

并发跑 6 个实验，终端输出全部交错在一起？Pyruns 将每个任务的标准输出**完全隔离**到独立日志文件，并在 Monitor 页面提供实时的 ANSI 彩色终端——包括 `tqdm` 进度条都能正确渲染。SSH 断开也不怕，任务在后台持续运行。

---

## ✨ 核心特性

| 特性 | 说明 |
|------|------|
| 🔌 **多框架零侵入解析** | 从源码中提取 `argparse` 定义来渲染 Web UI 表单；亦支持直接基于 `yaml` 文件的配置；**命令行模式可直接运行任意框架的脚本（包括 Hydra、Fire 等）**。 |
| 🧮 **参数网格展开** | 支持使用 `\|` 进行笛卡尔积排列或 `(\|)` 进行配对组合，用于生成批量参数配置集。 |
| ⚡ **独立任务队列** | 内部实现任务队列缓冲，可选 Thread/Process pool 型执行器控制并发规模。 |
| 📋 **状态看板管理** | 对任务进行 Pending/Running/Failed/Completed 状态流转管理，支持对历史配置的搜索与复用。 |
| 🖥️ **流式彩色终端** | 增量返回终端输出并完整支持 ANSI 转义字符渲染（如 `tqdm`）。 |
| 📊 **指标监控聚合** | 提供 `pyruns.record()` 回调，帮助在多组参数实验后导出 CSV/JSON 等合并报告。 |
| 📁 **环境参数快照** | 在 `_pyruns/` 下建立与脚本结构绑定的运行时目录，快照当前环境与参数，防干扰且支持软删除安全机制。 |

> 🎯 **设计理念**：Pyruns 不是一个重量级的实验平台（如 MLflow、W&B），而是一个**开箱即用、轻量化的本地调参助手**。它的目标是让你在**不改变现有工作流**的前提下，用最低的学习成本获得参数管理和实验追踪的便利。

---

## 🚀 启动方式

### 模式 1：基于 Argparse 的脚本接入

无需修改源码。Pyruns 通过 AST 分析器提取源码中 `add_argument` 的参数。

```bash
pyr train.py
```
这会在脚本所在目录下生成 `_pyruns_/train/config_default.yaml`，随后启动本地的 Web 服务（默认监听端口 `8099`）。

### 模式 2：基于 YAML 加载逻辑的接入

若您的源码直接通过读取外部 YAML 配置驱动并在代码内调用 `pyruns.load()`：

```bash
# 首次运行：传入默认参数模板
pyr train.py my_config.yaml  
```
此后，Pyruns 会接管参数调度及其相关环境变量：

```bash
pyr train.py
```

### 模式 3：CLI 命令行交互模式

如果你在无头服务器 (Headless Server) 上运行，或者更偏爱纯命令行操作，Pyruns 提供了一个**与 Web UI 级别完全等同**的 CLI 交互环境。

```bash
pyr cli train.py
```

这会自动构建和 Web UI 完全一样的工作区目录结构和配置，然后进入交互式的 REPL 终端：
```text
  Pyruns CLI  (type 'help' for commands, 'exit' to quit)
pyruns> ls         # 查看当前任务
pyruns> run 1      # 运行指定任务，并自动 stream 输出日志！
pyruns> status -i  # 实时显示系统和 GPU 监控
```
任何通过 CLI 触发的操作和 Web UI 是 100% 数据互通和兼容的。

### 模式 4：命令行模式 / Args 模式（兼容任意框架）

Pyruns 的 **Args 模式** 可以用来管理任意框架的实验。你只需要在生成任务时使用 Args 视图，并在 `run_script` 中填写启动命令：

```yaml
# 示例：管理 Hydra 实验
run_script: "python -m my_project.train"
args: |
  model=vit
  dataset=imagenet
  training.lr=0.001
  training.epochs=300
```

Pyruns 会将 `args` 字段的内容作为命令行参数直接追加到 `run_script` 后面执行。这意味着**无论你的脚本使用 Hydra、Fire、Click 还是任何其他框架**，只要它能通过命令行参数启动，你就可以利用 Pyruns 的批量生成和任务管理能力来管理它。

---

## 📝 实际上手示例

项目的 `examples/` 目录下提供了可直接运行的完整示例脚本，分别对应两种接入模式。

### 示例 1：Argparse 原生支持（零改动接入）

> 对应目录：`examples/1_argparse_script/`

下面是一个标准的 `argparse` 训练脚本，可以直接交给 Pyruns 接管——**无需对原始代码做任何修改**：

```python
# examples/1_argparse_script/main.py
import pyruns
import argparse
import time

def main():
    parser = argparse.ArgumentParser(description="A simple ML training script.")
    parser.add_argument("--lr", type=float, default=0.001, help="Learning rate")
    parser.add_argument("--epochs", type=int, default=10, help="Number of training epochs")
    parser.add_argument("-b", "--batch_size", type=int, default=32, help="Batch size")
    parser.add_argument("--optimizer", type=str, default="adam", choices=["adam", "sgd"])
    args = parser.parse_args()

    print(f"Hyperparameters: LR={args.lr}, Batch Size={args.batch_size}")
    for epoch in range(1, args.epochs + 1):
        time.sleep(0.5)
        loss = 1.0 / (epoch * args.lr * 100)
        print(f"Epoch {epoch}/{args.epochs} - Loss: {loss:.4f}")

    # 可选：记录最终指标，脱离 Pyruns 环境时该调用被静默忽略
    pyruns.record(last_loss=loss)

if __name__ == "__main__":
    main()
```

**使用方式**：

```bash
# Pyruns 自动解析 argparse 参数并启动 Web UI
pyr main.py
```

Pyruns 通过 AST 静态分析自动提取 `add_argument()` 的所有定义（参数名、类型、默认值、help 文本），生成可编辑的 Web UI 表单。用户在界面修改参数后，Pyruns 会以命令行参数的形式将其传递给脚本——脚本本身的 `parse_args()` 逻辑完全不受影响。

### 示例 2：使用 `pyruns.load()` 加载 YAML 配置

> 对应目录：`examples/2_pyruns_config/`

当训练脚本不使用命令行参数、而是直接读取 YAML 配置文件时，可以通过 `pyruns.load()` 完成接入。`load()` 返回的 `ConfigNode` 对象支持点号属性访问，嵌套结构会被自动递归封装：

```python
# examples/2_pyruns_config/main1.py
import pyruns
import time

def main():
    config = pyruns.load()  # 自动绑定当前任务的 config.yaml

    lr = config.lr
    epochs = config.epochs
    optimizer = config.optimizer

    print(f"Hyperparameters: LR={lr}, Optimizer={optimizer}")
    for epoch in range(1, epochs + 1):
        time.sleep(0.5)
        loss = 1.0 / (epoch * lr * 100)
        print(f"Epoch {epoch}/{epochs} - Loss: {loss:.4f}")

if __name__ == "__main__":
    main()
```

配套的默认配置文件 `config1.yaml`：

```yaml
lr: 5e-3
epochs: 20
optimizer: sgd
batch_size: 64
dropout: 0.2
model: resnet50
```

**使用方式**：

```bash
# 首次运行：传入 YAML 模板，Pyruns 将其复制为 config_default.yaml
pyr main1.py config1.yaml

# 后续运行：无需再指定 YAML，Pyruns 自动使用已保存的模板
pyr main1.py
```

此外，`pyruns.load()` 也支持多层嵌套的 YAML 结构。以 `config2.yaml` 为例，项目、模型、训练三级分层的配置可以通过链式点号一路访问到底：

```yaml
# config2.yaml — 三级嵌套结构
project:
  name: "DeepSense_Alpha"
  version: 1.2
  output_dir: "./results"
model:
  type: "Transformer"
  layers: 12
  dropout: 0.1
training:
  hyperparams:
    lr: 0.0005
    epochs: 8
    optimizer: "AdamW"
  resources:
    device: "cuda"
    precision: "fp16"
    gpu_config:
      memory_frac: 0.8
```

在脚本中通过点号链式访问即可读取任意层级的值：

```python
config = pyruns.load()
config.project.name              # "DeepSense_Alpha"
config.training.hyperparams.lr   # 0.0005
config.training.resources.device # "cuda"
```

---

## 🎯 界面模块

### 🔧 Generator — 简洁清晰的参数编辑器
在左侧提供清晰可见的结构化表单控制超参数修改，并支持声明化批量语法；右侧可实时预览将会并行生成的批量实验任务。通过（Pin）功能可以方便地标记核心参数。
![Generator UI](docs/assets/ui_generator_refined.png)

> UI/Performance update: the Generator page now uses a flatter visual system with tighter spacing, smaller corner radii, true lazy tab rendering, and more selective Manager/Monitor refresh behavior.

### 📦 Manager — 便捷的历史任务记录与管理
核心的任务管理面板。能够极其方便地监控、搜索并管理所有生成的任务队列。支持勾选进行并发执行限制；点击进入任务卡片，可查阅其精准的参数快照 (`config.yaml`) 历史记录。
![Manager UI](docs/assets/tab_manager.png)

<details>
<summary><b>🔥 点击查看卡片内部详情弹窗特性</b></summary>

| 特性 | 视图预览 |
| :---: | :---: |
| **生命周期总览**<br>重跑历史与 PIDs 记录 | ![Task Details Info](docs/assets/taskinfo.png) |
| **绝对隔离快照**<br>独享的 `config.yaml` 映射 | ![Task Details Config](docs/assets/config.png) |
| **实验笔记记录**<br>支持随时修改的实验副文本 | ![Task Details Notes](docs/assets/notes.png) |
| **环境变量溯源**<br>完整还原任务启动时的全部系统变量 | ![Task Details Env](docs/assets/env.png) |

</details>

### 📈 Monitor — 实时查看与一键导出报告
将处于活跃状态的任务的标准输流出实时定向到浏览器终端。同时，监视到的任务运行指标（如 Loss、Accuracy 等），在此支持跨任务勾选，一键导出聚合比对报表。
![Monitor UI](docs/assets/tab_monitor.png)

---

## 🧪 批量生成语法

在 Generator 的代码域内支持特定的管道解析语法，用于描述性构建执行计划：

**笛卡尔积组合 `|`** — 全排列组装（如 3 × 2 = 6 个独立任务）：
```yaml
learning_rate: 0.001 | 0.01 | 0.1
batch_size: 32 | 64
```

**一一配对映射 `(|)`** — 等长对应（共 3 个独立任务）：
```yaml
seed: (1 | 2 | 3)
experiment_name: (exp_a | exp_b | exp_c)
```
支持数字序列区间（如：`lr: 1:10:2`）。详细结构规则见 [批量构建语法说明](docs/batch-syntax.md)。

---

## 📂 运行区结构原理

Pyruns 采用隔离持久化策略。针对单一入口脚本所生成的执行缓存符合以下文件树形规约：

```text
your_project/
├── train.py
└── _pyruns_/
    ├── _pyruns_settings.yaml         # 全局端口、并发数相关配制 
    └── train/                        # 对应该脚本的独立命名空间
        ├── script_info.json          # 记录脚本路径与环境依赖
        ├── config_default.yaml       # UI 表单所需的参数初始骨架 
        └── tasks/
            ├── fast_tuning_[1-of-6]/
            │   ├── task_info.json    # 元数据状态机（存放执行PID、启停时间、监控数据等）
            │   ├── config.yaml       # 该任务启动时的确切参数配置切片
            │   └── run_logs/
            │       ├── run1.log      # 主流终端输出
            │       └── error.log     # 非零状态码退出时的标准错误分离堆栈
            └── .trash/               # Manager界面执行的非实质性软删除回收站
```

底层调用逻辑在执行队列发出 Run 信号时生效，执行器将 `config.yaml` 对应路径经由 `__PYRUNS_CONFIG__` 环境变量置入被唤醒的子进程。

---

## 📖 补充文档

| 文档部分 | 说明 |
|------|------|
| [📗 安装部署与初次接入](docs/getting-started.md) | 环境说明与第一个示例运作 |
| [📘 批量语法细则](docs/batch-syntax.md) | 复杂网格规则与类型推断行为 |
| [💻 命令行 CLI 交互控制](docs/cli-guide.md) | 在无头服务器/纯终端使用 REPL 环境管理全部流程的操作详解 |
| [📕 界面高级操作与控制](docs/ui-guide.md) | Manager执行限制细节及报表数据的导出等 |
| [📙 配置流转与沙盒说明](docs/configuration.md) | Node树层级、优先读取顺位判定 |
| [📓 API 接口文档](docs/api-reference.md) | 深入代码端的 `read()` / `load()` 及 `record()` 功能介绍 |

---

## License

MIT
