openbayes-cli 0.4.5__py3-none-any.whl
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.
- bayes/__init__.py +0 -0
- bayes/client/__init__.py +0 -0
- bayes/client/base.py +20 -0
- bayes/client/dataset_version_client.py +91 -0
- bayes/client/gear_client.py +468 -0
- bayes/client/job_run_client.py +504 -0
- bayes/client/job_upload_client.py +114 -0
- bayes/client/org_client.py +67 -0
- bayes/client/resource_client.py +108 -0
- bayes/client/runtime_client.py +32 -0
- bayes/client/ssh_client.py +66 -0
- bayes/client/status_client.py +14 -0
- bayes/client/user_client.py +58 -0
- bayes/commands/__init__.py +0 -0
- bayes/commands/gear.py +691 -0
- bayes/commands/org.py +100 -0
- bayes/commands/ssh.py +70 -0
- bayes/error.py +9 -0
- bayes/model/__init__.py +0 -0
- bayes/model/dataset_version.py +14 -0
- bayes/model/file/__init__.py +0 -0
- bayes/model/file/data_bindings.py +42 -0
- bayes/model/file/openbayes_data.py +133 -0
- bayes/model/file/openbayes_gear.py +72 -0
- bayes/model/file/openbayes_ignore.py +75 -0
- bayes/model/file/openbayes_yaml.py +180 -0
- bayes/model/file/settings.py +157 -0
- bayes/model/party.py +35 -0
- bayes/model/resource.py +147 -0
- bayes/model/runtime.py +34 -0
- bayes/root.py +170 -0
- bayes/templates/openbayes_zh-Hans.yaml +134 -0
- bayes/templates/openbayesignore.yaml +3 -0
- bayes/usercases/__init__.py +0 -0
- bayes/usercases/archive_usecase.py +79 -0
- bayes/usercases/auth_usecase.py +35 -0
- bayes/usercases/dataset_version_usecase.py +61 -0
- bayes/usercases/disk_usecase.py +98 -0
- bayes/usercases/gear_download_usecese.py +113 -0
- bayes/usercases/gear_logs_usecase.py +44 -0
- bayes/usercases/gear_open_usecase.py +16 -0
- bayes/usercases/gear_run_usecase.py +123 -0
- bayes/usercases/gear_upload_usecase.py +248 -0
- bayes/usercases/gear_usecase.py +301 -0
- bayes/usercases/openbayes_data_usecase.py +73 -0
- bayes/usercases/org_usecase.py +85 -0
- bayes/usercases/resource_usecase.py +74 -0
- bayes/usercases/runtime_usecase.py +58 -0
- bayes/usercases/ssh_usecase.py +110 -0
- bayes/usercases/switch_usercase.py +19 -0
- bayes/utils.py +163 -0
- openbayes_cli-0.4.5.dist-info/METADATA +62 -0
- openbayes_cli-0.4.5.dist-info/RECORD +55 -0
- openbayes_cli-0.4.5.dist-info/WHEEL +4 -0
- openbayes_cli-0.4.5.dist-info/entry_points.txt +3 -0
bayes/commands/org.py
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
3
|
+
import typer
|
|
4
|
+
|
|
5
|
+
from bayes.model.file.settings import BayesEnvConfig
|
|
6
|
+
from bayes.usercases import org_usecase
|
|
7
|
+
from bayes.usercases import auth_usecase
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
app = typer.Typer()
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@app.command()
|
|
14
|
+
def switch(name: str, ctx: typer.Context):
|
|
15
|
+
"""
|
|
16
|
+
组织切换
|
|
17
|
+
用法:
|
|
18
|
+
bayes org switch [组织名] [选项]
|
|
19
|
+
|
|
20
|
+
可用选项:
|
|
21
|
+
-h, --help 查看 switch 的帮助
|
|
22
|
+
|
|
23
|
+
"""
|
|
24
|
+
# 先检查登陆状态
|
|
25
|
+
login = auth_usecase.check_login()
|
|
26
|
+
if not login:
|
|
27
|
+
print("尚未授权,请先登录")
|
|
28
|
+
raise typer.Exit(code=1)
|
|
29
|
+
|
|
30
|
+
# 检查用户是否尝试切换回用户模式(组织名称是否与用户名相同,忽略大小写)
|
|
31
|
+
bayes_settings = ctx.obj
|
|
32
|
+
default_env: Optional[BayesEnvConfig] = bayes_settings.default_env
|
|
33
|
+
switch_back_to_user = str.lower(name) == str.lower(default_env.username)
|
|
34
|
+
|
|
35
|
+
# 如果不是切换回用户模式,则检查组织是否存在。如果组织不存在,打印相应的错误信息并退出程序
|
|
36
|
+
if not switch_back_to_user:
|
|
37
|
+
# 看这个用户下是否有这个组织(这个地方涉及到一个权限的问题,管理员能在命令行切换到其他人的组织吗?)
|
|
38
|
+
if not org_usecase.user_contains_org(default_env.username, name):
|
|
39
|
+
print("请输入当前登录用户下正确的组织名称")
|
|
40
|
+
raise typer.Exit(code=1)
|
|
41
|
+
# 切换到指定的组织
|
|
42
|
+
result = bayes_settings.switch_org(name)
|
|
43
|
+
if result:
|
|
44
|
+
print(f"已成功切换到组织 {name}")
|
|
45
|
+
raise typer.Exit()
|
|
46
|
+
else:
|
|
47
|
+
result = bayes_settings.switch_user(name)
|
|
48
|
+
if result:
|
|
49
|
+
print(f"已成功切换到个人账号 {name}")
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
@app.command()
|
|
53
|
+
def status(ctx: typer.Context):
|
|
54
|
+
"""
|
|
55
|
+
组织信息
|
|
56
|
+
|
|
57
|
+
用法:
|
|
58
|
+
bayes org status [选项]
|
|
59
|
+
|
|
60
|
+
可用选项:
|
|
61
|
+
-h, --help 查看 status 的帮助
|
|
62
|
+
|
|
63
|
+
使用用例:
|
|
64
|
+
bayes org status
|
|
65
|
+
"""
|
|
66
|
+
bayes_settings = ctx.obj
|
|
67
|
+
default_env: Optional[BayesEnvConfig] = bayes_settings.default_env
|
|
68
|
+
|
|
69
|
+
userinfo = auth_usecase.get_default_credential_userinfo()
|
|
70
|
+
if userinfo is not None:
|
|
71
|
+
print(f"当前环境: {default_env.endpoint}")
|
|
72
|
+
print(f"当前组织: {default_env.orgName}")
|
|
73
|
+
print(f"用户名: {default_env.username}")
|
|
74
|
+
print(f"邮箱: {userinfo.email}")
|
|
75
|
+
else:
|
|
76
|
+
print(f"当前环境: {default_env.endpoint}")
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
@app.command()
|
|
80
|
+
def ls(ctx: typer.Context):
|
|
81
|
+
"""
|
|
82
|
+
查看所属组织
|
|
83
|
+
|
|
84
|
+
用法:
|
|
85
|
+
bayes org ls [选项]
|
|
86
|
+
|
|
87
|
+
可用选项:
|
|
88
|
+
-h, --help 查看 ls 的帮助
|
|
89
|
+
"""
|
|
90
|
+
# 先检查登陆状态
|
|
91
|
+
login = auth_usecase.check_login()
|
|
92
|
+
if not login:
|
|
93
|
+
print("尚未授权,请先登录")
|
|
94
|
+
raise typer.Exit(code=1)
|
|
95
|
+
|
|
96
|
+
bayes_settings = ctx.obj
|
|
97
|
+
default_env: Optional[BayesEnvConfig] = bayes_settings.default_env
|
|
98
|
+
|
|
99
|
+
user_orgs_data = org_usecase.list_user_orgs(default_env.username)
|
|
100
|
+
org_usecase.list_display_table(user_orgs_data)
|
bayes/commands/ssh.py
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
import typer
|
|
4
|
+
|
|
5
|
+
from bayes.usercases import auth_usecase, ssh_usecase
|
|
6
|
+
|
|
7
|
+
app = typer.Typer()
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@app.command()
|
|
11
|
+
def create(ctx: typer.Context):
|
|
12
|
+
"""
|
|
13
|
+
创建新的 SSH key
|
|
14
|
+
用法:
|
|
15
|
+
bayes ssh create [选项]
|
|
16
|
+
|
|
17
|
+
可用选项:
|
|
18
|
+
-h, --help 查看 create 的帮助
|
|
19
|
+
|
|
20
|
+
"""
|
|
21
|
+
# 检查用户是否已登录
|
|
22
|
+
login = auth_usecase.check_login()
|
|
23
|
+
if not login:
|
|
24
|
+
print("尚未授权,请先登录")
|
|
25
|
+
raise typer.Exit(code=1)
|
|
26
|
+
|
|
27
|
+
print("正在检查 SSH 公钥,请稍候...")
|
|
28
|
+
|
|
29
|
+
isExist, err = ssh_usecase.is_finger_print_exist()
|
|
30
|
+
if isExist:
|
|
31
|
+
print("OpenBayes 服务器中已存在此设备的公钥")
|
|
32
|
+
raise typer.Exit(code=1)
|
|
33
|
+
|
|
34
|
+
print("OpenBayes 服务器中不存在关于此设备的公钥")
|
|
35
|
+
|
|
36
|
+
passphrase = typer.prompt(f"请输入 SSH key 的密码:", hide_input=True)
|
|
37
|
+
err = ssh_usecase.create_key(passphrase)
|
|
38
|
+
if err is not None:
|
|
39
|
+
raise typer.Exit(code=1)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
@app.command()
|
|
43
|
+
def upload(ctx: typer.Context,
|
|
44
|
+
pub_key_path: str,
|
|
45
|
+
name: str = typer.Option("", "-n", "--name", help="SSH 名字,不填则默认使用 hostname")):
|
|
46
|
+
"""
|
|
47
|
+
上传 SSH 公钥
|
|
48
|
+
|
|
49
|
+
用法:
|
|
50
|
+
bayes ssh upload [公钥] [选项]
|
|
51
|
+
|
|
52
|
+
可用选项:
|
|
53
|
+
-h, --help 查看 upload 的帮助
|
|
54
|
+
-n, --name string [可选] SSH 名字,不填则默认使用 hostname
|
|
55
|
+
"""
|
|
56
|
+
# 检查用户是否已登录
|
|
57
|
+
login = auth_usecase.check_login()
|
|
58
|
+
if not login:
|
|
59
|
+
print("尚未授权,请先登录")
|
|
60
|
+
raise typer.Exit(code=1)
|
|
61
|
+
|
|
62
|
+
try:
|
|
63
|
+
os.stat(pub_key_path)
|
|
64
|
+
except FileNotFoundError:
|
|
65
|
+
print(f"路径 {pub_key_path} 不存在")
|
|
66
|
+
raise typer.Exit(code=1)
|
|
67
|
+
|
|
68
|
+
err = ssh_usecase.upload_key(name, pub_key_path)
|
|
69
|
+
if err is not None:
|
|
70
|
+
raise typer.Exit(code=1)
|
bayes/error.py
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
|
|
2
|
+
class Error(Exception):
|
|
3
|
+
def __init__(self, message: str):
|
|
4
|
+
self.message = message
|
|
5
|
+
super().__init__(self.message)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def credential_notfound_error(name: str) -> Exception:
|
|
9
|
+
return Exception(f"配置名 '{name}' 不存在, 使用 bayes switch '{name}' -e {{endpoint}} 设置")
|
bayes/model/__init__.py
ADDED
|
File without changes
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
from datetime import datetime
|
|
2
|
+
from typing import List
|
|
3
|
+
|
|
4
|
+
from pydantic import BaseModel
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class DatasetVersion(BaseModel):
|
|
8
|
+
semanticBindingName: str
|
|
9
|
+
createdAt: datetime
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class PublicDatasetVersions(BaseModel):
|
|
13
|
+
data: List[DatasetVersion]
|
|
14
|
+
|
|
File without changes
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
from typing import List, Optional
|
|
2
|
+
from pydantic import BaseModel, Field
|
|
3
|
+
import yaml
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
import typer
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class OpenBayesDataBinding(BaseModel):
|
|
9
|
+
data: str
|
|
10
|
+
name: Optional[str] = None
|
|
11
|
+
path: str
|
|
12
|
+
type: str
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class DataBindings(BaseModel):
|
|
16
|
+
data_binding: Optional[List[OpenBayesDataBinding]] = Field(None)
|
|
17
|
+
binding: Optional[List[str]] = Field(None)
|
|
18
|
+
data_bindings: List[OpenBayesDataBinding] = Field(default_factory=list)
|
|
19
|
+
bindings: Optional[List[str]] = Field(None)
|
|
20
|
+
|
|
21
|
+
def get_data_bindings(self) -> List[OpenBayesDataBinding]:
|
|
22
|
+
if self.data_bindings:
|
|
23
|
+
return self.data_bindings
|
|
24
|
+
if self.data_binding:
|
|
25
|
+
return self.data_binding
|
|
26
|
+
if self.bindings:
|
|
27
|
+
binding_list = []
|
|
28
|
+
for b in self.bindings:
|
|
29
|
+
parts = b.split(":")
|
|
30
|
+
data_binding = OpenBayesDataBinding(
|
|
31
|
+
data=parts[0],
|
|
32
|
+
path=parts[1],
|
|
33
|
+
type=parts[2] if len(parts) > 2 else "ro"
|
|
34
|
+
)
|
|
35
|
+
binding_list.append(data_binding)
|
|
36
|
+
return binding_list
|
|
37
|
+
return []
|
|
38
|
+
|
|
39
|
+
def get_bindings(self) -> List[str]:
|
|
40
|
+
if self.bindings:
|
|
41
|
+
return self.bindings
|
|
42
|
+
return self.binding or []
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
from enum import Enum
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
|
|
4
|
+
import yaml
|
|
5
|
+
from pydantic import BaseModel, Field
|
|
6
|
+
from typing import List, Optional, Tuple
|
|
7
|
+
import os
|
|
8
|
+
|
|
9
|
+
from bayes.model.file.settings import BayesEnvConfig, BayesSettings
|
|
10
|
+
from bayes.utils import Utils
|
|
11
|
+
|
|
12
|
+
DATA_FILE_NAME = ".openbayesdata"
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class OpenBayesDataType(str, Enum):
|
|
16
|
+
DATASET = "DATASET"
|
|
17
|
+
CODE = "CODE"
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class OpenBayesData(BaseModel):
|
|
21
|
+
user: str
|
|
22
|
+
version: str
|
|
23
|
+
pid: Optional[str] = None # project_id
|
|
24
|
+
did: Optional[str] = None # dataset_id
|
|
25
|
+
path: str # data_file_path
|
|
26
|
+
location: str = ""
|
|
27
|
+
zip: str = "" # zip_path
|
|
28
|
+
length: int = 0 # upload_length
|
|
29
|
+
token: str = ""
|
|
30
|
+
|
|
31
|
+
def has_last_upload(self) -> bool:
|
|
32
|
+
if self.location and self.token and self.zip:
|
|
33
|
+
try:
|
|
34
|
+
os.stat(self.zip)
|
|
35
|
+
return True
|
|
36
|
+
except FileNotFoundError as e:
|
|
37
|
+
print(f"zip_path:{self.zip} not found")
|
|
38
|
+
return False
|
|
39
|
+
return False
|
|
40
|
+
|
|
41
|
+
def has_last_archived_upload(self, zip_path: str) -> bool:
|
|
42
|
+
if self.location and self.token and self.zip == zip_path:
|
|
43
|
+
return self.has_last_upload()
|
|
44
|
+
return False
|
|
45
|
+
|
|
46
|
+
def update_upload(
|
|
47
|
+
self, location: str, token: str, zip_path: str, upload_length: int
|
|
48
|
+
):
|
|
49
|
+
self.location = location
|
|
50
|
+
self.zip = zip_path
|
|
51
|
+
self.length = upload_length
|
|
52
|
+
self.token = token
|
|
53
|
+
|
|
54
|
+
def update_version(self, version: str):
|
|
55
|
+
self.version = version
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def empty_openbayes_datas() -> List[OpenBayesData]:
|
|
59
|
+
return []
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def new_openbayes_dataset_data(did: str, data_file_path: str) -> OpenBayesData:
|
|
63
|
+
default_env: Optional[BayesEnvConfig] = BayesSettings().default_env
|
|
64
|
+
cli_version = Utils.get_version_from_pyproject_toml()
|
|
65
|
+
return OpenBayesData(
|
|
66
|
+
user=default_env.username, version=cli_version, did=did, path=data_file_path
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def new_openbayes_code_data(pid: str, data_file_path: str) -> OpenBayesData:
|
|
71
|
+
default_env: Optional[BayesEnvConfig] = BayesSettings().default_env
|
|
72
|
+
cli_version = Utils.get_version_from_pyproject_toml()
|
|
73
|
+
return OpenBayesData(
|
|
74
|
+
user=default_env.username, version=cli_version, pid=pid, path=data_file_path
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
class OpenBayesDataSettings:
|
|
79
|
+
def __init__(self, config_path: Optional[Path] = None):
|
|
80
|
+
self.config_path: Path = Path(config_path) if isinstance(config_path, str) else config_path or Path(DATA_FILE_NAME)
|
|
81
|
+
if self.config_path.is_dir():
|
|
82
|
+
self.config_path = self.config_path / DATA_FILE_NAME
|
|
83
|
+
self.configuration: List[OpenBayesData] = []
|
|
84
|
+
self.load_from_file()
|
|
85
|
+
|
|
86
|
+
def load_from_file(self):
|
|
87
|
+
if self.config_path.exists():
|
|
88
|
+
with self.config_path.open("r") as f:
|
|
89
|
+
config_data = yaml.safe_load(f)
|
|
90
|
+
self.configuration = [OpenBayesData(**data) for data in config_data] if config_data else []
|
|
91
|
+
|
|
92
|
+
def save_to_file(self):
|
|
93
|
+
with self.config_path.open("w") as f:
|
|
94
|
+
yaml.dump([item.model_dump() for item in self.configuration], f, default_flow_style=False)
|
|
95
|
+
|
|
96
|
+
def update_or_add_data(self, new_data: OpenBayesData):
|
|
97
|
+
for i, data in enumerate(self.configuration):
|
|
98
|
+
if data.user == new_data.user and ((data.pid and data.pid == new_data.pid) or (data.did and data.did == new_data.did)):
|
|
99
|
+
self.configuration[i] = new_data
|
|
100
|
+
return
|
|
101
|
+
self.configuration.append(new_data)
|
|
102
|
+
|
|
103
|
+
def get_data_by_user_and_id(self, username: str, id: str) -> Optional[OpenBayesData]:
|
|
104
|
+
for data in self.configuration:
|
|
105
|
+
if data.user == username and ((data.pid and data.pid == id) or (data.did and data.did == id)):
|
|
106
|
+
return data
|
|
107
|
+
return None
|
|
108
|
+
|
|
109
|
+
def remove_data_by_user_and_id(self, username: str, id: str):
|
|
110
|
+
self.configuration = [
|
|
111
|
+
data for data in self.configuration
|
|
112
|
+
if not (data.user == username and ((data.pid and data.pid == id) or (data.did and data.did == id)))
|
|
113
|
+
]
|
|
114
|
+
|
|
115
|
+
def write(self, new_data: OpenBayesData):
|
|
116
|
+
self.update_or_add_data(new_data)
|
|
117
|
+
self.save_to_file()
|
|
118
|
+
|
|
119
|
+
def read_by_cur_user(self, id: str) -> Tuple[Optional[OpenBayesData], Optional[Exception]]:
|
|
120
|
+
default_env: Optional[BayesEnvConfig] = BayesSettings().default_env
|
|
121
|
+
data = self.get_data_by_user_and_id(default_env.username, id)
|
|
122
|
+
if data:
|
|
123
|
+
return data, None
|
|
124
|
+
return None, FileNotFoundError("No matching upload configuration found")
|
|
125
|
+
|
|
126
|
+
def remove_by_cur_user(self, id: str) -> Optional[Exception]:
|
|
127
|
+
default_env: Optional[BayesEnvConfig] = BayesSettings().default_env
|
|
128
|
+
self.remove_data_by_user_and_id(default_env.username, id)
|
|
129
|
+
try:
|
|
130
|
+
self.save_to_file()
|
|
131
|
+
except Exception as e:
|
|
132
|
+
return e
|
|
133
|
+
return None
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
from typing import Optional
|
|
4
|
+
|
|
5
|
+
import yaml
|
|
6
|
+
from pydantic import BaseModel
|
|
7
|
+
|
|
8
|
+
FILE_NAME = ".openbayesgear"
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class OpenBayesGear(BaseModel):
|
|
12
|
+
id: str
|
|
13
|
+
name: str
|
|
14
|
+
jid: Optional[str] = ""
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class OpenBayesGearSettings(BaseModel):
|
|
18
|
+
configuration: Optional[OpenBayesGear] = None
|
|
19
|
+
config_path: Optional[Path] = None
|
|
20
|
+
|
|
21
|
+
def __init__(self, config_path: Optional[Path] = None, **kwargs):
|
|
22
|
+
super().__init__(**kwargs)
|
|
23
|
+
self.config_path = config_path or Path(FILE_NAME)
|
|
24
|
+
self.load_from_file()
|
|
25
|
+
|
|
26
|
+
def load_from_file(self):
|
|
27
|
+
if self.config_path.exists():
|
|
28
|
+
with self.config_path.open("r") as f:
|
|
29
|
+
config_data = yaml.safe_load(f)
|
|
30
|
+
if config_data:
|
|
31
|
+
self.configuration = OpenBayesGear(**config_data)
|
|
32
|
+
else:
|
|
33
|
+
self.configuration = None
|
|
34
|
+
|
|
35
|
+
def save_to_file(self):
|
|
36
|
+
with self.config_path.open("w") as f:
|
|
37
|
+
if self.configuration:
|
|
38
|
+
yaml.dump(self.configuration.model_dump(), f, default_flow_style=False)
|
|
39
|
+
else:
|
|
40
|
+
f.write("")
|
|
41
|
+
|
|
42
|
+
def create_or_update(self, directory: str, pid: str, project_name: str) -> None:
|
|
43
|
+
directory_path = Path(directory)
|
|
44
|
+
file_path = directory_path / FILE_NAME
|
|
45
|
+
|
|
46
|
+
os.makedirs(directory_path, exist_ok=True)
|
|
47
|
+
|
|
48
|
+
self.config_path = file_path
|
|
49
|
+
self.configuration = OpenBayesGear(id=pid, name=project_name)
|
|
50
|
+
|
|
51
|
+
self.save_to_file()
|
|
52
|
+
|
|
53
|
+
def read_from_file(self, path: str) -> OpenBayesGear:
|
|
54
|
+
with open(path, "r") as f:
|
|
55
|
+
config_data = yaml.safe_load(f)
|
|
56
|
+
if config_data:
|
|
57
|
+
return OpenBayesGear(**config_data)
|
|
58
|
+
else:
|
|
59
|
+
raise FileNotFoundError(f"No config data found in {path}")
|
|
60
|
+
|
|
61
|
+
def update_jid(self, directory: str, jid: str) -> None:
|
|
62
|
+
path = Path(directory) / FILE_NAME
|
|
63
|
+
|
|
64
|
+
gear = self.read_from_file(str(path))
|
|
65
|
+
|
|
66
|
+
gear.jid = jid
|
|
67
|
+
self.configuration = gear
|
|
68
|
+
|
|
69
|
+
try:
|
|
70
|
+
self.save_to_file()
|
|
71
|
+
except Exception as e:
|
|
72
|
+
raise RuntimeError(f"Error saving to file: {e}")
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
from pydantic import BaseModel
|
|
2
|
+
from typing import Optional
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
import os
|
|
5
|
+
import yaml
|
|
6
|
+
|
|
7
|
+
IGNORE_FILE_NAME = ".openbayesignore"
|
|
8
|
+
TEMPLATE_PATH = "bayes/templates/openbayesignore.yaml"
|
|
9
|
+
# 定义忽略的文件和目录模式
|
|
10
|
+
IGNORE_CLEANUPS = [
|
|
11
|
+
"__MACOSX",
|
|
12
|
+
"*.rsrc",
|
|
13
|
+
".openbayesdata",
|
|
14
|
+
".openbayesgear",
|
|
15
|
+
".openbayesignore",
|
|
16
|
+
".DS_Store",
|
|
17
|
+
"Desktop.ini",
|
|
18
|
+
"desktop.ini",
|
|
19
|
+
"._*",
|
|
20
|
+
"Thumbs.db",
|
|
21
|
+
".Spotlight-V100",
|
|
22
|
+
".Trashes",
|
|
23
|
+
".VolumeIcon.icns",
|
|
24
|
+
"$RECYCLE.BIN",
|
|
25
|
+
"$Recycle.Bin",
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class OpenBayesIgnore(BaseModel):
|
|
30
|
+
message: Optional[str] = None
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class OpenBayesIgnoreSettings(BaseModel):
|
|
34
|
+
configuration: Optional[OpenBayesIgnore] = None
|
|
35
|
+
config_path: Optional[Path] = None
|
|
36
|
+
|
|
37
|
+
def __init__(self, config_path: Optional[Path] = None, **kwargs):
|
|
38
|
+
super().__init__(**kwargs)
|
|
39
|
+
self.config_path = config_path or Path(IGNORE_FILE_NAME)
|
|
40
|
+
self.load_or_create_default_yaml()
|
|
41
|
+
|
|
42
|
+
def load_or_create_default_yaml(self):
|
|
43
|
+
if self.config_path.exists():
|
|
44
|
+
self.load_from_yaml()
|
|
45
|
+
else:
|
|
46
|
+
self.create_default(self.config_path.parent)
|
|
47
|
+
|
|
48
|
+
def load_from_yaml(self):
|
|
49
|
+
with open(self.config_path, "r", encoding='utf-8') as f:
|
|
50
|
+
message = f.read()
|
|
51
|
+
self.configuration = OpenBayesIgnore(message=message)
|
|
52
|
+
|
|
53
|
+
def save_to_yaml(self):
|
|
54
|
+
with open(self.config_path, "w", encoding='utf-8') as f:
|
|
55
|
+
f.write(self.configuration.message)
|
|
56
|
+
|
|
57
|
+
@staticmethod
|
|
58
|
+
def read_template(template_path):
|
|
59
|
+
with open(template_path, 'r', encoding='utf-8') as file:
|
|
60
|
+
return file.read()
|
|
61
|
+
|
|
62
|
+
def create_default(self, directory):
|
|
63
|
+
# 读取模板内容
|
|
64
|
+
template_content = self.read_template(TEMPLATE_PATH)
|
|
65
|
+
|
|
66
|
+
# 确保目录存在
|
|
67
|
+
os.makedirs(directory, exist_ok=True)
|
|
68
|
+
file_path = directory / IGNORE_FILE_NAME
|
|
69
|
+
|
|
70
|
+
# 写入模板内容到文件
|
|
71
|
+
with open(file_path, 'w', encoding='utf-8') as file:
|
|
72
|
+
file.write(template_content)
|
|
73
|
+
|
|
74
|
+
# 加载文件内容为配置
|
|
75
|
+
self.configuration = OpenBayesIgnore(message=template_content)
|