Metadata-Version: 2.4
Name: cfgedit
Version: 0.1.3
Summary: 本地运行的 Python dataclass 配置可视化编辑器
Author: zuyeto
License: MIT
License-File: LICENSE
Keywords: config,configuration,dataclass,editor,visual
Classifier: Environment :: Web Environment
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
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 :: Software Development :: User Interfaces
Requires-Python: >=3.9
Description-Content-Type: text/markdown

# CFG Editor

[![PyPI version](https://img.shields.io/pypi/v/cfgedit.svg)](https://pypi.org/project/cfgedit/)
[![Python](https://img.shields.io/badge/python-3.9%2B-blue.svg)](https://www.python.org/)
[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)

**中文** | [English](#cfg-editor-english)

一个本地运行的 Python dataclass 配置可视化编辑器。程序会扫描配置目录内的 `.py` 文件，在浏览器中生成可编辑页面，点击保存后把修改写回对应配置文件，只替换字段默认值，不重写整个文件。

> 纯标准库实现，无第三方运行时依赖。

## 目录

- [功能特性](#功能特性)
- [安装](#安装)
- [快速开始](#快速开始)
- [命令行选项](#命令行选项)
- [在代码中调用](#在代码中调用)
- [使用流程](#使用流程)
- [配置文件写法建议](#配置文件写法建议)
- [示例](#示例)
- [模块结构](#模块结构)
- [许可证](#许可证)

## 功能特性

- 自动读取配置目录中 `.py` 文件里的 `@dataclass` 配置类。
- 按配置文件、配置类、字段分组展示，支持搜索字段。
- 支持 `str`、`int`、`float`、`bool`、`list`、`tuple`、`None` 等常见默认值编辑。
- 保留字段旁的行内注释，用作页面说明。
- 保存时只替换字段默认值，不重写整个配置文件。
- 聚合类中的 `field(default_factory=SomeConfig)` 显示为只读提示，具体参数在对应配置类中编辑。

## 安装

从 PyPI 安装：

```bash
pip install cfgedit
```

或从本地源码安装：

```bash
pip install .
```

开发模式（可编辑安装）：

```bash
pip install -e .
```

## 快速开始

安装后会注册 `cfgedit` 命令，在含有配置文件的目录下运行：

```bash
cfgedit
```

启动后默认随机选用一个未占用端口并自动打开浏览器，终端也会打印实际地址：

```text
CFG Editor 已启动: http://127.0.0.1:54321/
```

未安装时也可以直接用源码入口运行：

```bash
python main.py
```

## 命令行选项

| 选项 | 默认值 | 说明 |
| --- | --- | --- |
| `--host` | `127.0.0.1` | 服务监听地址 |
| `--port` | `0` | 服务监听端口，`0` 表示由系统分配未占用的随机端口 |
| `--config-dir` | `./configs` | 配置文件目录 |
| `--check` | — | 只检查配置目录能否被正确解析，不启动服务 |
| `--root-class` | — | 作为结构视图根节点的配置类名 |
| `--root-name` | — | 结构视图中根配置的显示名称 |

示例：

```bash
# 固定端口并指定配置目录
cfgedit --port 8080 --config-dir configs

# 只校验配置目录能否被解析
cfgedit --check
```

## 在代码中调用

也可以在配置主文件里直接启动，自动以传入配置对象所在目录作为配置目录，并以其类作为结构视图根节点：

```python
from cfgedit import start

if __name__ == "__main__":
    config = get_default_config()
    start(config, root_name="我的项目配置")
```

`start()` 常用参数：

| 参数 | 说明 |
| --- | --- |
| `config` | 配置对象，用于自动定位配置目录与根配置类 |
| `host` | 服务监听地址，默认 `127.0.0.1` |
| `port` | 服务监听端口，默认 `0`（随机端口） |
| `config_dir` | 显式指定配置目录，省略时根据 `config` 推断 |
| `root_name` | 结构视图中根配置的显示名称 |
| `root_class` | 作为结构视图根节点的配置类名 |

## 使用流程

1. 运行 `cfgedit`（或未安装时 `python main.py`）。
2. 在网页左侧选择配置类，或用搜索框查找字段。
3. 在右侧编辑参数。
4. 点击 `保存修改`。
5. 程序会把修改写回对应配置文件。

## 配置文件写法建议

推荐使用这种结构：

```python
from dataclasses import dataclass, field


@dataclass
class TrainConfig:
    batch_size: int = 32  # 批大小
    learning_rate: float = 1e-3  # 学习率
    milestones: list[int] = field(default_factory=lambda: [10, 20])
```

当前编辑器主要面向简单的 dataclass 默认值。复杂表达式、函数引用、非 lambda 的 `default_factory` 会被识别但不直接编辑。

## 示例

示例配置位于 [examples/sample_config.py](examples/sample_config.py)。把它复制到任意配置目录，再用 `--config-dir` 指定该目录即可查看页面生成效果：

```bash
cfgedit --config-dir examples
```

## 模块结构

```text
cfgedit/
  __init__.py   包入口，导出 start 与版本号
  cli.py        命令行入口
  app.py        start() 编程式启动接口
  paths.py      项目路径常量
  schema.py     dataclass 配置扫描与字段结构生成
  writer.py     字段值类型转换与写回
  server.py     本地 HTTP 服务与 API
  web.py        内置前端页面
main.py         极简启动入口
```

## 许可证

本项目基于 [MIT License](LICENSE) 发布。

---

# CFG Editor (English)

[中文](#cfg-editor) | **English**

A locally-run visual editor for Python dataclass configurations. The program scans `.py` files inside a config directory, generates an editable page in your browser, and writes changes back to the corresponding config file when you click save — replacing only field default values rather than rewriting the whole file.

> Built purely on the standard library, with no third-party runtime dependencies.

## Table of Contents

- [Features](#features)
- [Installation](#installation)
- [Quick Start](#quick-start)
- [Command-Line Options](#command-line-options)
- [Calling from Code](#calling-from-code)
- [Workflow](#workflow)
- [Config File Conventions](#config-file-conventions)
- [Example](#example)
- [Module Structure](#module-structure)
- [License](#license-1)

## Features

- Automatically reads `@dataclass` config classes from `.py` files in the config directory.
- Displays fields grouped by config file, config class, and field, with field search support.
- Supports editing common default value types such as `str`, `int`, `float`, `bool`, `list`, `tuple`, and `None`.
- Preserves inline comments next to fields, using them as on-page descriptions.
- Replaces only field default values on save, without rewriting the entire config file.
- Shows `field(default_factory=SomeConfig)` in aggregate classes as a read-only hint; the actual parameters are edited in the corresponding config class.

## Installation

Install from PyPI:

```bash
pip install cfgedit
```

Or install from local source:

```bash
pip install .
```

Development mode (editable install):

```bash
pip install -e .
```

## Quick Start

After installation, the `cfgedit` command is registered. Run it in a directory containing config files:

```bash
cfgedit
```

On startup, it picks a random unused port by default and automatically opens your browser. The terminal also prints the actual address:

```text
CFG Editor 已启动: http://127.0.0.1:54321/
```

If not installed, you can also run directly from the source entry point:

```bash
python main.py
```

## Command-Line Options

| Option | Default | Description |
| --- | --- | --- |
| `--host` | `127.0.0.1` | Address the service listens on |
| `--port` | `0` | Port the service listens on; `0` means the system assigns a random unused port |
| `--config-dir` | `./configs` | Config file directory |
| `--check` | — | Only check whether the config directory can be parsed correctly; does not start the service |
| `--root-class` | — | Name of the config class to use as the root node of the structure view |
| `--root-name` | — | Display name of the root config in the structure view |

Examples:

```bash
# Fix the port and specify the config directory
cfgedit --port 8080 --config-dir configs

# Only validate whether the config directory can be parsed
cfgedit --check
```

## Calling from Code

You can also start it directly from your main config file. It automatically uses the directory of the passed-in config object as the config directory and its class as the root node of the structure view:

```python
from cfgedit import start

if __name__ == "__main__":
    config = get_default_config()
    start(config, root_name="My Project Config")
```

Common `start()` parameters:

| Parameter | Description |
| --- | --- |
| `config` | Config object, used to automatically locate the config directory and root config class |
| `host` | Address the service listens on, defaults to `127.0.0.1` |
| `port` | Port the service listens on, defaults to `0` (random port) |
| `config_dir` | Explicitly specify the config directory; inferred from `config` when omitted |
| `root_name` | Display name of the root config in the structure view |
| `root_class` | Name of the config class to use as the root node of the structure view |

## Workflow

1. Run `cfgedit` (or `python main.py` if not installed).
2. Select a config class in the left panel of the page, or use the search box to find a field.
3. Edit the parameters on the right.
4. Click `保存修改` (Save Changes).
5. The program writes the changes back to the corresponding config file.

## Config File Conventions

This structure is recommended:

```python
from dataclasses import dataclass, field


@dataclass
class TrainConfig:
    batch_size: int = 32  # batch size
    learning_rate: float = 1e-3  # learning rate
    milestones: list[int] = field(default_factory=lambda: [10, 20])
```

The current editor mainly targets simple dataclass default values. Complex expressions, function references, and non-lambda `default_factory` are recognized but not directly editable.

## Example

A sample config is located at [examples/sample_config.py](examples/sample_config.py). Copy it into any config directory, then point `--config-dir` at that directory to see how the page is generated:

```bash
cfgedit --config-dir examples
```

## Module Structure

```text
cfgedit/
  __init__.py   Package entry, exports start and version number
  cli.py        Command-line entry
  app.py        start() programmatic launch interface
  paths.py      Project path constants
  schema.py     dataclass config scanning and field structure generation
  writer.py     Field value type conversion and write-back
  server.py     Local HTTP service and API
  web.py        Built-in frontend page
main.py         Minimal launch entry
```

## License

This project is released under the [MIT License](LICENSE).
