marzban 0.4.2__py3-none-any.whl → 0.4.3__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 CHANGED
@@ -67,4 +67,4 @@ __all__ = (
67
67
  "NextPlanModel"
68
68
  )
69
69
 
70
- __version__ = "0.4.2"
70
+ __version__ = "0.4.3"
marzban/api.py CHANGED
@@ -5,6 +5,8 @@ from sshtunnel import SSHTunnelForwarder
5
5
  from datetime import datetime
6
6
  from .models import *
7
7
  from typing import Optional
8
+
9
+
8
10
  class MarzbanAPI:
9
11
  def __init__(self,
10
12
  base_url: str, *,
@@ -168,21 +170,21 @@ class MarzbanAPI:
168
170
  async def disable_all_users_admin(self, username: str, token: str) -> None:
169
171
  url = f"/api/admin/{username}/users/disable"
170
172
  await self._request("POST", url, token)
171
-
173
+
172
174
  async def activate_all_users_admin(self, username: str, token: str) -> None:
173
175
  url = f"/api/admin/{username}/users/activate"
174
176
  await self._request("POST", url, token)
175
-
177
+
176
178
  async def reset_admin_usage(self, username: str, token: str) -> Admin:
177
179
  url = f"/api/admin/usage/reset/{username}"
178
180
  response = await self._request("POST", url, token)
179
181
  return Admin(**response.json())
180
-
182
+
181
183
  async def get_admin_usage(self, username: str, token: str) -> Admin:
182
184
  url = f"/api/admin/usage/{username}"
183
185
  response = await self._request("GET", url, token)
184
186
  return response.json()
185
-
187
+
186
188
  async def get_system_stats(self, token: str) -> SystemStats:
187
189
  url = "/api/system"
188
190
  response = await self._request("GET", url, token)
@@ -200,7 +202,9 @@ class MarzbanAPI:
200
202
 
201
203
  async def modify_hosts(self, hosts: Dict[str, List[ProxyHost]], token: str) -> Dict[str, List[ProxyHost]]:
202
204
  url = "/api/hosts"
203
- response = await self._request("PUT", url, token, data=hosts)
205
+
206
+ hosts_model = HostsModel(root=hosts)
207
+ response = await self._request("PUT", url, token, data=hosts_model)
204
208
  return response.json()
205
209
 
206
210
  async def get_core_stats(self, token: str) -> CoreStats:
@@ -217,7 +221,7 @@ class MarzbanAPI:
217
221
  response = await self._request("GET", url, token)
218
222
  return response.json()
219
223
 
220
- async def modify_core_config(self, config: Dict[str, Any], token: str) -> Dict[str, Any]:
224
+ async def modify_core_config(self, config: CoreConfig, token: str) -> Dict[str, Any]:
221
225
  url = "/api/core/config"
222
226
  response = await self._request("PUT", url, token, data=config)
223
227
  return response.json()
@@ -236,7 +240,7 @@ class MarzbanAPI:
236
240
  url = f"/api/user/{username}"
237
241
  response = await self._request("PUT", url, token, data=user)
238
242
  return UserResponse(**response.json())
239
-
243
+
240
244
  async def activate_next_plan(self, username: str, token: str) -> UserResponse:
241
245
  url = f"/api/user/{username}/active-next"
242
246
  response = await self._request("POST", url, token)
@@ -260,25 +264,27 @@ class MarzbanAPI:
260
264
  username: Optional[List[str]] = None, search: Optional[str] = None,
261
265
  status: Optional[str] = None, sort: Optional[str] = None) -> UsersResponse:
262
266
  url = "/api/users"
263
- params = {"offset": offset, "limit": limit, "username": username, "search": search, "status": status, "sort": sort}
267
+ params = {"offset": offset, "limit": limit, "username": username, "search": search, "status": status,
268
+ "sort": sort}
264
269
  response = await self._request("GET", url, token, params=params)
265
270
  return UsersResponse(**response.json())
266
271
 
267
272
  async def reset_users_data_usage(self, token: str) -> None:
268
273
  url = "/api/users/reset"
269
274
  await self._request("POST", url, token)
