Skip to content
This repository was archived by the owner on Jul 31, 2026. It is now read-only.

Commit eee9be8

Browse files
authored
Merge pull request #56 from remnawave/development
Upgrade SDK to Remnawave API v2.8.0
2 parents 102f8c1 + 0f95dd4 commit eee9be8

26 files changed

Lines changed: 743 additions & 130 deletions

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ pip install git+https://github.com/remnawave/python-sdk.git@development
5050

5151
| Contract Version | Remnawave Panel Version |
5252
| ---------------- | ----------------------- |
53+
| 2.8.0 | >=2.8.0 |
5354
| 2.7.0 | >=2.7.0 |
5455
| 2.6.3 | >=2.6.3 |
5556
| 2.6.2 | >=2.6.2 |

poetry.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,18 @@
11
[project]
22
name = "remnawave"
3-
version = "2.7.1"
4-
description = "A Python SDK for interacting with the Remnawave API v2.7.1."
3+
version = "2.8.0"
4+
description = "A Python SDK for interacting with the Remnawave API v2.8.0."
55
authors = [
66
{name = "Artem",email = "dev@forestsnet.com"}
77
]
88
license = { text = "MIT" }
99
readme = "README.md"
10-
requires-python = ">=3.11,<3.14"
10+
requires-python = ">=3.11,<3.15"
1111
dependencies = [
1212
"rapid-api-client (==0.6.0)",
1313
"orjson (>=3.10.15,<4.0.0)",
1414
"httpx (>=0.27.2,<0.28.0)",
1515
"pydantic[email]>=2.9.2,<3.0.0",
16-
"pydantic-core>=2.33.1,<2.34.0",
17-
"pydantic>=2.9.2,<3.0.0",
1816
"cryptography (>=46.0.3,<47.0.0)",
1917
]
2018
keywords = ["remnawave", "api", "sdk", "proxy", "httpx", "async", "xray"]
@@ -26,6 +24,7 @@ classifiers = [
2624
"Programming Language :: Python :: 3.11",
2725
"Programming Language :: Python :: 3.12",
2826
"Programming Language :: Python :: 3.13",
27+
"Programming Language :: Python :: 3.14",
2928
"Programming Language :: Python :: Implementation :: CPython",
3029
"Programming Language :: Python :: Implementation :: PyPy",
3130
"Framework :: AsyncIO",

remnawave/controllers/api_tokens_management.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
CreateApiTokenResponseDto,
1010
DeleteApiTokenResponseDto,
1111
FindAllApiTokensResponseDto,
12+
GetApiTokenScopesResponseDto,
1213
)
1314
from remnawave.rapid import BaseController, delete, get, post
1415

@@ -36,3 +37,10 @@ async def find_all(
3637
) -> FindAllApiTokensResponseDto:
3738
"""Get all API tokens"""
3839
...
40+
41+
@get("/tokens/scopes", response_class=GetApiTokenScopesResponseDto)
42+
async def get_scopes(
43+
self,
44+
) -> GetApiTokenScopesResponseDto:
45+
"""Get available API token scopes"""
46+
...

remnawave/controllers/bandwidthstats.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from typing import Annotated
22

33
from rapid_api_client import Path, Query
4+
from rapid_api_client.annotations import PydanticBody
45

56
from remnawave.models.bandwidthstats import (
67
GetLegacyStatsNodesUsersUsageResponseDto,
@@ -11,10 +12,12 @@
1112
GetStatsNodesRealtimeUsageResponseDto,
1213
GetStatsNodesUsageResponseDto,
1314
GetStatsNodeUsersUsageResponseDto,
15+
GetStatsNodesUsersUsageRequestDto,
16+
GetStatsNodesUsersUsageResponseDto,
1417
GetStatsUserUsageResponseDto,
1518
GetUserUsageByRangeResponseDto,
1619
)
17-
from remnawave.rapid import BaseController, get
20+
from remnawave.rapid import BaseController, get, post
1821

1922

