train-notifier 1.0.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.
- train_notifier-1.0.0/LICENSE +21 -0
- train_notifier-1.0.0/PKG-INFO +90 -0
- train_notifier-1.0.0/README.md +70 -0
- train_notifier-1.0.0/pyproject.toml +29 -0
- train_notifier-1.0.0/setup.cfg +4 -0
- train_notifier-1.0.0/src/notifier/__init__.py +4 -0
- train_notifier-1.0.0/src/notifier/notifier.py +217 -0
- train_notifier-1.0.0/src/train_notifier.egg-info/PKG-INFO +90 -0
- train_notifier-1.0.0/src/train_notifier.egg-info/SOURCES.txt +10 -0
- train_notifier-1.0.0/src/train_notifier.egg-info/dependency_links.txt +1 -0
- train_notifier-1.0.0/src/train_notifier.egg-info/requires.txt +2 -0
- train_notifier-1.0.0/src/train_notifier.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 hjz
|
|
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,90 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: train-notifier
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: 训练任务邮件通知工具,支持模板和系统信息自动附带
|
|
5
|
+
Author-email: hjz <1912285210@qq.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/hjz/train-notifier
|
|
8
|
+
Keywords: notifier,email,training,machine-learning
|
|
9
|
+
Classifier: Development Status :: 4 - Beta
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
14
|
+
Requires-Python: >=3.8
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
License-File: LICENSE
|
|
17
|
+
Requires-Dist: apprise>=1.0.0
|
|
18
|
+
Requires-Dist: python-dotenv>=0.19.0
|
|
19
|
+
Dynamic: license-file
|
|
20
|
+
|
|
21
|
+
# train-notifier
|
|
22
|
+
|
|
23
|
+
训练任务邮件通知工具,支持模板和系统信息自动附带。
|
|
24
|
+
|
|
25
|
+
## 安装
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
pip install train-notifier
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## 快速使用
|
|
32
|
+
|
|
33
|
+
### 1. 创建 `.env` 文件
|
|
34
|
+
|
|
35
|
+
```env
|
|
36
|
+
SMTP_SERVER=smtp.qq.com
|
|
37
|
+
SMTP_PORT=465
|
|
38
|
+
SMTP_USER=你的邮箱@qq.com
|
|
39
|
+
SMTP_PASS=你的授权码
|
|
40
|
+
RECV_EMAIL=收件邮箱@qq.com
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### 2. 代码调用
|
|
44
|
+
|
|
45
|
+
```python
|
|
46
|
+
from notifier import Notifier
|
|
47
|
+
|
|
48
|
+
n = Notifier()
|
|
49
|
+
|
|
50
|
+
# 自定义通知
|
|
51
|
+
n.notify(title="标题", body="内容")
|
|
52
|
+
|
|
53
|
+
# 训练完成(无参数)
|
|
54
|
+
n.train_done()
|
|
55
|
+
|
|
56
|
+
# 训练出错
|
|
57
|
+
n.train_error(message="CUDA out of memory")
|
|
58
|
+
|
|
59
|
+
# Epoch 进度
|
|
60
|
+
n.epoch_done(epoch=3, total=10, loss=0.0234)
|
|
61
|
+
|
|
62
|
+
# 任务完成
|
|
63
|
+
n.task_done(task_name="数据预处理")
|
|
64
|
+
|
|
65
|
+
# 自定义提醒
|
|
66
|
+
n.alert(message="GPU 温度过高!")
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## 函数列表
|
|
70
|
+
|
|
71
|
+
| 函数 | 参数 | 说明 |
|
|
72
|
+
|------|------|------|
|
|
73
|
+
| `notify(title, body)` | 标题, 内容 | 自定义通知 |
|
|
74
|
+
| `train_done()` | 无 | 训练完成 |
|
|
75
|
+
| `train_error(message)` | 错误信息 | 训练出错 |
|
|
76
|
+
| `epoch_done(epoch, total, loss)` | 轮数, 总轮数, 损失值 | Epoch 完成 |
|
|
77
|
+
| `task_done(task_name)` | 任务名称 | 任务完成 |
|
|
78
|
+
| `alert(message)` | 提醒内容 | 自定义提醒 |
|
|
79
|
+
|
|
80
|
+
## 邮件样式
|
|
81
|
+
|
|
82
|
+
每封邮件包含:
|
|
83
|
+
- 紫色渐变头部
|
|
84
|
+
- 称呼:尊敬的训练师
|
|
85
|
+
- 内容区(左侧色条高亮)
|
|
86
|
+
- 系统信息(时间、主机、系统、Python 版本)
|
|
87
|
+
|
|
88
|
+
## 许可证
|
|
89
|
+
|
|
90
|
+
MIT
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# train-notifier
|
|
2
|
+
|
|
3
|
+
训练任务邮件通知工具,支持模板和系统信息自动附带。
|
|
4
|
+
|
|
5
|
+
## 安装
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install train-notifier
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## 快速使用
|
|
12
|
+
|
|
13
|
+
### 1. 创建 `.env` 文件
|
|
14
|
+
|
|
15
|
+
```env
|
|
16
|
+
SMTP_SERVER=smtp.qq.com
|
|
17
|
+
SMTP_PORT=465
|
|
18
|
+
SMTP_USER=你的邮箱@qq.com
|
|
19
|
+
SMTP_PASS=你的授权码
|
|
20
|
+
RECV_EMAIL=收件邮箱@qq.com
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### 2. 代码调用
|
|
24
|
+
|
|
25
|
+
```python
|
|
26
|
+
from notifier import Notifier
|
|
27
|
+
|
|
28
|
+
n = Notifier()
|
|
29
|
+
|
|
30
|
+
# 自定义通知
|
|
31
|
+
n.notify(title="标题", body="内容")
|
|
32
|
+
|
|
33
|
+
# 训练完成(无参数)
|
|
34
|
+
n.train_done()
|
|
35
|
+
|
|
36
|
+
# 训练出错
|
|
37
|
+
n.train_error(message="CUDA out of memory")
|
|
38
|
+
|
|
39
|
+
# Epoch 进度
|
|
40
|
+
n.epoch_done(epoch=3, total=10, loss=0.0234)
|
|
41
|
+
|
|
42
|
+
# 任务完成
|
|
43
|
+
n.task_done(task_name="数据预处理")
|
|
44
|
+
|
|
45
|
+
# 自定义提醒
|
|
46
|
+
n.alert(message="GPU 温度过高!")
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## 函数列表
|
|
50
|
+
|
|
51
|
+
| 函数 | 参数 | 说明 |
|
|
52
|
+
|------|------|------|
|
|
53
|
+
| `notify(title, body)` | 标题, 内容 | 自定义通知 |
|
|
54
|
+
| `train_done()` | 无 | 训练完成 |
|
|
55
|
+
| `train_error(message)` | 错误信息 | 训练出错 |
|
|
56
|
+
| `epoch_done(epoch, total, loss)` | 轮数, 总轮数, 损失值 | Epoch 完成 |
|
|
57
|
+
| `task_done(task_name)` | 任务名称 | 任务完成 |
|
|
58
|
+
| `alert(message)` | 提醒内容 | 自定义提醒 |
|
|
59
|
+
|
|
60
|
+
## 邮件样式
|
|
61
|
+
|
|
62
|
+
每封邮件包含:
|
|
63
|
+
- 紫色渐变头部
|
|
64
|
+
- 称呼:尊敬的训练师
|
|
65
|
+
- 内容区(左侧色条高亮)
|
|
66
|
+
- 系统信息(时间、主机、系统、Python 版本)
|
|
67
|
+
|
|
68
|
+
## 许可证
|
|
69
|
+
|
|
70
|
+
MIT
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "train-notifier"
|
|
7
|
+
version = "1.0.0"
|
|
8
|
+
description = "训练任务邮件通知工具,支持模板和系统信息自动附带"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = {text = "MIT"}
|
|
11
|
+
requires-python = ">=3.8"
|
|
12
|
+
authors = [
|
|
13
|
+
{name = "hjz", email = "1912285210@qq.com"}
|
|
14
|
+
]
|
|
15
|
+
keywords = ["notifier", "email", "training", "machine-learning"]
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Development Status :: 4 - Beta",
|
|
18
|
+
"Intended Audience :: Developers",
|
|
19
|
+
"License :: OSI Approved :: MIT License",
|
|
20
|
+
"Programming Language :: Python :: 3",
|
|
21
|
+
"Topic :: Software Development :: Libraries",
|
|
22
|
+
]
|
|
23
|
+
dependencies = [
|
|
24
|
+
"apprise>=1.0.0",
|
|
25
|
+
"python-dotenv>=0.19.0",
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
[project.urls]
|
|
29
|
+
Homepage = "https://github.com/hjz/train-notifier"
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
"""
|
|
2
|
+
train-notifier - 训练任务邮件通知工具
|
|
3
|
+
|
|
4
|
+
使用方法:
|
|
5
|
+
from notifier import Notifier
|
|
6
|
+
|
|
7
|
+
n = Notifier()
|
|
8
|
+
|
|
9
|
+
# 自定义通知
|
|
10
|
+
n.notify(title="标题", body="内容")
|
|
11
|
+
|
|
12
|
+
# 训练完成(无参数)
|
|
13
|
+
n.train_done()
|
|
14
|
+
|
|
15
|
+
# 训练出错
|
|
16
|
+
n.train_error(message="CUDA out of memory")
|
|
17
|
+
|
|
18
|
+
# Epoch 进度
|
|
19
|
+
n.epoch_done(epoch=3, total=10, loss=0.0234)
|
|
20
|
+
|
|
21
|
+
# 任务完成
|
|
22
|
+
n.task_done(task_name="数据预处理")
|
|
23
|
+
|
|
24
|
+
# 自定义提醒
|
|
25
|
+
n.alert(message="GPU 温度过高!")
|
|
26
|
+
|
|
27
|
+
函数列表:
|
|
28
|
+
notify(title, body) 自定义通知
|
|
29
|
+
train_done() 训练完成(无参数)
|
|
30
|
+
train_error(message="未知错误") 训练出错
|
|
31
|
+
epoch_done(epoch, total, loss) Epoch 完成
|
|
32
|
+
task_done(task_name) 任务完成
|
|
33
|
+
alert(message) 自定义提醒
|
|
34
|
+
|
|
35
|
+
.env 配置:
|
|
36
|
+
SMTP_SERVER=smtp.qq.com SMTP 服务器地址
|
|
37
|
+
SMTP_PORT=465 端口号
|
|
38
|
+
SMTP_USER=你的邮箱@qq.com 发件邮箱
|
|
39
|
+
SMTP_PASS=你的授权码 邮箱授权码(非登录密码)
|
|
40
|
+
RECV_EMAIL=收件邮箱@qq.com 收件邮箱
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
import apprise
|
|
44
|
+
from dotenv import load_dotenv
|
|
45
|
+
import os
|
|
46
|
+
import platform
|
|
47
|
+
from datetime import datetime
|
|
48
|
+
|
|
49
|
+
load_dotenv()
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class Notifier:
|
|
53
|
+
"""邮件通知工具类
|
|
54
|
+
|
|
55
|
+
每封邮件自动附带: 称呼、时间、主机名、系统版本、Python 版本
|
|
56
|
+
|
|
57
|
+
函数列表:
|
|
58
|
+
notify(title, body) 自定义通知
|
|
59
|
+
train_done() 训练完成(无参数)
|
|
60
|
+
train_error(message="未知错误") 训练出错
|
|
61
|
+
epoch_done(epoch, total, loss) Epoch 完成
|
|
62
|
+
task_done(task_name) 任务完成
|
|
63
|
+
alert(message) 自定义提醒
|
|
64
|
+
"""
|
|
65
|
+
|
|
66
|
+
REQUIRED = ["SMTP_SERVER", "SMTP_PORT", "SMTP_USER", "SMTP_PASS", "RECV_EMAIL"]
|
|
67
|
+
|
|
68
|
+
def __init__(self):
|
|
69
|
+
"""初始化,从 .env 加载配置,缺失时抛出异常"""
|
|
70
|
+
self.smtp_server = os.getenv("SMTP_SERVER")
|
|
71
|
+
self.smtp_port = os.getenv("SMTP_PORT")
|
|
72
|
+
self.smtp_user = os.getenv("SMTP_USER")
|
|
73
|
+
self.smtp_pass = os.getenv("SMTP_PASS")
|
|
74
|
+
self.recv_email = os.getenv("RECV_EMAIL")
|
|
75
|
+
|
|
76
|
+
# 检查缺失或为空的配置
|
|
77
|
+
missing = [k for k in self.REQUIRED if not os.getenv(k)]
|
|
78
|
+
if missing:
|
|
79
|
+
example = (
|
|
80
|
+
"\n请在 .env 文件中补全以下配置:\n"
|
|
81
|
+
"SMTP_SERVER=smtp.qq.com\n"
|
|
82
|
+
"SMTP_PORT=465\n"
|
|
83
|
+
"SMTP_USER=你的邮箱@qq.com\n"
|
|
84
|
+
"SMTP_PASS=你的授权码\n"
|
|
85
|
+
"RECV_EMAIL=收件邮箱@qq.com"
|
|
86
|
+
)
|
|
87
|
+
raise ValueError(f".env 缺少以下配置: {missing}{example}")
|
|
88
|
+
|
|
89
|
+
def _build_html(self, body: str) -> str:
|
|
90
|
+
"""构建 HTML 邮件内容"""
|
|
91
|
+
now = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
|
92
|
+
return f"""
|
|
93
|
+
<div style="font-family: 'Microsoft YaHei', Arial, sans-serif; max-width: 600px; margin: 0 auto; padding: 20px; background: #f5f5f5;">
|
|
94
|
+
<div style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); padding: 20px; border-radius: 10px 10px 0 0; text-align: center;">
|
|
95
|
+
<h2 style="color: white; margin: 0;">📬 训练通知</h2>
|
|
96
|
+
</div>
|
|
97
|
+
|
|
98
|
+
<div style="background: white; padding: 25px; border-radius: 0 0 10px 10px; box-shadow: 0 2px 10px rgba(0,0,0,0.1);">
|
|
99
|
+
<p style="font-size: 16px; color: #333;">尊敬的训练师,</p>
|
|
100
|
+
|
|
101
|
+
<div style="background: #f8f9fa; padding: 15px; border-left: 4px solid #667eea; margin: 15px 0; border-radius: 0 5px 5px 0;">
|
|
102
|
+
<p style="margin: 0; color: #555; font-size: 15px;">{body}</p>
|
|
103
|
+
</div>
|
|
104
|
+
|
|
105
|
+
<hr style="border: none; border-top: 1px dashed #ddd; margin: 20px 0;">
|
|
106
|
+
|
|
107
|
+
<div style="font-size: 13px; color: #888; line-height: 1.8;">
|
|
108
|
+
<p style="margin: 5px 0;">⏰ <b>时间:</b>{now}</p>
|
|
109
|
+
<p style="margin: 5px 0;">💻 <b>主机:</b>{platform.node()}</p>
|
|
110
|
+
<p style="margin: 5px 0;">🖥️ <b>系统:</b>{platform.system()} {platform.release()}</p>
|
|
111
|
+
<p style="margin: 5px 0;">🐍 <b>Python:</b>{platform.python_version()}</p>
|
|
112
|
+
</div>
|
|
113
|
+
</div>
|
|
114
|
+
|
|
115
|
+
<p style="text-align: center; font-size: 12px; color: #aaa; margin-top: 15px;">
|
|
116
|
+
此邮件由 train-notifier 自动发送
|
|
117
|
+
</p>
|
|
118
|
+
</div>
|
|
119
|
+
"""
|
|
120
|
+
|
|
121
|
+
def _send(self, title: str, body: str) -> bool:
|
|
122
|
+
"""内部发送方法"""
|
|
123
|
+
html = self._build_html(body)
|
|
124
|
+
|
|
125
|
+
ap = apprise.Apprise()
|
|
126
|
+
ap.add(f"mailtos://{self.recv_email}:{self.smtp_port}?smtp={self.smtp_server}&user={self.smtp_user}&pass={self.smtp_pass}&mode=ssl")
|
|
127
|
+
|
|
128
|
+
result = ap.notify(title=title, body=html)
|
|
129
|
+
|
|
130
|
+
if not result:
|
|
131
|
+
print("❌ 邮件发送失败,请检查 .env 配置")
|
|
132
|
+
|
|
133
|
+
return result
|
|
134
|
+
|
|
135
|
+
def notify(self, title: str, body: str) -> bool:
|
|
136
|
+
"""自定义通知
|
|
137
|
+
|
|
138
|
+
Args:
|
|
139
|
+
title: 邮件标题
|
|
140
|
+
body: 邮件内容
|
|
141
|
+
|
|
142
|
+
Returns:
|
|
143
|
+
bool: True=成功, False=失败
|
|
144
|
+
|
|
145
|
+
Example:
|
|
146
|
+
n.notify("自定义标题", "随便写点内容")
|
|
147
|
+
"""
|
|
148
|
+
return self._send(title, body)
|
|
149
|
+
|
|
150
|
+
def train_done(self) -> bool:
|
|
151
|
+
"""训练完成通知(无参数)
|
|
152
|
+
|
|
153
|
+
Returns:
|
|
154
|
+
bool: True=成功, False=失败
|
|
155
|
+
|
|
156
|
+
Example:
|
|
157
|
+
n.train_done()
|
|
158
|
+
"""
|
|
159
|
+
return self._send("🎉 训练完成", "✅ 模型训练已全部结束,请查看结果。")
|
|
160
|
+
|
|
161
|
+
def train_error(self, message: str = "未知错误") -> bool:
|
|
162
|
+
"""训练出错通知
|
|
163
|
+
|
|
164
|
+
Args:
|
|
165
|
+
message: 错误信息,默认 "未知错误"
|
|
166
|
+
|
|
167
|
+
Returns:
|
|
168
|
+
bool: True=成功, False=失败
|
|
169
|
+
|
|
170
|
+
Example:
|
|
171
|
+
n.train_error("CUDA out of memory")
|
|
172
|
+
"""
|
|
173
|
+
return self._send("❌ 训练出错", f"⚠️ 训练过程中发生错误:{message}")
|
|
174
|
+
|
|
175
|
+
def epoch_done(self, epoch: int, total: int, loss: float) -> bool:
|
|
176
|
+
"""Epoch 完成通知
|
|
177
|
+
|
|
178
|
+
Args:
|
|
179
|
+
epoch: 当前轮数
|
|
180
|
+
total: 总轮数
|
|
181
|
+
loss: 当前损失值
|
|
182
|
+
|
|
183
|
+
Returns:
|
|
184
|
+
bool: True=成功, False=失败
|
|
185
|
+
|
|
186
|
+
Example:
|
|
187
|
+
n.epoch_done(epoch=3, total=10, loss=0.0234)
|
|
188
|
+
"""
|
|
189
|
+
return self._send("📊 Epoch 完成", f"Epoch {epoch}/{total} 已完成,当前 loss: {loss}")
|
|
190
|
+
|
|
191
|
+
def task_done(self, task_name: str) -> bool:
|
|
192
|
+
"""任务完成通知
|
|
193
|
+
|
|
194
|
+
Args:
|
|
195
|
+
task_name: 任务名称
|
|
196
|
+
|
|
197
|
+
Returns:
|
|
198
|
+
bool: True=成功, False=失败
|
|
199
|
+
|
|
200
|
+
Example:
|
|
201
|
+
n.task_done("数据预处理")
|
|
202
|
+
"""
|
|
203
|
+
return self._send("✅ 任务完成", f"任务 \"{task_name}\" 已执行完毕。")
|
|
204
|
+
|
|
205
|
+
def alert(self, message: str) -> bool:
|
|
206
|
+
"""自定义提醒
|
|
207
|
+
|
|
208
|
+
Args:
|
|
209
|
+
message: 提醒内容
|
|
210
|
+
|
|
211
|
+
Returns:
|
|
212
|
+
bool: True=成功, False=失败
|
|
213
|
+
|
|
214
|
+
Example:
|
|
215
|
+
n.alert("GPU 温度过高!")
|
|
216
|
+
"""
|
|
217
|
+
return self._send("🔔 提醒", message)
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: train-notifier
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: 训练任务邮件通知工具,支持模板和系统信息自动附带
|
|
5
|
+
Author-email: hjz <1912285210@qq.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/hjz/train-notifier
|
|
8
|
+
Keywords: notifier,email,training,machine-learning
|
|
9
|
+
Classifier: Development Status :: 4 - Beta
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
14
|
+
Requires-Python: >=3.8
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
License-File: LICENSE
|
|
17
|
+
Requires-Dist: apprise>=1.0.0
|
|
18
|
+
Requires-Dist: python-dotenv>=0.19.0
|
|
19
|
+
Dynamic: license-file
|
|
20
|
+
|
|
21
|
+
# train-notifier
|
|
22
|
+
|
|
23
|
+
训练任务邮件通知工具,支持模板和系统信息自动附带。
|
|
24
|
+
|
|
25
|
+
## 安装
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
pip install train-notifier
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## 快速使用
|
|
32
|
+
|
|
33
|
+
### 1. 创建 `.env` 文件
|
|
34
|
+
|
|
35
|
+
```env
|
|
36
|
+
SMTP_SERVER=smtp.qq.com
|
|
37
|
+
SMTP_PORT=465
|
|
38
|
+
SMTP_USER=你的邮箱@qq.com
|
|
39
|
+
SMTP_PASS=你的授权码
|
|
40
|
+
RECV_EMAIL=收件邮箱@qq.com
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### 2. 代码调用
|
|
44
|
+
|
|
45
|
+
```python
|
|
46
|
+
from notifier import Notifier
|
|
47
|
+
|
|
48
|
+
n = Notifier()
|
|
49
|
+
|
|
50
|
+
# 自定义通知
|
|
51
|
+
n.notify(title="标题", body="内容")
|
|
52
|
+
|
|
53
|
+
# 训练完成(无参数)
|
|
54
|
+
n.train_done()
|
|
55
|
+
|
|
56
|
+
# 训练出错
|
|
57
|
+
n.train_error(message="CUDA out of memory")
|
|
58
|
+
|
|
59
|
+
# Epoch 进度
|
|
60
|
+
n.epoch_done(epoch=3, total=10, loss=0.0234)
|
|
61
|
+
|
|
62
|
+
# 任务完成
|
|
63
|
+
n.task_done(task_name="数据预处理")
|
|
64
|
+
|
|
65
|
+
# 自定义提醒
|
|
66
|
+
n.alert(message="GPU 温度过高!")
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## 函数列表
|
|
70
|
+
|
|
71
|
+
| 函数 | 参数 | 说明 |
|
|
72
|
+
|------|------|------|
|
|
73
|
+
| `notify(title, body)` | 标题, 内容 | 自定义通知 |
|
|
74
|
+
| `train_done()` | 无 | 训练完成 |
|
|
75
|
+
| `train_error(message)` | 错误信息 | 训练出错 |
|
|
76
|
+
| `epoch_done(epoch, total, loss)` | 轮数, 总轮数, 损失值 | Epoch 完成 |
|
|
77
|
+
| `task_done(task_name)` | 任务名称 | 任务完成 |
|
|
78
|
+
| `alert(message)` | 提醒内容 | 自定义提醒 |
|
|
79
|
+
|
|
80
|
+
## 邮件样式
|
|
81
|
+
|
|
82
|
+
每封邮件包含:
|
|
83
|
+
- 紫色渐变头部
|
|
84
|
+
- 称呼:尊敬的训练师
|
|
85
|
+
- 内容区(左侧色条高亮)
|
|
86
|
+
- 系统信息(时间、主机、系统、Python 版本)
|
|
87
|
+
|
|
88
|
+
## 许可证
|
|
89
|
+
|
|
90
|
+
MIT
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
src/notifier/__init__.py
|
|
5
|
+
src/notifier/notifier.py
|
|
6
|
+
src/train_notifier.egg-info/PKG-INFO
|
|
7
|
+
src/train_notifier.egg-info/SOURCES.txt
|
|
8
|
+
src/train_notifier.egg-info/dependency_links.txt
|
|
9
|
+
src/train_notifier.egg-info/requires.txt
|
|
10
|
+
src/train_notifier.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
notifier
|