Skip to content

Commit e6680dc

Browse files
authored
Bump to 2.1.8. Other details in commit message
Update to version 2.1.8 with API enhancements
2 parents b6ca96f + c8e13c4 commit e6680dc

File tree

8 files changed

+102
-23
lines changed

8 files changed

+102
-23
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ pip install git+https://github.com/remnawave/python-sdk.git@development
6363

6464
| Contract Version | Remnawave Panel Version |
6565
| ---------------- | ----------------------- |
66-
| 2.1.7.post1 | >=2.1.7 |
66+
| 2.1.8 | >=2.1.8 |
67+
| 2.1.7.post1 | ==2.1.7 |
6768
| 2.1.4 | >=2.1.4, <2.1.7 |
6869
| 2.1.1 | >=2.1.1, <2.1.4 |
6970
| 2.0.0 | >=2.0.0,<2.1.0 |

pyproject.toml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[project]
22
name = "remnawave"
3-
version = "2.1.7.post1"
4-
description = "A Python SDK for interacting with the Remnawave API v2.1.7."
3+
version = "2.1.8"
4+
description = "A Python SDK for interacting with the Remnawave API v2.1.8."
55
authors = [
66
{name = "Artem",email = "[email protected]"}
77
]
@@ -28,6 +28,10 @@ classifiers = [
2828
"Programming Language :: Python :: Implementation :: CPython",
2929
"Programming Language :: Python :: Implementation :: PyPy",
3030
"Framework :: AsyncIO",
31+
"Topic :: Software Development :: Libraries :: Python Modules",
32+
"Topic :: Internet :: WWW/HTTP",
33+
"Topic :: Utilities",
34+
"Topic :: Rest APIs",
3135
]
3236

3337
[project.urls]

remnawave/controllers/subscription.py

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@
33
from rapid_api_client import Path
44

55
from remnawave.enums import ClientType
6-
from remnawave.models import GetSubscriptionInfoResponseDto, GetRawSubscriptionByShortUuidResponseDto
6+
from remnawave.models import GetSubscriptionInfoResponseDto
77
from remnawave.rapid import BaseController, get
88

99

1010
class SubscriptionController(BaseController):
11+
# Public endpoints below
1112
@get("/sub/{short_uuid}/info", response_class=GetSubscriptionInfoResponseDto)
1213
async def get_subscription_info_by_short_uuid(
1314
self,
@@ -50,15 +51,5 @@ async def get_subscription_with_type(
5051
),
5152
] = "VGVzdGVy",
5253
) -> str:
53-
"""None"""
54-
...
55-
56-
# get raw sub by short uuid
57-
@get("/sub/{short_uuid}/raw", response_class=GetRawSubscriptionByShortUuidResponseDto)
58-
async def get_raw_subscription(
59-
self,
60-
short_uuid: Annotated[str, Path(description="Short UUID of the user")],
61-
withDisabledHosts: Annotated[Annotated[bool, Path(description="Include disabled hosts")], bool] = False,
62-
) -> GetRawSubscriptionByShortUuidResponseDto:
6354
"""None"""
6455
...

remnawave/controllers/subscriptions_controller.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@
33
from rapid_api_client import Path, Query
44

55
from remnawave.enums import ClientType
6+
from remnawave.models.subscription import GetRawSubscriptionByShortUuidResponseDto
67
from remnawave.rapid import BaseController, get
78
from remnawave.models import GetAllSubscriptionsResponseDto, GetSubscriptionByUsernameResponseDto, GetSubscriptionByShortUUIDResponseDto, GetSubscriptionByUUIDResponseDto
89

910