270
-
271
- async def get_user_data_usage(self, username: str, token: str, start_date: Optional[datetime] = None, end_date: Optional[datetime] = None) -> UserUsagesResponse:
275
+
276
+ async def get_user_data_usage(self, username: str, token: str, start_date: Optional[datetime] = None,
277
+ end_date: Optional[datetime] = None) -> UserUsagesResponse:
272
278
  if isinstance(start_date, str):
273
279
  start_date = datetime.fromisoformat(start_date)
274
280
  if isinstance(end_date, str):
275
281
  end_date = datetime.fromisoformat(end_date)
276
-
282
+
277
283
  params = {
278
284
  "start": start_date.isoformat(timespec="seconds") if start_date else None,
279
285
  "end": end_date.isoformat(timespec="seconds") if end_date else None
280
286
  }
281
- params = {k: v for k, v in params.items() if v is not None}
287
+ params = {k: v for k, v in params.items() if v is not None}
282
288
  url = f"/api/user/{username}/usage"
283
289
  response = await self._request("GET", url, token, params=params)
284
290
  return UserUsagesResponse(**response.json())
marzban/models.py CHANGED
@@ -1,5 +1,6 @@
1
- from pydantic import BaseModel, field_validator, ValidationInfo, AfterValidator, ValidationError
2
- from typing import Optional, List, Dict, Any, ClassVar, Annotated, Literal
1
+ from typing import Optional, List, Dict, Any, ClassVar, Literal
2
+
3
+ from pydantic import BaseModel, field_validator, RootModel
3
4
 
4
5
 
5
6
  class Token(BaseModel):
@@ -35,10 +36,11 @@ class ProxySettings(BaseModel):
35
36
  id: Optional[str] = None
36
37
  flow: Optional[str] = None
37
38
 
39
+
38
40
  class NextPlanModel(BaseModel):
39
41
  add_remaining_traffic: bool = False
40
- data_limit: Optional[int] = 0
41
- expire: Optional[int] = 0
42
+ data_limit: Optional[int] = 0
43
+ expire: Optional[int] = 0
42
44
  fire_on_either: bool = True
43
45
 
44
46
  @field_validator("data_limit", mode="before")
@@ -47,6 +49,7 @@ class NextPlanModel(BaseModel):
47
49
  raise ValueError("Data limit in the next plan must be 0 or greater")
48
50
  return value
49
51
 
52
+
50
53
  class UserCreate(BaseModel):
51
54
  username: str
52
55
  proxies: Optional[Dict[str, ProxySettings]] = {}
@@ -149,6 +152,10 @@ class ProxyHost(BaseModel):
149
152
  is_disabled: bool
150
153
 
151
154
 
155
+ class HostsModel(RootModel):
156
+ root: Dict[str, List[ProxyHost]]
157
+
158
+
152
159
  class ProxyInbound(BaseModel):
153
160
  tag: str
154
161
  protocol: str
@@ -269,3 +276,54 @@ class SystemStats(BaseModel):
269
276
  outgoing_bandwidth: Optional[int] = None
270
277
  incoming_bandwidth_speed: Optional[int] = None
271
278
  outgoing_bandwidth_speed: Optional[int] = None
