Remnawave_python-sdk/remnawave/controllers/system.py
Artem 294d70e8c6 feat: Обновить SDK до Remnawave API v2.8.0
Новые эндпоинты:
- GET /tokens/scopes (api_tokens_management.get_scopes)
- GET /users/stream — keyset-пагинация (users.get_users_stream)
- PATCH /hosts/bulk/update (hosts_bulk_actions.update_hosts)
- POST /bandwidth-stats/nodes/users (bandwidthstats.get_stats_nodes_users_usage)

Удалённые эндпоинты (вслед за API):
- POST /hosts/bulk/set-inbound, /hosts/bulk/set-port (заменены update_hosts)
- POST /system/tools/happ/encrypt

Изменения моделей:
- Hosts: tags (вместо tag), mihomoIpVersion, pinnedPeerCertSha256,
  verifyPeerCertByName, finalMask, xhttpExtraParams; fingerprint -> str;
  удалены tag/allowInsecure (с обратной совместимостью через свойства)
- API-токены: name/expiresInDays/scopes, tokens/enabled; новый enum Scope
  (полный каталог scope-ов v2.8.0)
- Nodes: nodeConsumptionMultiplier, note, proxyUrl; тело RestartNodeRequestBodyDto
- trafficLimitBytes int -> float (users, nodes, bulk-actions)
- Infra billing: name, nullable nodeUuid, обязательное nextBillingAt
- HWID: requestIp; webhook-события (user/service) обновлены
- Новый enum MihomoIpVersion

Исправления:
- Bulk-ответы хостов переведены на RootModel (раньше падали с ValueError)
- revoke_user_subscription: исправлен порядок Annotated/Optional (тело терялось)
- Restart*RequestBodyDto: populate_by_name (force_restart игнорировался)

Зависимости:
- Убраны избыточные пины pydantic и pydantic-core (покрыты pydantic[email])
- requires-python <3.14 -> <3.15, добавлен классификатор Python 3.14

Версия пакета 2.7.1 -> 2.8.0.
2026-06-30 22:47:15 +02:00

81 lines
No EOL
2.4 KiB
Python

from typing import Annotated
from rapid_api_client import PydanticBody
from remnawave.models import (
GetBandwidthStatsResponseDto,
GetNodesStatisticsResponseDto,
GetStatsResponseDto,
GetNodesMetricsResponseDto,
GetRemnawaveHealthResponseDto,
GetX25519KeyPairResponseDto,
DebugSrrMatcherRequestDto,
DebugSrrMatcherResponseDto,
GetMetadataResponseDto,
GetRecapResponseDto,
)
from remnawave.rapid import BaseController, get, post
class SystemController(BaseController):
@get("/system/metadata", response_class=GetMetadataResponseDto)
async def get_metadata(
self,
) -> GetMetadataResponseDto:
"""Get Remnawave Information"""
...
@get("/system/stats", response_class=GetStatsResponseDto)
async def get_stats(
self,
) -> GetStatsResponseDto:
"""Get System Stats"""
...
@get("/system/stats/bandwidth", response_class=GetBandwidthStatsResponseDto)
async def get_bandwidth_stats(
self,
) -> GetBandwidthStatsResponseDto:
"""Get System Bandwidth Statistics"""
...
@get("/system/stats/nodes", response_class=GetNodesStatisticsResponseDto)
async def get_nodes_statistics(
self,
) -> GetNodesStatisticsResponseDto:
"""Get Nodes Statistics"""
...
@get("/system/health", response_class=GetRemnawaveHealthResponseDto)
async def get_health(
self,
) -> GetRemnawaveHealthResponseDto:
"""Get System Health"""
...
@get("/system/nodes/metrics", response_class=GetNodesMetricsResponseDto)
async def get_nodes_metrics(
self,
) -> GetNodesMetricsResponseDto:
"""Get Nodes Metrics"""
...
@get("/system/tools/x25519/generate", response_class=GetX25519KeyPairResponseDto)
async def get_x25519_key_pair(
self,
) -> GetX25519KeyPairResponseDto:
"""Get X25519 Key Pair"""
...
@post("/system/testers/srr-matcher", response_class=DebugSrrMatcherResponseDto)
async def debug_srr_matcher(
self,
body: Annotated[DebugSrrMatcherRequestDto, PydanticBody()],
) -> DebugSrrMatcherResponseDto:
"""Test SRR Matcher"""
...
@get("/system/stats/recap", response_class=GetRecapResponseDto)
async def get_recap(
self,
) -> GetRecapResponseDto:
"""Get Recap"""
...