1011
class SubscriptionsController(BaseController):
12+
# Protected endpoints below
1113
@get("/subscriptions", response_class=GetAllSubscriptionsResponseDto)
1214
async def get_all_subscriptions(
1315
self,
@@ -42,5 +44,14 @@ async def get_subscription_by_uuid(
4244
self,
4345
uuid: Annotated[str, Path(description="UUID of the user")],
4446
) -> GetSubscriptionByUUIDResponseDto:
47+
"""None"""
48+
...
49+
50+
@get("/subscriptions/by-short-uuid/{short_uuid}/raw", response_class=GetRawSubscriptionByShortUuidResponseDto)
51+
async def get_raw_subscription(
52+
self,
53+
short_uuid: Annotated[str, Path(description="Short UUID of the user")],
54+
withDisabledHosts: Annotated[Annotated[bool, Path(description="Include disabled hosts")], bool] = False,
55+
) -> GetRawSubscriptionByShortUuidResponseDto:
4556
"""None"""
4657
...

remnawave/controllers/system.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
GetStatsResponseDto,
55
GetNodesMetricsResponseDto,
66
GetRemnawaveHealthResponseDto,
7+
GetX25519KeyPairResponseDto
78
)
89
from remnawave.rapid import BaseController, get
910

@@ -43,3 +44,10 @@ async def get_nodes_metrics(
4344
) -> GetNodesMetricsResponseDto:
4445
"""Get Nodes Metrics"""
4546
...
47+
48+
@get("/system/tools/x25519/generate", response_class=GetX25519KeyPairResponseDto)
49+
async def get_x25519_key_pair(
50+
self,
51+
) -> GetX25519KeyPairResponseDto:
52+
"""Get X25519 Key Pair"""
53+
...

remnawave/models/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,8 @@
199199
StatusCounts,
200200
UsersStatistic,
201201
GetNodesMetricsResponseDto,
202+
GetX25519KeyPairResponseDto,
203+
X25519KeyPair,
202204
)
203205
from .users import (
204206
ActiveInternalSquadDto,
@@ -327,6 +329,8 @@
327329
"StatusCounts",
328330
"UsersStatistic",
329331
"GetNodesMetricsResponseDto",
332+
"GetX25519KeyPairResponseDto",
333+
"X25519KeyPair",
330334
# XRay config models
331335
"ConfigResponseDto", # Legacy alias
332336
"GetConfigResponseDto",

remnawave/models/subscription.py

Lines changed: 62 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from datetime import datetime
22
from typing import Any, Dict, List, Optional
3+
from uuid import UUID
34

45
from pydantic import BaseModel, Field
56

@@ -25,7 +26,6 @@ class UserSubscription(BaseModel):
2526
user_status: UserStatus = Field(alias="userStatus")
2627
is_active: bool = Field(alias="isActive")
2728

28-
2929
class SubscriptionInfoData(BaseModel):
3030
is_found: bool = Field(alias="isFound")
3131
user: UserSubscription
@@ -43,6 +43,63 @@ class GetSubscriptionInfoResponseDto(BaseModel):
4343
subscription_url: str = Field(alias="subscriptionUrl")
4444
happ: HappCrypto
4545

46+
class UserLastConnectedNodeDto(BaseModel):
47+
connected_at: datetime = Field(alias="connectedAt")
48+
node_name: str = Field(alias="nodeName")
49+
country_code: Optional[str] = Field(None, alias="countryCode") # новое поле
50+
51+
class ActiveInternalSquadDto(BaseModel):
52+
uuid: UUID
53+
name: str
54+
55+
class HappCrypto(BaseModel):
56+
crypto_link: str = Field(alias="cryptoLink")
57+
58+
class UserResponseDto(BaseModel):
59+
uuid: UUID
60+
short_uuid: str = Field(alias="shortUuid")
61+
username: str
62+
status: str
63+
used_traffic_bytes: float = Field(alias="usedTrafficBytes")
64+
lifetime_used_traffic_bytes: float = Field(alias="lifetimeUsedTrafficBytes")
65+
traffic_limit_bytes: int = Field(alias="trafficLimitBytes")
66+
traffic_limit_strategy: str = Field(alias="trafficLimitStrategy")
67+
sub_last_user_agent: Optional[str] = Field(None, alias="subLastUserAgent")
68+
sub_last_opened_at: Optional[datetime] = Field(None, alias="subLastOpenedAt")
69+
expire_at: datetime = Field(alias="expireAt")
70+
online_at: Optional[datetime] = Field(None, alias="onlineAt")
71+
sub_revoked_at: Optional[datetime] = Field(None, alias="subRevokedAt")
72+
last_traffic_reset_at: Optional[datetime] = Field(None, alias="lastTrafficResetAt")
73+
trojan_password: str = Field(alias="trojanPassword")
74+
vless_uuid: UUID = Field(alias="vlessUuid")
75+
ss_password: str = Field(alias="ssPassword")
76+
description: Optional[str] = None
77+
tag: Optional[str] = None
78+
telegram_id: Optional[int] = Field(None, alias="telegramId")
79+
email: Optional[str] = None
80+
hwidDeviceLimit: Optional[int] = Field(None, alias="hwidDeviceLimit")
81+
first_connected_at: Optional[datetime] = Field(None, alias="firstConnectedAt")
82+
last_triggered_threshold: int = Field(alias="lastTriggeredThreshold")
83+
created_at: datetime = Field(alias="createdAt")
84+
updated_at: datetime = Field(alias="updatedAt")
85+
active_internal_squads: List[ActiveInternalSquadDto] = Field(alias="activeInternalSquads")
86+
subscription_url: str = Field(alias="subscriptionUrl")
87+
last_connected_node: Optional[UserLastConnectedNodeDto] = Field(None, alias="lastConnectedNode")
88+
happ: Optional[HappCrypto] = Field(None, alias="happ")
89+
90+
class ConvertedUserInfo(BaseModel):
91+
days_left: int = Field(alias="daysLeft")
92+
traffic_limit: str = Field(alias="trafficLimit")
93+
traffic_used: str = Field(alias="trafficUsed")
94+
lifetime_traffic_used: str = Field(alias="lifetimeTrafficUsed")
95+
is_hwid_limited: bool = Field(alias="isHwidLimited")
96+
97+
class Passwords(BaseModel):
98+
ss_password: Optional[str] = Field(None, alias="ssPassword")
99+
trojan_password: Optional[str] = Field(None, alias="trojanPassword")
100+
vless_password: Optional[str] = Field(None, alias="vlessPassword")
101+
102+
46103

47104
class RawHostAdditionalParams(BaseModel):
48105
mode: Optional[str] = None
@@ -68,14 +125,13 @@ class RawHostDbData(BaseModel):
68125
is_hidden: bool = Field(alias="isHidden")
69126
tag: Optional[str] = None
70127

71-
72128
class RawHost(BaseModel):
73129
address: Optional[str] = None
74130
alpn: Optional[str] = None
75131
fingerprint: Optional[str] = None
76132
host: Optional[str] = None
77133
network: Optional[str] = None
78-
password: Optional[str] = None
134+
password: Optional[Passwords] = None
79135
path: Optional[str] = None
80136
public_key: Optional[str] = Field(None, alias="publicKey")
81137
port: Optional[int] = None
@@ -95,14 +151,11 @@ class RawHost(BaseModel):
95151
protocol_options: Optional[RawHostProtocolOptions] = Field(None, alias="protocolOptions")
96152
db_data: RawHostDbData = Field(alias="dbData")
97153

98-
99154
class RawSubscriptionResponse(BaseModel):
100-
user: UserSubscription
101-
subscription_url: str = Field(alias="subscriptionUrl")
102-
raw_hosts: List[RawHost] = Field(alias="rawHosts")
155+
user: UserResponseDto
156+
converted_user_info: ConvertedUserInfo = Field(alias="convertedUserInfo")
103157
headers: Dict[str, str]
104-
is_hwid_limited: bool = Field(alias="isHwidLimited")
105-
158+
raw_hosts: List[RawHost] = Field(alias="rawHosts")
106159

107160
class GetRawSubscriptionByShortUuidResponseDto(RawSubscriptionResponse):
108161
pass

remnawave/models/system.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,3 +121,10 @@ class NodeMetric(BaseModel):
121121

122122
class GetNodesMetricsResponseDto(BaseModel):
123123
response: List[NodeMetric]
124+
125+
class X25519KeyPair(BaseModel):
126+
public_key: str = Field(alias="publicKey")
127+
private_key: str = Field(alias="privateKey")
128+
129+
class GetX25519KeyPairResponseDto(BaseModel):
130+
key_pairs: List[X25519KeyPair] = Field(alias="keyPairs")

0 commit comments

Comments
 (0)