279
+
280
+
281
+ class Settings(BaseModel):
282
+ clients: Optional[List[Dict[str, Any]]] = []
283
+ decryption: Optional[str] = None
284
+ network: Optional[str] = None
285
+
286
+
287
+ class StreamSettings(BaseModel):
288
+ network: Optional[str] = None
289
+ security: Optional[str] = None
290
+ tcpSettings: Optional[Dict[str, Any]] = {}
291
+ wsSettings: Optional[Dict[str, Any]] = {}
292
+ grpcSettings: Optional[Dict[str, Any]] = {}
293
+ tlsSettings: Optional[Dict[str, Any]] = {}
294
+ realitySettings: Optional[Dict[str, Any]] = {}
295
+
296
+
297
+ class Inbound(BaseModel):
298
+ port: Optional[int] = None
299
+ protocol: Optional[str] = None
300
+ settings: Optional[Settings] = Settings()
301
+ streamSettings: Optional[StreamSettings] = StreamSettings()
302
+ sniffing: Optional[Dict[str, Any]] = {}
303
+ tag: Optional[str] = None
304
+
305
+
306
+ class Outbound(BaseModel):
307
+ protocol: Optional[str] = None
308
+ settings: Optional[Dict[str, Any]] = {}
309
+ tag: Optional[str] = None
310
+
311
+
312
+ class RoutingRule(BaseModel):
313
+ type: Optional[str] = None
314
+ ip: Optional[List[str]] = []
315
+ domain: Optional[List[str]] = []
316
+ protocol: Optional[List[str]] = []
317
+ outboundTag: Optional[str] = None
318
+
319
+
320
+ class Routing(BaseModel):
321
+ domainStrategy: Optional[str] = None
322
+ rules: Optional[List[RoutingRule]] = []
323
+
324
+
325
+ class CoreConfig(BaseModel):
326
+ log: Optional[Dict[str, Any]] = {}
327
+ inbounds: Optional[List[Inbound]] = []
328
+ outbounds: Optional[List[Outbound]] = []
329
+ routing: Optional[Routing] = Routing()
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: marzban
3
- Version: 0.4.2
3
+ Version: 0.4.3
4
4
  Summary: Асинхронная библиотека Python для взаимодействия с MarzbanAPI | Поддерживает работу через HTTPS/SSH
5
5
  Home-page: https://github.com/sm1ky/marzban_api
6
6
  Author: Artem
@@ -27,6 +27,7 @@ Dynamic: classifier
27
27
  Dynamic: description
28
28
  Dynamic: description-content-type
29
29
  Dynamic: home-page
30
+ Dynamic: license-file
30
31
  Dynamic: project-url
31
32
  Dynamic: requires-dist
32
33
  Dynamic: requires-python
@@ -0,0 +1,9 @@
1
+ marzban/__init__.py,sha256=WU4NjKb2i_Cm9ylQmVea-sPvyoBXM0X_YbvTxx4gNUE,1404
2
+ marzban/api.py,sha256=rQY4TOjW1WofLWIg1iVZN6u7ltyc_PwAgazwEfu4m8Q,19905
3
+ marzban/models.py,sha256=AVpAbcY2uqkEMfwlFff8H-lhxSY2v_CzIW7OU8fwNs0,9205
4
+ marzban/utils.py,sha256=1oweg75j_w2uuZXw96W-ZKn3WiQniqKGqj6PBU6ds74,1174
5
+ marzban-0.4.3.dist-info/licenses/LICENSE,sha256=e7OchdHfXoz2OZRHj8iltLIKYwdri9J4_9PMEnov418,1061
6
+ marzban-0.4.3.dist-info/METADATA,sha256=XT3u3us6oUocfD6sDappFWp2Fd949cA8JuEjp-nRJI4,4104
7
+ marzban-0.4.3.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
8
+ marzban-0.4.3.dist-info/top_level.txt,sha256=KUmBWzTarBlzw2GZOuk-d-jM2GU4zPWo1iwvW_mXS-c,8
9
+ marzban-0.4.3.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.8.0)
2
+ Generator: setuptools (78.1.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,9 +0,0 @@
1
- marzban/__init__.py,sha256=jKrQxf2UMpmvvKvt5r6GkHTDF30xZoSO9RJic_ofGwg,1404
2
- marzban/api.py,sha256=Prk-CyDqBQmztZaWzBmTMa4sewmutsEQiLloA27gXUs,19843
3
- marzban/models.py,sha256=Mver2ne18efsrT8xHzZjuqhTQr-f6OqJJfziI4V39Us,7754
4
- marzban/utils.py,sha256=1oweg75j_w2uuZXw96W-ZKn3WiQniqKGqj6PBU6ds74,1174
5
- marzban-0.4.2.dist-info/LICENSE,sha256=e7OchdHfXoz2OZRHj8iltLIKYwdri9J4_9PMEnov418,1061
6
- marzban-0.4.2.dist-info/METADATA,sha256=cWLn-DA0Qy5Rp5-rte9l2l2LrBroAJ79X75b3BeHlFs,4082
7
- marzban-0.4.2.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
8
- marzban-0.4.2.dist-info/top_level.txt,sha256=KUmBWzTarBlzw2GZOuk-d-jM2GU4zPWo1iwvW_mXS-c,8
9
- marzban-0.4.2.dist-info/RECORD,,