Skip to content

Commit

Permalink
Refactor/exp name (#64)
Browse files Browse the repository at this point in the history
* Update project.py

* allow create experiment with same name

* format:code

* dup name

* update

* update:style

* Update HeaderBar.vue

* fix:shit!!!!!!

---------

Co-authored-by: KAAANG <[email protected]>
Co-authored-by: Feudalman <[email protected]>
  • Loading branch information
3 people authored Sep 20, 2024
1 parent aaaeeeb commit a1f2c76
Show file tree
Hide file tree
Showing 10 changed files with 49 additions and 104 deletions.
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# swanlab
swankit==0.1.1b1
swankit

# web server
fastapi>=0.110.1
Expand Down
101 changes: 20 additions & 81 deletions swanboard/callback.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
from swankit.callback import SwanKitCallback, ColumnInfo
from .db.models import *
from .db import add_multi_chart, connect, NotExistedError, ExistedError, ChartTypeError
from typing import Tuple, Callable, Optional
from swanboard.utils import check_exp_name_format, check_desc_format, swanlog, get_swanlog_dir
from datetime import datetime
from typing import Tuple, Optional
from swanboard.utils import swanlog, get_swanlog_dir
import time
import re


class SwanBoardCallback(SwanKitCallback):
Expand All @@ -16,63 +16,6 @@ def __init__(self):
super(SwanBoardCallback, self).__init__()
self.exp: Optional[Experiment] = None

@staticmethod
def __get_exp_name(experiment_name: str = None, suffix: str = None) -> Tuple[str, str]:
"""
预处理实验名称,如果实验名称过长,截断
Parameters
----------
experiment_name : str
实验名称
suffix : str
实验名称后缀添加方式,可以为None、"default"或自由后缀,前者代表不添加后缀,后者代表添加时间戳后缀
Returns
----------
experiment_name : str
校验后的实验名称
exp_name : str
最终的实验名称
"""
# ---------------------------------- 校验实验名称 ----------------------------------
experiment_name = "exp" if experiment_name is None else experiment_name
# 校验实验名称
experiment_name_checked = check_exp_name_format(experiment_name)
# 如果实验名称太长的tip
tip = "The experiment name you provided is too long, it has been truncated automatically."

# 如果前后长度不一样,说明实验名称被截断了,提醒
if len(experiment_name_checked) != len(experiment_name) and suffix is None:
swanlog.warning(tip)

# 如果suffix为None, 则不添加后缀,直接返回
if suffix is None or suffix is False:
return experiment_name_checked, experiment_name

# 如果suffix为True, 则添加默认后缀
if suffix is True:
suffix = "default"

# suffix必须是字符串
if not isinstance(suffix, str):
raise TypeError("The suffix must be a string, but got {}".format(type(suffix)))

# 如果suffix_checked为default,则设置为默认后缀
if suffix.lower().strip() == "default":
# 添加默认后缀
default_suffix = "{}".format(datetime.now().strftime("%b%d_%H-%M-%S"))
exp_name = "{}_{}".format(experiment_name_checked, default_suffix)
else:
exp_name = "{}_{}".format(experiment_name_checked, suffix)

# 校验实验名称,如果实验名称过长,截断
experiment_name_checked = check_exp_name_format(exp_name)
if len(experiment_name_checked) != len(exp_name):
swanlog.warning(tip)

return experiment_name_checked, exp_name

def __str__(self) -> str:
return "SwanBoardCallback"

Expand All @@ -88,36 +31,32 @@ def before_init_experiment(
exp_name: str,
description: str,
num: int,
suffix: str,
setter: Callable[[str, str, str, str], None],
colors: Tuple[str, str],
):
# ---------------------------------- 实验描述校验 ----------------------------------
description = description if description is not None else ""
desc = check_desc_format(description)
if desc != description:
swanlog.warning("The description has been truncated automatically.")
pattern = r"-\d+$"
# ---------------------------------- 实验名称校验 ----------------------------------
# 这个循环的目的是如果创建失败则等零点五秒重新生成后缀重新创建,直到创建成功
# 但是由于需要考虑suffix为none不生成后缀的情况,所以需要在except中判断一下
old = exp_name
while True:
experiment_name, exp_name = self.__get_exp_name(old, suffix)
try:
# 获得数据库实例
self.exp = Experiment.create(name=exp_name, run_id=run_id, description=description, num=num)
self.exp = Experiment.create(
name=exp_name,
run_id=run_id,
description=description,
num=num,
colors=colors,
)
break
except ExistedError:
# 如果suffix名为default,说明是自动生成的后缀,需要重新生成后缀
if isinstance(suffix, str) and suffix.lower().strip() == "default":
swanlog.debug(f"Experiment {exp_name} has existed, try another name...")
time.sleep(0.5)
continue
# 其他情况下,说明是用户自定义的后缀,需要报错
swanlog.debug(f"Experiment {exp_name} has existed, try another name...")
# 以-{数字}结尾
if bool(re.search(pattern, exp_name)):
arr = exp_name.split("-")
arr[-1] = str(int(arr[-1]) + 1)
exp_name = "-".join(arr)
else:
Experiment.purely_delete(run_id=run_id)
raise ExistedError(f"Experiment {exp_name} has existed in local, please try another name.")
# 执行相关设置
setter(experiment_name, self.exp.light, self.exp.dark, self.exp.description)
exp_name = f"{exp_name}-1"
time.sleep(0.5)

def on_log(self):
# 每一次log的时候检查一下数据库中的实验状态
Expand Down
2 changes: 1 addition & 1 deletion swanboard/controller/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ def get_project_summary(project_id: int = DEFAULT_PROJECT_ID) -> dict:
tag_data = ujson.loads(lines[-1])
experiment_summaries[tag["name"]] = tag_data["data"]
except Exception as e:
swanlog.error(f"[expr: {expr['name']} - {tag["name"]}] --- {e}")
swanlog.error(f"[expr: {expr['name']} - {tag['name']}] --- {e}")
continue

data[expr["name"]] = experiment_summaries
Expand Down
6 changes: 4 additions & 2 deletions swanboard/db/models/experiments.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ def create(
cls,
name: str,
run_id: str,
colors: tuple,
description: str = None,
project_id: int = Project.DEFAULT_PROJECT_ID,
num: int = None,
Expand All @@ -134,6 +135,8 @@ def create(
实验名称
run_id : str
运行时信息
colors : Tuple[str, str], optional
实验颜色,[light, dark],默认为None
description : str
实验描述,默认为空字符串
project_id : int, optional
Expand All @@ -160,8 +163,7 @@ def create(
raise ForeignProNotExistedError("项目不存在")
# 这个sum是+1以后的值
_sum = Project.increase_sum(project_id)
# 调用父类的create方法创建实验实例
light, dark = generate_color(_sum if num is None else num + 1)
light, dark = colors
try:
return super().create(
name=name,
Expand Down
10 changes: 5 additions & 5 deletions swanboard/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "swanboard",
"version": "0.1.3b6",
"description": "Dashboard for Swanlab",
"python": "true"
}
"name": "swanboard",
"version": "0.1.4-alpha",
"description": "Dashboard for Swanlab",
"python": "true"
}
3 changes: 2 additions & 1 deletion vue/src/i18n/en-US/common.json5
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@
title: {
experiment: 'Delete this experiment',
project: 'Delete this project'
}
},
success: 'Delete Successfully'
},
search: {
placeholder: 'Search Lab...'
Expand Down
3 changes: 2 additions & 1 deletion vue/src/i18n/zh-CN/common.json5
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@
title: {
experiment: '删除该实验',
project: '删除该项目'
}
},
success: '删除成功'
},
search: {
placeholder: '搜索实验...'
Expand Down
2 changes: 1 addition & 1 deletion vue/src/layouts/ExperimentLayout.vue
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ const deleteExperiment = () => {
.then(({ data }) => {
projectStore.deleteExperiment(data.experiment_id)
router.replace('/').then(() => {
message.success('Delete Successfully')
message.success(t('common.delete.success'))
})
})
.catch(({ data }) => {
Expand Down
20 changes: 10 additions & 10 deletions vue/src/layouts/main/components/HeaderBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,9 @@
<!-- <span class="whitespace-nowrap text-xs pl-2 text-dimmer"> {{ formatVersion(version) }}</span> -->
</div>
</div>
<div class="w-full grow flex justify-end gap-6 px-8">
<!-- button: language switch -->
<div class="flex items-center font-semibold">
<button @click="switchLang()" class="switchLang relative w-9 h-9">
<div :class="mainLangClass">中</div>
<div :class="secondLangClass">En</div>
</button>
</div>
<div class="w-full grow flex justify-end gap-6 pl-8 pr-4">
<!-- links -->
<div class="px-6 items-center font-semibold gap-8 md:flex hidden">
<div class="pl-6 items-center font-semibold gap-6 md:flex hidden">
<a
:href="item.link"
target="_blank"
Expand All @@ -33,7 +26,14 @@
</div>
</div>
<!-- fixeds -->
<div class="flex items-center font-semibold">
<div class="flex items-center font-semibold gap-6">
<!-- button: language switch -->
<div class="flex items-center font-semibold">
<button @click="switchLang()" class="switchLang relative w-9 h-9">
<div :class="mainLangClass">中</div>
<div :class="secondLangClass">En</div>
</button>
</div>
<a
:href="item.link"
target="_blank"
Expand Down
4 changes: 3 additions & 1 deletion vue/src/views/home/HomeView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
{{ getDuration(row) }}
</template>
<template v-for="item in configs" :key="item.slot" v-slot:[item.slot]="{ row }">
{{ row.config[item.slot]?.value != undefined ? row.config[item.slot]?.value : '-' }}
{{ row.config?.[item.slot]?.value != undefined ? row.config[item.slot]?.value : '-' }}
</template>
</ExprTable>
</div>
Expand Down Expand Up @@ -140,6 +140,7 @@ const configs = ref([])
;(() => {
// 寻找需要增加的表头
experiments.value.map((item) => {
if (!item.config) return
Object.entries(item.config).forEach(([key]) => {
// 如果这个key已经存在configs中,跳过
if (configs.value.some((config) => config.title === key)) {
Expand All @@ -155,6 +156,7 @@ const configs = ref([])
// column.value.push(...configs.value)
})()
console.log(configs.value)
// ---------------------------------- 表格数据,同时还有tag的表头处理 ----------------------------------
// 表格体数据
Expand Down

0 comments on commit a1f2c76

Please sign in to comment.