marzban 0.3.3__py3-none-any.whl → 0.4.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- marzban/__init__.py +5 -3
- marzban/api.py +22 -3
- marzban/models.py +21 -7
- {marzban-0.3.3.dist-info → marzban-0.4.0.dist-info}/METADATA +7 -1
- marzban-0.4.0.dist-info/RECORD +8 -0
- marzban-0.3.3.dist-info/RECORD +0 -8
- {marzban-0.3.3.dist-info → marzban-0.4.0.dist-info}/LICENSE +0 -0
- {marzban-0.3.3.dist-info → marzban-0.4.0.dist-info}/WHEEL +0 -0
- {marzban-0.3.3.dist-info → marzban-0.4.0.dist-info}/top_level.txt +0 -0
marzban/__init__.py
CHANGED
@@ -27,7 +27,8 @@ from .models import (
|
|
27
27
|
HTTPValidationError,
|
28
28
|
ValidationError,
|
29
29
|
SubscriptionUserResponse,
|
30
|
-
SystemStats
|
30
|
+
SystemStats,
|
31
|
+
NextPlanModel
|
31
32
|
)
|
32
33
|
|
33
34
|
__all__ = (
|
@@ -60,7 +61,8 @@ __all__ = (
|
|
60
61
|
"HTTPValidationError",
|
61
62
|
"ValidationError",
|
62
63
|
"SubscriptionUserResponse",
|
63
|
-
"SystemStats"
|
64
|
+
"SystemStats",
|
65
|
+
"NextPlanModel"
|
64
66
|
)
|
65
67
|
|
66
|
-
__version__ = "0.
|
68
|
+
__version__ = "0.4.0"
|
marzban/api.py
CHANGED
@@ -2,10 +2,9 @@ import httpx
|
|
2
2
|
import paramiko
|
3
3
|
from paramiko.ssh_exception import SSHException
|
4
4
|
from sshtunnel import SSHTunnelForwarder
|
5
|
-
|
5
|
+
from datetime import datetime
|
6
6
|
from .models import *
|
7
|
-
|
8
|
-
|
7
|
+
from typing import Optional
|
9
8
|
class MarzbanAPI:
|
10
9
|
def __init__(self,
|
11
10
|
base_url: str, *,
|
@@ -219,6 +218,11 @@ class MarzbanAPI:
|
|
219
218
|
url = f"/api/user/{username}"
|
220
219
|
response = await self._request("PUT", url, token, data=user)
|
221
220
|
return UserResponse(**response.json())
|
221
|
+
|
222
|
+
async def activate_next_plan(self, username: str, token: str) -> UserResponse:
|
223
|
+
url = f"/api/user/{username}/active-next"
|
224
|
+
response = await self._request("POST", url, token)
|
225
|
+
return UserResponse(**response.json())
|
222
226
|
|
223
227
|
async def remove_user(self, username: str, token: str) -> None:
|
224
228
|
url = f"/api/user/{username}"
|
@@ -245,6 +249,21 @@ class MarzbanAPI:
|
|
245
249
|
async def reset_users_data_usage(self, token: str) -> None:
|
246
250
|
url = "/api/users/reset"
|
247
251
|
await self._request("POST", url, token)
|
252
|
+
|
253
|
+
async def get_user_data_usage(self, username: str, token: str, start_date: Optional[datetime] = None, end_date: Optional[datetime] = None) -> UserUsagesResponse:
|
254
|
+
if isinstance(start_date, str):
|
255
|
+
start_date = datetime.fromisoformat(start_date)
|
256
|
+
if isinstance(end_date, str):
|
257
|
+
end_date = datetime.fromisoformat(end_date)
|
258
|
+
|
259
|
+
params = {
|
260
|
+
"start": start_date.isoformat(timespec="seconds") if start_date else None,
|
261
|
+
"end": end_date.isoformat(timespec="seconds") if end_date else None
|
262
|
+
}
|
263
|
+
params = {k: v for k, v in params.items() if v is not None}
|
264
|
+
url = f"/api/user/{username}/usage"
|
265
|
+
response = await self._request("GET", url, token, params=params)
|
266
|
+
return UserUsagesResponse(**response.json())
|
248
267
|
|
249
268
|
async def set_owner(self, username: str, admin_username: str, token: str) -> UserResponse:
|
250
269
|
url = f"/api/user/{username}/set-owner?admin_username={admin_username}"
|
marzban/models.py
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
from pydantic import BaseModel, field_validator, ValidationInfo, AfterValidator, ValidationError
|
2
|
-
from typing import Optional, List, Dict, Any, ClassVar, Annotated
|
2
|
+
from typing import Optional, List, Dict, Any, ClassVar, Annotated, Literal
|
3
3
|
|
4
4
|
|
5
5
|
class Token(BaseModel):
|
@@ -33,6 +33,17 @@ class ProxySettings(BaseModel):
|
|
33
33
|
id: Optional[str] = None
|
34
34
|
flow: Optional[str] = None
|
35
35
|
|
36
|
+
class NextPlanModel(BaseModel):
|
37
|
+
add_remaining_traffic: bool = False
|
38
|
+
data_limit: Optional[int] = 0
|
39
|
+
expire: Optional[int] = 0
|
40
|
+
fire_on_either: bool = True
|
41
|
+
|
42
|
+
@field_validator("data_limit", mode="before")
|
43
|
+
def validate_data_limit(cls, value):
|
44
|
+
if value is not None and value < 0:
|
45
|
+
raise ValueError("Data limit in the next plan must be 0 or greater")
|
46
|
+
return value
|
36
47
|
|
37
48
|
class UserCreate(BaseModel):
|
38
49
|
username: str
|
@@ -47,7 +58,8 @@ class UserCreate(BaseModel):
|
|
47
58
|
online_at: Optional[str] = None
|
48
59
|
on_hold_expire_duration: Optional[int] = 0
|
49
60
|
on_hold_timeout: Optional[str] = None
|
50
|
-
status:
|
61
|
+
status: Literal["active", "on_hold"] = "active"
|
62
|
+
next_plan: Optional[NextPlanModel] = None
|
51
63
|
|
52
64
|
|
53
65
|
class UserResponse(BaseModel):
|
@@ -63,15 +75,16 @@ class UserResponse(BaseModel):
|
|
63
75
|
online_at: Optional[str] = None
|
64
76
|
on_hold_expire_duration: Optional[int] = None
|
65
77
|
on_hold_timeout: Optional[str] = None
|
66
|
-
status:
|
67
|
-
admin: Optional[Admin] = None
|
78
|
+
status: Literal["active", "disabled", "limited", "expired", "on_hold"] = "active"
|
68
79
|
used_traffic: Optional[int] = None
|
69
80
|
lifetime_used_traffic: Optional[int] = None
|
70
|
-
created_at: Optional[str] = None
|
71
81
|
links: Optional[List[str]] = []
|
72
82
|
subscription_url: Optional[str] = None
|
73
83
|
subscription_token: Optional[str] = None
|
74
84
|
excluded_inbounds: Optional[Dict[str, List[str]]] = None
|
85
|
+
next_plan: Optional[NextPlanModel] = None
|
86
|
+
admin: Optional[Admin] = None
|
87
|
+
created_at: Optional[str] = None
|
75
88
|
|
76
89
|
def __init__(self, **data):
|
77
90
|
super().__init__(**data)
|
@@ -152,7 +165,7 @@ class UserModify(BaseModel):
|
|
152
165
|
proxies: Optional[Dict[str, ProxySettings]] = {}
|
153
166
|
expire: Optional[int] = None
|
154
167
|
data_limit: Optional[int] = None
|
155
|
-
data_limit_reset_strategy: Optional[
|
168
|
+
data_limit_reset_strategy: Optional[Literal["no_reset", "day", "week", "month", "year"]] = None
|
156
169
|
inbounds: Optional[Dict[str, List[str]]] = None
|
157
170
|
note: Optional[str] = None
|
158
171
|
sub_updated_at: Optional[str] = None
|
@@ -160,7 +173,8 @@ class UserModify(BaseModel):
|
|
160
173
|
online_at: Optional[str] = None
|
161
174
|
on_hold_expire_duration: Optional[int] = None
|
162
175
|
on_hold_timeout: Optional[str] = None
|
163
|
-
status: Optional[
|
176
|
+
status: Optional[Literal["active", "disabled", "limited", "expired", "on_hold"]] = None
|
177
|
+
next_plan: Optional[NextPlanModel] = None
|
164
178
|
|
165
179
|
|
166
180
|
class UserTemplateCreate(BaseModel):
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: marzban
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.4.0
|
4
4
|
Summary: Асинхронная библиотека Python для взаимодействия с MarzbanAPI | Поддерживает работу через HTTPS/SSH
|
5
5
|
Home-page: https://github.com/sm1ky/marzban_api
|
6
6
|
Author: Artem
|
@@ -20,6 +20,7 @@ Requires-Dist: httpx>=0.23.0
|
|
20
20
|
Requires-Dist: pydantic>=1.10.0
|
21
21
|
Requires-Dist: paramiko>=3.5.0
|
22
22
|
Requires-Dist: sshtunnel>=0.4.0
|
23
|
+
Requires-Dist: datetime>=5.5
|
23
24
|
|
24
25
|
|
25
26
|
# MarzbanAPI Client
|
@@ -30,8 +31,13 @@ Requires-Dist: sshtunnel>=0.4.0
|
|
30
31
|
[](https://pypi.python.org/pypi/marzban)
|
31
32
|
[](https://pypi.python.org/pypi/marzban)
|
32
33
|
[](https://pypi.python.org/pypi/marzban)
|
34
|
+
[](https://github.com/Gozargah/Marzban)
|
35
|
+
|
33
36
|
|
34
37
|
**MarzbanAPI Client** is an asynchronous Python library designed for interacting with [Marzban](https://github.com/Gozargah/Marzban). It provides comprehensive methods for managing administrators, users, nodes, and system statistics.
|
38
|
+
It supports **Marzban version 0.8.0**, providing comprehensive methods for managing administrators, users, nodes, and system statistics.
|
39
|
+
|
40
|
+
To see the list of supported Marzban versions and corresponding API compatibility, check out our [Supported Versions](https://github.com/sm1ky/marzban_api/blob/production/.readme/supported_version.md) file.
|
35
41
|
|
36
42
|
## Installation
|
37
43
|
|
@@ -0,0 +1,8 @@
|
|
1
|
+
marzban/__init__.py,sha256=1nT8atlpx5HEbJIXcLBJyftIlZGvmx8bVLiF3UNNutA,1342
|
2
|
+
marzban/api.py,sha256=gX_DTYzO8bkD_5lw399hn7g4mZbjS5TInhnjPxQD6hM,19024
|
3
|
+
marzban/models.py,sha256=9cJsMaZa5so67cQcw9fbCwyqui_0dHNvY0CysOk7blw,7678
|
4
|
+
marzban-0.4.0.dist-info/LICENSE,sha256=e7OchdHfXoz2OZRHj8iltLIKYwdri9J4_9PMEnov418,1061
|
5
|
+
marzban-0.4.0.dist-info/METADATA,sha256=-bvXr3P86T6UJQzTwRNI0YMo5z2LWSAg12EMJwyAGbM,3658
|
6
|
+
marzban-0.4.0.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
|
7
|
+
marzban-0.4.0.dist-info/top_level.txt,sha256=KUmBWzTarBlzw2GZOuk-d-jM2GU4zPWo1iwvW_mXS-c,8
|
8
|
+
marzban-0.4.0.dist-info/RECORD,,
|
marzban-0.3.3.dist-info/RECORD
DELETED
@@ -1,8 +0,0 @@
|
|
1
|
-
marzban/__init__.py,sha256=j8R4BtzQfxUTiJYGEe_QMV2fFbcukPhw9-VKiVcBwLM,1302
|
2
|
-
marzban/api.py,sha256=fKxxyJx_Hm6iM7jFmJIYdA4GiSI_7zEP7DzawxfZiN4,17912
|
3
|
-
marzban/models.py,sha256=p9QWCmNcDJQZO1EZm4ihgwS7ZJpayaMjo4fFGOpW3cE,6947
|
4
|
-
marzban-0.3.3.dist-info/LICENSE,sha256=e7OchdHfXoz2OZRHj8iltLIKYwdri9J4_9PMEnov418,1061
|
5
|
-
marzban-0.3.3.dist-info/METADATA,sha256=QNdYzqDND3Pp6H6KiI6aEXyZnyQCGZ-o7xK-VYiMkdM,3159
|
6
|
-
marzban-0.3.3.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
|
7
|
-
marzban-0.3.3.dist-info/top_level.txt,sha256=KUmBWzTarBlzw2GZOuk-d-jM2GU4zPWo1iwvW_mXS-c,8
|
8
|
-
marzban-0.3.3.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|