sync-pilot 0.1.0__tar.gz

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,7 @@
1
+ __pycache__/
2
+ *.pyc
3
+ .venv/
4
+ *.egg-info/
5
+ dist/
6
+ build/
7
+ .eggs/
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Liang Yi
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,127 @@
1
+ Metadata-Version: 2.4
2
+ Name: sync-pilot
3
+ Version: 0.1.0
4
+ Summary: Interactive TUI tool for syncing projects to remote servers via rsync + SSH
5
+ Project-URL: Homepage, https://github.com/cidxb/sync-pilot
6
+ Project-URL: Repository, https://github.com/cidxb/sync-pilot
7
+ Author: Liang Yi
8
+ License-Expression: MIT
9
+ License-File: LICENSE
10
+ Keywords: remote,rsync,ssh,sync,training,tui
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Environment :: Console
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Topic :: System :: Systems Administration
17
+ Classifier: Topic :: Utilities
18
+ Requires-Python: >=3.10
19
+ Requires-Dist: pyyaml>=6.0
20
+ Requires-Dist: rich>=13.0
21
+ Description-Content-Type: text/markdown
22
+
23
+ # sync-pilot
24
+
25
+ 交互式 TUI 工具,通过 rsync + SSH 同步项目到远端服务器。专为 ML/DL 训练工作流设计。
26
+
27
+ Interactive TUI tool for syncing projects to remote servers via rsync + SSH. Built for ML/DL training workflows.
28
+
29
+ ## Features / 功能
30
+
31
+ - **Push/Pull** — rsync 同步代码和 checkpoints
32
+ - **Remote Training** — 一键推送代码 + tmux 启动远端训练,自动加 `uv run` 前缀
33
+ - **Monitor** — GPU 状态、tmux session 输出查看、实时 attach、session 管理
34
+ - **Status** — 项目状态总览(远端目录大小、checkpoint 数量)
35
+ - **Data Push** — 一次性推送大型数据集
36
+ - **i18n** — 自动检测系统语言(中/英),支持 `--lang` 和 `SYNC_PILOT_LANG` 覆盖
37
+
38
+ ## Install / 安装
39
+
40
+ ```bash
41
+ pip install sync-pilot
42
+ # or
43
+ uv add sync-pilot
44
+ ```
45
+
46
+ ## Quick Start / 快速开始
47
+
48
+ ```bash
49
+ # 1. Initialize config in your project directory
50
+ cd /path/to/your/project
51
+ sync-pilot init
52
+
53
+ # 2. Edit sync_config.yaml with your remote server info
54
+ vim sync_config.yaml
55
+
56
+ # 3. Launch interactive TUI
57
+ sync-pilot
58
+ ```
59
+
60
+ ## Usage / 使用
61
+
62
+ ```bash
63
+ sync-pilot # Interactive TUI menu
64
+ sync-pilot init # Generate config files in current directory
65
+ sync-pilot push # Push code to remote
66
+ sync-pilot pull # Pull checkpoints from remote
67
+ sync-pilot train # Push + launch remote training
68
+ sync-pilot push-data # One-time data upload
69
+ sync-pilot watch # Monitor GPU & tmux sessions
70
+ sync-pilot status # Project status overview
71
+ ```
72
+
73
+ ### Options
74
+
75
+ ```
76
+ -c, --config FILE Config file path (default: auto-detect)
77
+ -p, --project NAME Target project name
78
+ --lang zh|en Force UI language
79
+ -V, --version Show version
80
+ ```
81
+
82
+ ## Configuration / 配置
83
+
84
+ `sync_config.yaml`:
85
+
86
+ ```yaml
87
+ remote_host: 1.2.3.4
88
+ remote_user: root
89
+ remote_port: 22 # Optional, default 22
90
+
91
+ projects:
92
+ my_project:
93
+ description: "My ML project"
94
+ local_path: /home/user/workspace/project/
95
+ remote_path: /mnt/workspace/project/
96
+ exclude_file: rsync_exclude.txt # Relative to this config file
97
+ use_uv: true # Auto-prefix python commands with uv run
98
+ pull_directories:
99
+ - checkpoints/
100
+ checkpoint_patterns: # For status search (default: *.pth, *.pt)
101
+ - "*.pth"
102
+ - "*.safetensors"
103
+
104
+ training_data:
105
+ description: "Training dataset (32GB)"
106
+ local_path: /home/user/data/
107
+ remote_path: /mnt/data/
108
+ pull_only: true # Prevent accidental push
109
+ ```
110
+
111
+ ### Config file auto-detection
112
+
113
+ sync-pilot looks for config files in this order:
114
+ 1. `sync_config.yaml`
115
+ 2. `sync-pilot.yaml`
116
+ 3. `.sync-pilot.yaml`
117
+
118
+ ## Requirements / 依赖
119
+
120
+ - Python >= 3.10
121
+ - `rsync` and `ssh` available on PATH
122
+ - `tmux` on the remote server (for training/watch features)
123
+ - SSH key-based auth configured (recommended)
124
+
125
+ ## License
126
+
127
+ MIT
@@ -0,0 +1,105 @@
1
+ # sync-pilot
2
+
3
+ 交互式 TUI 工具,通过 rsync + SSH 同步项目到远端服务器。专为 ML/DL 训练工作流设计。
4
+
5
+ Interactive TUI tool for syncing projects to remote servers via rsync + SSH. Built for ML/DL training workflows.
6
+
7
+ ## Features / 功能
8
+
9
+ - **Push/Pull** — rsync 同步代码和 checkpoints
10
+ - **Remote Training** — 一键推送代码 + tmux 启动远端训练,自动加 `uv run` 前缀
11
+ - **Monitor** — GPU 状态、tmux session 输出查看、实时 attach、session 管理
12
+ - **Status** — 项目状态总览(远端目录大小、checkpoint 数量)
13
+ - **Data Push** — 一次性推送大型数据集
14
+ - **i18n** — 自动检测系统语言(中/英),支持 `--lang` 和 `SYNC_PILOT_LANG` 覆盖
15
+
16
+ ## Install / 安装
17
+
18
+ ```bash
19
+ pip install sync-pilot
20
+ # or
21
+ uv add sync-pilot
22
+ ```
23
+
24
+ ## Quick Start / 快速开始
25
+
26
+ ```bash
27
+ # 1. Initialize config in your project directory
28
+ cd /path/to/your/project
29
+ sync-pilot init
30
+
31
+ # 2. Edit sync_config.yaml with your remote server info
32
+ vim sync_config.yaml
33
+
34
+ # 3. Launch interactive TUI
35
+ sync-pilot
36
+ ```
37
+
38
+ ## Usage / 使用
39
+
40
+ ```bash
41
+ sync-pilot # Interactive TUI menu
42
+ sync-pilot init # Generate config files in current directory
43
+ sync-pilot push # Push code to remote
44
+ sync-pilot pull # Pull checkpoints from remote
45
+ sync-pilot train # Push + launch remote training
46
+ sync-pilot push-data # One-time data upload
47
+ sync-pilot watch # Monitor GPU & tmux sessions
48
+ sync-pilot status # Project status overview
49
+ ```
50
+
51
+ ### Options
52
+
53
+ ```
54
+ -c, --config FILE Config file path (default: auto-detect)
55
+ -p, --project NAME Target project name
56
+ --lang zh|en Force UI language
57
+ -V, --version Show version
58
+ ```
59
+
60
+ ## Configuration / 配置
61
+
62
+ `sync_config.yaml`:
63
+
64
+ ```yaml
65
+ remote_host: 1.2.3.4
66
+ remote_user: root
67
+ remote_port: 22 # Optional, default 22
68
+
69
+ projects:
70
+ my_project:
71
+ description: "My ML project"
72
+ local_path: /home/user/workspace/project/
73
+ remote_path: /mnt/workspace/project/
74
+ exclude_file: rsync_exclude.txt # Relative to this config file
75
+ use_uv: true # Auto-prefix python commands with uv run
76
+ pull_directories:
77
+ - checkpoints/
78
+ checkpoint_patterns: # For status search (default: *.pth, *.pt)
79
+ - "*.pth"
80
+ - "*.safetensors"
81
+
82
+ training_data:
83
+ description: "Training dataset (32GB)"
84
+ local_path: /home/user/data/
85
+ remote_path: /mnt/data/
86
+ pull_only: true # Prevent accidental push
87
+ ```
88
+
89
+ ### Config file auto-detection
90
+
91
+ sync-pilot looks for config files in this order:
92
+ 1. `sync_config.yaml`
93
+ 2. `sync-pilot.yaml`
94
+ 3. `.sync-pilot.yaml`
95
+
96
+ ## Requirements / 依赖
97
+
98
+ - Python >= 3.10
99
+ - `rsync` and `ssh` available on PATH
100
+ - `tmux` on the remote server (for training/watch features)
101
+ - SSH key-based auth configured (recommended)
102
+
103
+ ## License
104
+
105
+ MIT
@@ -0,0 +1,33 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "sync-pilot"
7
+ version = "0.1.0"
8
+ description = "Interactive TUI tool for syncing projects to remote servers via rsync + SSH"
9
+ readme = "README.md"
10
+ license = "MIT"
11
+ requires-python = ">=3.10"
12
+ authors = [{ name = "Liang Yi" }]
13
+ keywords = ["rsync", "ssh", "sync", "tui", "remote", "training"]
14
+ classifiers = [
15
+ "Development Status :: 4 - Beta",
16
+ "Environment :: Console",
17
+ "Intended Audience :: Developers",
18
+ "License :: OSI Approved :: MIT License",
19
+ "Programming Language :: Python :: 3",
20
+ "Topic :: System :: Systems Administration",
21
+ "Topic :: Utilities",
22
+ ]
23
+ dependencies = [
24
+ "pyyaml>=6.0",
25
+ "rich>=13.0",
26
+ ]
27
+
28
+ [project.scripts]
29
+ sync-pilot = "sync_pilot.cli:main"
30
+
31
+ [project.urls]
32
+ Homepage = "https://github.com/cidxb/sync-pilot"
33
+ Repository = "https://github.com/cidxb/sync-pilot"
@@ -0,0 +1,3 @@
1
+ """sync-pilot: Interactive TUI tool for syncing projects to remote servers."""
2
+
3
+ __version__ = "0.1.0"
@@ -0,0 +1,113 @@
1
+ """CLI entry point for sync-pilot."""
2
+
3
+ import os
4
+ import sys
5
+ import shutil
6
+ import argparse
7
+ from importlib import resources
8
+
9
+ from rich.console import Console
10
+
11
+ from . import __version__
12
+ from .i18n import t, set_locale
13
+ from .core import (
14
+ find_config,
15
+ load_config,
16
+ interactive_menu,
17
+ action_push,
18
+ action_pull,
19
+ action_train,
20
+ action_push_data,
21
+ action_watch,
22
+ action_status,
23
+ console,
24
+ )
25
+
26
+
27
+ def action_init():
28
+ """Generate default config files in CWD."""
29
+ template_dir = resources.files("sync_pilot") / "templates"
30
+ files = ["sync_config.yaml", "rsync_exclude.txt"]
31
+
32
+ for fname in files:
33
+ dest = os.path.join(os.getcwd(), fname)
34
+ if os.path.exists(dest):
35
+ console.print(f"[yellow]{t('config_exists', path=fname)}[/yellow]")
36
+ continue
37
+
38
+ src = template_dir / fname
39
+ with resources.as_file(src) as src_path:
40
+ shutil.copy2(str(src_path), dest)
41
+ console.print(f"[green]{t('config_created', path=fname)}[/green]")
42
+
43
+ console.print(f"\n{t('init_done')}")
44
+
45
+
46
+ def main():
47
+ parser = argparse.ArgumentParser(
48
+ prog="sync-pilot",
49
+ description="Interactive TUI for syncing projects to remote servers via rsync + SSH",
50
+ )
51
+ parser.add_argument(
52
+ "-V", "--version",
53
+ action="version",
54
+ version=f"sync-pilot {__version__}",
55
+ )
56
+ parser.add_argument(
57
+ "action",
58
+ nargs="?",
59
+ default=None,
60
+ choices=["init", "push", "pull", "train", "push-data", "watch", "status"],
61
+ help="Action to execute (omit for interactive menu)",
62
+ )
63
+ parser.add_argument(
64
+ "command",
65
+ nargs="?",
66
+ default=None,
67
+ help="Training command (only for 'train' action)",
68
+ )
69
+ parser.add_argument("--project", "-p", default=None, help="Project name")
70
+ parser.add_argument("--config", "-c", default=None, help="Config file path")
71
+ parser.add_argument("--lang", default=None, choices=["zh", "en"], help="Force UI language")
72
+
73
+ args = parser.parse_args()
74
+
75
+ # Language override
76
+ if args.lang:
77
+ set_locale(args.lang)
78
+
79
+ # init doesn't need config
80
+ if args.action == "init":
81
+ action_init()
82
+ return
83
+
84
+ config_path = find_config(args.config)
85
+ config = load_config(config_path)
86
+
87
+ if args.action is None:
88
+ interactive_menu(config)
89
+ elif args.action == "push":
90
+ action_push(config, args.project)
91
+ elif args.action == "pull":
92
+ action_pull(config, args.project)
93
+ elif args.action == "train":
94
+ action_train(config, command=args.command, project_name=args.project)
95
+ elif args.action == "push-data":
96
+ project = args.project
97
+ if project is None:
98
+ for name, proj in config["projects"].items():
99
+ if proj.get("pull_only") and not proj.get("pull_directories") and not proj.get("pull_directory"):
100
+ project = name
101
+ break
102
+ if project is None:
103
+ console.print(f"[yellow]{t('specify_data_project')}[/yellow]")
104
+ sys.exit(1)
105
+ action_push_data(config, project)
106
+ elif args.action == "watch":
107
+ action_watch(config)
108
+ elif args.action == "status":
109
+ action_status(config)
110
+
111
+
112
+ if __name__ == "__main__":
113
+ main()