mirror of
https://github.com/remnawave/python-sdk.git
synced 2026-05-13 04:09:05 +00:00
feat: Обновить модели для поддержки необязательных полей и улучшить валидацию
This commit is contained in:
parent
3e6be1f4b4
commit
9c1b478fcf
4 changed files with 20 additions and 41 deletions
|
|
@ -150,7 +150,7 @@ class NodeResponseDto(BaseModel):
|
|||
last_status_message: Optional[str] = Field(None, alias="lastStatusMessage")
|
||||
xray_version: Optional[str] = Field(None, alias="xrayVersion")
|
||||
node_version: Optional[str] = Field(None, alias="nodeVersion")
|
||||
xray_uptime: str = Field(alias="xrayUptime")
|
||||
xray_uptime: float = Field(0, alias="xrayUptime")
|
||||
is_traffic_tracking_active: bool = Field(alias="isTrafficTrackingActive")
|
||||
traffic_reset_day: Optional[int] = Field(None, alias="trafficResetDay")
|
||||
traffic_limit_bytes: Optional[float] = Field(None, alias="trafficLimitBytes")
|
||||
|
|
|
|||
|
|
@ -166,7 +166,7 @@ class RawSubscriptionResponse(BaseModel):
|
|||
user: UserResponseDto
|
||||
converted_user_info: ConvertedUserInfo = Field(alias="convertedUserInfo")
|
||||
headers: Dict[str, str]
|
||||
raw_hosts: List[RawHost] = Field(alias="rawHosts")
|
||||
raw_hosts: Optional[List[RawHost]] = Field(None, alias="rawHosts")
|
||||
|
||||
|
||||
class GetRawSubscriptionByShortUuidResponseDto(RawSubscriptionResponse):
|
||||
|
|
|
|||
|
|
@ -33,15 +33,15 @@ class BandwidthStatisticResponseDto(BaseModel):
|
|||
|
||||
class CPUStatistic(BaseModel):
|
||||
cores: float
|
||||
physical_cores: float = Field(alias="physicalCores")
|
||||
physical_cores: Optional[float] = Field(None, alias="physicalCores")
|
||||
|
||||
|
||||
class MemoryStatistic(BaseModel):
|
||||
total: float
|
||||
free: float
|
||||
used: float
|
||||
active: float
|
||||
available: float
|
||||
active: Optional[float] = None
|
||||
available: Optional[float] = None
|
||||
|
||||
|
||||
class StatusCounts(BaseModel):
|
||||
|
|
@ -112,8 +112,20 @@ class GetNodesStatisticsResponseDto(BaseModel):
|
|||
last_seven_days: List[NodeStatistic] = Field(alias="lastSevenDays")
|
||||
|
||||
|
||||
class RuntimeMetric(BaseModel):
|
||||
"""Runtime metric from health endpoint"""
|
||||
model_config = {"extra": "allow"}
|
||||
|
||||
rss: Optional[float] = None
|
||||
heap_total: Optional[float] = Field(None, alias="heapTotal")
|
||||
heap_used: Optional[float] = Field(None, alias="heapUsed")
|
||||
external: Optional[float] = None
|
||||
instance_type: Optional[str] = Field(None, alias="instanceType")
|
||||
|
||||
|
||||
class GetRemnawaveHealthResponseDto(BaseModel):
|
||||
pm2_stats: List[PM2Stat] = Field(alias="pm2Stats")
|
||||
pm2_stats: Optional[List[PM2Stat]] = Field(None, alias="pm2Stats")
|
||||
runtime_metrics: Optional[List[RuntimeMetric]] = Field(None, alias="runtimeMetrics")
|
||||
|
||||
|
||||
class TrafficStatDto(BaseModel):
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import pytest
|
||||
from uuid import UUID
|
||||
|
||||
from remnawave.models import (
|
||||
# Legacy models (deprecated)
|
||||
|
|
@ -7,11 +6,10 @@ from remnawave.models import (
|
|||
GetNodesRealtimeUsageResponseDto,
|
||||
GetNodeUserUsageByRangeResponseDto,
|
||||
GetUserUsageByRangeResponseDto,
|
||||
|
||||
|
||||
# New stats models
|
||||
GetLegacyStatsUserUsageResponseDto,
|
||||
GetLegacyStatsNodesUsersUsageResponseDto,
|
||||
GetStatsNodesRealtimeUsageResponseDto,
|
||||
GetStatsNodesUsageResponseDto,
|
||||
GetStatsNodeUsersUsageResponseDto,
|
||||
GetStatsUserUsageResponseDto,
|
||||
|
|
@ -69,24 +67,6 @@ async def test_legacy_node_user_usage(remnawave):
|
|||
assert len(node_user_usage) >= 0
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_stats_nodes_realtime_usage(remnawave):
|
||||
"""Test new stats nodes realtime usage endpoint"""
|
||||
realtime_usage = await remnawave.bandwidthstats.get_nodes_realtime_usage()
|
||||
assert isinstance(realtime_usage, GetStatsNodesRealtimeUsageResponseDto)
|
||||
assert hasattr(realtime_usage, 'response')
|
||||
assert isinstance(realtime_usage.response, list)
|
||||
|
||||
# Check structure if data exists
|
||||
if realtime_usage.response:
|
||||
first_item = realtime_usage.response[0]
|
||||
assert hasattr(first_item, 'node_uuid')
|
||||
assert hasattr(first_item, 'node_name')
|
||||
assert hasattr(first_item, 'download_bytes')
|
||||
assert hasattr(first_item, 'upload_bytes')
|
||||
assert hasattr(first_item, 'total_bytes')
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_stats_nodes_usage(remnawave):
|
||||
"""Test new stats nodes usage endpoint with charts"""
|
||||
|
|
@ -232,20 +212,7 @@ async def test_legacy_stats_nodes_users_usage(remnawave):
|
|||
async def test_bandwidth_data_structure(remnawave):
|
||||
"""Test bandwidth stats data structure validity"""
|
||||
start, end = generate_date_range()
|
||||
|
||||
# Get realtime data
|
||||
realtime = await remnawave.bandwidthstats.get_nodes_realtime_usage()
|
||||
|
||||
if realtime.response:
|
||||
# Verify each node has required fields
|
||||
for node in realtime.response:
|
||||
assert isinstance(node.node_uuid, UUID)
|
||||
assert isinstance(node.node_name, str)
|
||||
assert isinstance(node.download_bytes, (int, float))
|
||||
assert isinstance(node.upload_bytes, (int, float))
|
||||
assert isinstance(node.total_bytes, (int, float))
|
||||
assert node.total_bytes >= 0
|
||||
|
||||
|
||||
# Get stats data
|
||||
stats = await remnawave.bandwidthstats.get_stats_nodes_usage(
|
||||
start=start,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue