🐛 Bug: Fix the bug in the chart display.
Browse files💰 Sponsors: Thanks to @PowerHunter for the ¥600 sponsorship, sponsorship information has been added to the README.
- README.md +2 -2
- README_CN.md +2 -2
- main.py +52 -47
README.md
CHANGED
|
@@ -315,8 +315,8 @@ curl -X POST http://127.0.0.1:8000/v1/chat/completions \
|
|
| 315 |
## Sponsors
|
| 316 |
|
| 317 |
We thank the following sponsors for their support:
|
| 318 |
-
<!-- ¥
|
| 319 |
-
- @PowerHunter: ¥
|
| 320 |
|
| 321 |
## How to sponsor us
|
| 322 |
|
|
|
|
| 315 |
## Sponsors
|
| 316 |
|
| 317 |
We thank the following sponsors for their support:
|
| 318 |
+
<!-- ¥600 -->
|
| 319 |
+
- @PowerHunter: ¥600
|
| 320 |
|
| 321 |
## How to sponsor us
|
| 322 |
|
README_CN.md
CHANGED
|
@@ -315,8 +315,8 @@ curl -X POST http://127.0.0.1:8000/v1/chat/completions \
|
|
| 315 |
## 赞助商
|
| 316 |
|
| 317 |
我们感谢以下赞助商的支持:
|
| 318 |
-
<!-- ¥
|
| 319 |
-
- @PowerHunter:¥
|
| 320 |
|
| 321 |
## 如何赞助我们
|
| 322 |
|
|
|
|
| 315 |
## 赞助商
|
| 316 |
|
| 317 |
我们感谢以下赞助商的支持:
|
| 318 |
+
<!-- ¥600 -->
|
| 319 |
+
- @PowerHunter:¥600
|
| 320 |
|
| 321 |
## 如何赞助我们
|
| 322 |
|
main.py
CHANGED
|
@@ -1540,75 +1540,80 @@ async def data_page(x_api_key: str = Depends(get_api_key)):
|
|
| 1540 |
# 计算过去24小时的开始时间
|
| 1541 |
start_time = datetime.now(timezone.utc) - timedelta(hours=24)
|
| 1542 |
|
| 1543 |
-
#
|
| 1544 |
model_stats = await session.execute(
|
| 1545 |
select(
|
|
|
|
| 1546 |
RequestStat.model,
|
| 1547 |
-
RequestStat.provider,
|
| 1548 |
func.count().label('count')
|
| 1549 |
)
|
| 1550 |
.where(RequestStat.timestamp >= start_time)
|
| 1551 |
-
.group_by(
|
| 1552 |
-
.order_by(
|
| 1553 |
)
|
| 1554 |
model_stats = model_stats.fetchall()
|
| 1555 |
|
| 1556 |
-
#
|
| 1557 |
-
chart_data = []
|
| 1558 |
-
providers = list(set(stat.provider for stat in model_stats))
|
| 1559 |
models = list(set(stat.model for stat in model_stats))
|
| 1560 |
|
| 1561 |
-
|
| 1562 |
-
|
| 1563 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1564 |
count = next(
|
| 1565 |
(stat.count for stat in model_stats
|
| 1566 |
-
if stat.
|
| 1567 |
0
|
| 1568 |
)
|
| 1569 |
-
data_point[
|
|
|
|
| 1570 |
chart_data.append(data_point)
|
| 1571 |
|
| 1572 |
-
#
|
| 1573 |
-
|
| 1574 |
-
{"name": provider, "data_key": provider}
|
| 1575 |
-
for provider in providers
|
| 1576 |
-
]
|
| 1577 |
|
| 1578 |
-
#
|
| 1579 |
-
chart_config = {
|
| 1580 |
-
"stacked": True, # 堆叠柱状图
|
| 1581 |
-
"horizontal": False,
|
| 1582 |
-
"colors": [f"hsl({i * 360 / len(providers)}, 70%, 50%)" for i in range(len(providers))], # 生成不同的颜色
|
| 1583 |
-
"grid": True,
|
| 1584 |
-
"legend": True,
|
| 1585 |
-
"tooltip": True
|
| 1586 |
-
}
|
| 1587 |
chart_config = {
|
| 1588 |
-
|
| 1589 |
-
|
| 1590 |
-
|
| 1591 |
-
|
| 1592 |
-
|
| 1593 |
-
"tooltip": True # 启用工具提示
|
| 1594 |
}
|
| 1595 |
-
print(chart_data)
|
| 1596 |
-
print(series)
|
| 1597 |
|
| 1598 |
-
result =
|
| 1599 |
-
|
| 1600 |
-
|
| 1601 |
-
|
| 1602 |
-
|
| 1603 |
-
|
| 1604 |
-
|
| 1605 |
-
|
| 1606 |
-
|
| 1607 |
-
|
| 1608 |
-
|
| 1609 |
-
|
| 1610 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1611 |
).render()
|
|
|
|
| 1612 |
|
| 1613 |
return result
|
| 1614 |
|
|
|
|
| 1540 |
# 计算过去24小时的开始时间
|
| 1541 |
start_time = datetime.now(timezone.utc) - timedelta(hours=24)
|
| 1542 |
|
| 1543 |
+
# 按小时统计每个模型的请求数据
|
| 1544 |
model_stats = await session.execute(
|
| 1545 |
select(
|
| 1546 |
+
func.strftime('%H', RequestStat.timestamp).label('hour'),
|
| 1547 |
RequestStat.model,
|
|
|
|
| 1548 |
func.count().label('count')
|
| 1549 |
)
|
| 1550 |
.where(RequestStat.timestamp >= start_time)
|
| 1551 |
+
.group_by('hour', RequestStat.model)
|
| 1552 |
+
.order_by('hour')
|
| 1553 |
)
|
| 1554 |
model_stats = model_stats.fetchall()
|
| 1555 |
|
| 1556 |
+
# 获取所有唯一的模型名称
|
|
|
|
|
|
|
| 1557 |
models = list(set(stat.model for stat in model_stats))
|
| 1558 |
|
| 1559 |
+
# 生成24小时的数据点
|
| 1560 |
+
chart_data = []
|
| 1561 |
+
current_hour = datetime.now().hour
|
| 1562 |
+
|
| 1563 |
+
for i in range(24):
|
| 1564 |
+
# 计算小时标签(从当前小时往前推24小时)
|
| 1565 |
+
hour = (current_hour - i) % 24
|
| 1566 |
+
hour_str = f"{hour:02d}"
|
| 1567 |
+
|
| 1568 |
+
# 创建该小时的数据点
|
| 1569 |
+
data_point = {"label": hour_str}
|
| 1570 |
+
|
| 1571 |
+
# 添加每个模型在该小时的请求数
|
| 1572 |
+
for model in models:
|
| 1573 |
count = next(
|
| 1574 |
(stat.count for stat in model_stats
|
| 1575 |
+
if stat.hour == f"{hour:02d}" and stat.model == model),
|
| 1576 |
0
|
| 1577 |
)
|
| 1578 |
+
data_point[model] = count
|
| 1579 |
+
|
| 1580 |
chart_data.append(data_point)
|
| 1581 |
|
| 1582 |
+
# 反转数据点顺序使其按时间正序显示
|
| 1583 |
+
chart_data.reverse()
|
|
|
|
|
|
|
|
|
|
| 1584 |
|
| 1585 |
+
# 为每个模型配置显示属性
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1586 |
chart_config = {
|
| 1587 |
+
model: {
|
| 1588 |
+
"label": model,
|
| 1589 |
+
"color": f"hsl({i * 360 / len(models)}, 70%, 50%)" # 为每个模型生成不同的颜色
|
| 1590 |
+
}
|
| 1591 |
+
for i, model in enumerate(models)
|
|
|
|
| 1592 |
}
|
|
|
|
|
|
|
| 1593 |
|
| 1594 |
+
result = HTML(
|
| 1595 |
+
Head(title="数据统计"),
|
| 1596 |
+
Body(
|
| 1597 |
+
Div(
|
| 1598 |
+
# 堆叠柱状图
|
| 1599 |
+
Div(
|
| 1600 |
+
"模型使用统计 (24小时) - 按小时统计",
|
| 1601 |
+
class_="text-2xl font-bold mb-4"
|
| 1602 |
+
),
|
| 1603 |
+
Div(
|
| 1604 |
+
chart.chart(
|
| 1605 |
+
chart_data,
|
| 1606 |
+
chart_config,
|
| 1607 |
+
stacked=True,
|
| 1608 |
+
),
|
| 1609 |
+
class_="mb-8 h-[400px]" # 添加固定高度
|
| 1610 |
+
),
|
| 1611 |
+
id="main-content",
|
| 1612 |
+
class_="container ml-[200px] mx-auto p-4"
|
| 1613 |
+
)
|
| 1614 |
+
)
|
| 1615 |
).render()
|
| 1616 |
+
print(result)
|
| 1617 |
|
| 1618 |
return result
|
| 1619 |
|