2023
class BandWidthStatsController(BaseController):
@@ -70,6 +73,17 @@ async def get_stats_node_users_usage(
7073
"""Get Node Users Usage by Node UUID"""
7174
...
7275

76+
@post("/bandwidth-stats/nodes/users", response_class=GetStatsNodesUsersUsageResponseDto)
77+
async def get_stats_nodes_users_usage(
78+
self,
79+
body: Annotated[GetStatsNodesUsersUsageRequestDto, PydanticBody()],
80+
top_users_limit: Annotated[int, Query(description="Limit of top users to return", alias="topUsersLimit")],
81+
start: Annotated[str, Query(description="Start date (YYYY-MM-DD)")],
82+
end: Annotated[str, Query(description="End date (YYYY-MM-DD)")],
83+
) -> GetStatsNodesUsersUsageResponseDto:
84+
"""Get Nodes Users Usage by Nodes UUIDs"""
85+
...
86+
7387
@get("/bandwidth-stats/users/{uuid}", response_class=GetStatsUserUsageResponseDto)
7488
async def get_stats_user_usage(
7589
self,

remnawave/controllers/hosts_bulk_actions.py

Lines changed: 8 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,10 @@
77
BulkDeleteHostsResponseDto,
88
BulkDisableHostsResponseDto,
99
BulkEnableHostsResponseDto,
10-
SetInboundToManyHostsRequestDto,
11-
SetInboundToManyHostsResponseDto,
12-
SetPortToManyHostsResponseDto,
13-
SetPortToManyHostsRequestDto
10+
UpdateManyHostsRequestDto,
11+
UpdateManyHostsResponseDto,
1412
)
15-
from remnawave.rapid import AttributeBody, BaseController, post
13+
from remnawave.rapid import AttributeBody, BaseController, patch, post
1614

1715

1816
class HostsBulkActionsController(BaseController):
@@ -40,21 +38,10 @@ async def enable_hosts(
4038
"""Enable many hosts"""
4139
...
4240

43-
@post(
44-
"/hosts/bulk/set-inbound",
45-
response_class=SetInboundToManyHostsResponseDto,
46-
)
47-
async def set_inbound_to_hosts(
41+
@patch("/hosts/bulk/update", response_class=UpdateManyHostsResponseDto)
42+
async def update_hosts(
4843
self,
49-
body: Annotated[SetInboundToManyHostsRequestDto, PydanticBody()],
50-
) -> SetInboundToManyHostsResponseDto:
51-
"""Set inbound to many hosts"""
52-
...
53-
54-
@post("/hosts/bulk/set-port", response_class=SetPortToManyHostsResponseDto)
55-
async def set_port_to_hosts(
56-
self,
57-
body: Annotated[SetPortToManyHostsRequestDto, PydanticBody()],
58-
) -> SetPortToManyHostsResponseDto:
59-
"""Set port to many hosts"""
44+
body: Annotated[UpdateManyHostsRequestDto, PydanticBody()],
45+
) -> UpdateManyHostsResponseDto:
46+
"""Update many hosts"""
6047
...

remnawave/controllers/nodes.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
UpdateNodeRequestDto,
2020
UpdateNodeResponseDto,
2121
RestartAllNodesRequestBodyDto,
22+
RestartNodeRequestBodyDto,
2223
ResetNodeTrafficRequestDto,
2324
ResetNodeTrafficResponseDto,
2425
ProfileModificationRequestDto,
@@ -98,6 +99,7 @@ async def disable_node(
9899
async def restart_node(
99100
self,
100101
uuid: Annotated[str, Path(description="Node UUID")],
102+
body: Annotated[RestartNodeRequestBodyDto | None, PydanticBody()] = None,
101103
) -> RestartNodeResponseDto:
102104
"""Restart Node"""
103105
...

remnawave/controllers/system.py

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@
77
GetNodesMetricsResponseDto,
88
GetRemnawaveHealthResponseDto,
99
GetX25519KeyPairResponseDto,
10-
EncryptHappCryptoLinkRequestDto,
11-
EncryptHappCryptoLinkResponseDto,
1210
DebugSrrMatcherRequestDto,
1311
DebugSrrMatcherResponseDto,
1412
GetMetadataResponseDto,
@@ -67,14 +65,6 @@ async def get_x25519_key_pair(
6765
"""Get X25519 Key Pair"""
6866
...
6967

70-
@post("/system/tools/happ/encrypt", response_class=EncryptHappCryptoLinkResponseDto)
71-
async def encrypt_happ_crypto_link(
72-
self,
73-
body: Annotated[EncryptHappCryptoLinkRequestDto, PydanticBody()],
74-
) -> EncryptHappCryptoLinkResponseDto:
75-
"""Encrypt Happ Crypto Link"""
76-
...
77-
7868
@post("/system/testers/srr-matcher", response_class=DebugSrrMatcherResponseDto)
7969
async def debug_srr_matcher(
8070
self,

remnawave/controllers/users.py

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
GetUserByUuidResponseDto,
1616
GetUserAccessibleNodesResponseDto,
1717
GetUserSubscriptionRequestHistoryResponseDto,
18+
GetUsersStreamResponseDto,
1819
TelegramUserResponseDto,
1920
EmailUserResponseDto,
2021
TagUserResponseDto,
@@ -56,13 +57,31 @@ async def get_all_users(
5657
Query(default=None, description="Offset for pagination")
5758
] = None,
5859
size: Annotated[
59-
Optional[int],
60+
Optional[int],
6061
Query(default=None, description="Page size for pagination")
6162
] = None,
6263
) -> GetAllUsersResponseDto:
6364
"""Get all users"""
6465
...
6566

67+
@get("/users/stream", response_class=GetUsersStreamResponseDto)
68+
async def get_users_stream(
69+
self,
70+
size: Annotated[
71+
Optional[int],
72+
Query(default=None, description="Page size, no more than 1000 (default 250)"),
73+
] = None,
74+
cursor: Annotated[
75+
Optional[str],
76+
Query(
77+
default=None,
78+
description="Cursor from the previous response (nextCursor). Omit on the first request",
79+
),
80+
] = None,
81+
) -> GetUsersStreamResponseDto:
82+
"""Get all users using cursor-based (keyset) pagination"""
83+
...
84+
6685
@delete("/users/{uuid}", response_class=DeleteUserResponseDto)
6786
async def delete_user(
6887
self,
@@ -75,7 +94,7 @@ async def delete_user(
7594
async def revoke_user_subscription(
7695
self,
7796
uuid: Annotated[str, Path(description="UUID of the user")],
78-
body: Optional[Annotated[RevokeUserRequestDto, PydanticBody()]] = None,
97+
body: Annotated[Optional[RevokeUserRequestDto], PydanticBody()] = None,
7998
) -> RevokeUserSubscriptionResponseDto:
8099
"""Revoke User Subscription"""
81100
...

remnawave/enums/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
from .client_type import ClientType
33
from .error_code import ErrorCode
44
from .fingerprint import Fingerprint
5+
from .mihomo import MihomoIpVersion
6+
from .scopes import Scope
57
from .security_layer import SecurityLayer
68
from .template_type import TemplateType
79
from .users import TrafficLimitStrategy, UserStatus
@@ -25,6 +27,8 @@
2527
"ClientType",
2628
"ALPN",
2729
"Fingerprint",
30+
"MihomoIpVersion",
31+
"Scope",
2832
"SecurityLayer",
2933
"TemplateType",
3034
"ResponseRuleConditionOperator",

0 commit comments

Comments
 (0)