Python-3xui 0.0.8__tar.gz → 0.0.8.post1__tar.gz
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.
- {python_3xui-0.0.8 → python_3xui-0.0.8.post1}/PKG-INFO +3 -5
- {python_3xui-0.0.8 → python_3xui-0.0.8.post1}/README.md +2 -4
- {python_3xui-0.0.8 → python_3xui-0.0.8.post1}/pyproject.toml +2 -2
- {python_3xui-0.0.8 → python_3xui-0.0.8.post1}/python_3xui/api.py +21 -12
- {python_3xui-0.0.8 → python_3xui-0.0.8.post1}/python_3xui/util.py +1 -1
- {python_3xui-0.0.8 → python_3xui-0.0.8.post1}/tests/test_non_idempotent_endpoints_clients.py +2 -2
- {python_3xui-0.0.8 → python_3xui-0.0.8.post1}/.gitignore +0 -0
- {python_3xui-0.0.8 → python_3xui-0.0.8.post1}/LICENSE +0 -0
- {python_3xui-0.0.8 → python_3xui-0.0.8.post1}/python_3xui/__init__.py +0 -0
- {python_3xui-0.0.8 → python_3xui-0.0.8.post1}/python_3xui/base_model.py +0 -0
- {python_3xui-0.0.8 → python_3xui-0.0.8.post1}/python_3xui/endpoints.py +0 -0
- {python_3xui-0.0.8 → python_3xui-0.0.8.post1}/python_3xui/models.py +0 -0
- {python_3xui-0.0.8 → python_3xui-0.0.8.post1}/tests/conftest.py +0 -0
- {python_3xui-0.0.8 → python_3xui-0.0.8.post1}/tests/gather_response_stubs.py +0 -0
- {python_3xui-0.0.8 → python_3xui-0.0.8.post1}/tests/pytest.ini +0 -0
- {python_3xui-0.0.8 → python_3xui-0.0.8.post1}/tests/test_endpoints_clients.py +0 -0
- {python_3xui-0.0.8 → python_3xui-0.0.8.post1}/tests/test_endpoints_inbounds.py +0 -0
- {python_3xui-0.0.8 → python_3xui-0.0.8.post1}/tests/test_non_idempotent_endpoints_inbounds.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: Python-3xui
|
|
3
|
-
Version: 0.0.8
|
|
3
|
+
Version: 0.0.8.post1
|
|
4
4
|
Summary: 3x-ui wrapper for python
|
|
5
5
|
Project-URL: Homepage, https://github.com/Artem-Potapov/3x-py
|
|
6
6
|
Project-URL: Issues, https://github.com/Artem-Potapov/3x-py/issues
|
|
@@ -28,9 +28,7 @@ Description-Content-Type: text/markdown
|
|
|
28
28
|
<p>I'm not expecting much to be honest, so please feel free to fork it if I abandon the project and you need it!</p>
|
|
29
29
|
<p>Also, if you REALLY want it I can give you the ownership if I step down, you can find my email in the pyproject.toml (I don't check it that much but trust me I do)</p>
|
|
30
30
|
|
|
31
|
-
<h2>0.0.
|
|
31
|
+
<h2>0.0.81 Release Notes</h2>
|
|
32
32
|
<ul>
|
|
33
|
-
<li>
|
|
34
|
-
<li>delete_client_by_tgid_all_inbounds -> revoke_client_by_tgid_all_inbounds</li>
|
|
35
|
-
<li>Change vulnerable requirements</li>
|
|
33
|
+
<li>Minor change: make custom sub generators available instead of the default one</li>
|
|
36
34
|
</ul>
|
|
@@ -2,9 +2,7 @@
|
|
|
2
2
|
<p>I'm not expecting much to be honest, so please feel free to fork it if I abandon the project and you need it!</p>
|
|
3
3
|
<p>Also, if you REALLY want it I can give you the ownership if I step down, you can find my email in the pyproject.toml (I don't check it that much but trust me I do)</p>
|
|
4
4
|
|
|
5
|
-
<h2>0.0.
|
|
5
|
+
<h2>0.0.81 Release Notes</h2>
|
|
6
6
|
<ul>
|
|
7
|
-
<li>
|
|
8
|
-
<li>delete_client_by_tgid_all_inbounds -> revoke_client_by_tgid_all_inbounds</li>
|
|
9
|
-
<li>Change vulnerable requirements</li>
|
|
7
|
+
<li>Minor change: make custom sub generators available instead of the default one</li>
|
|
10
8
|
</ul>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "Python-3xui"
|
|
3
|
-
version = "0.0.
|
|
3
|
+
version = "0.0.8r1"
|
|
4
4
|
authors = [
|
|
5
5
|
{ name="JustMe_001", email="justme001.causation755@passinbox.com" },
|
|
6
6
|
]
|
|
@@ -56,4 +56,4 @@ exclude = [
|
|
|
56
56
|
|
|
57
57
|
|
|
58
58
|
[[tool.hatch.envs.hatch-test.matrix]]
|
|
59
|
-
python = ["3.12", "3.11"]
|
|
59
|
+
python = ["3.13", "3.12", "3.11"]
|
|
@@ -3,8 +3,9 @@ import logging
|
|
|
3
3
|
import re
|
|
4
4
|
import time
|
|
5
5
|
from collections.abc import Sequence, Mapping
|
|
6
|
+
from inspect import isawaitable
|
|
6
7
|
from logging import DEBUG
|
|
7
|
-
from typing import Self, Optional, Dict, Iterable, AsyncIterable, Type, Union, Any, List, Tuple, Literal
|
|
8
|
+
from typing import Self, Optional, Dict, Iterable, AsyncIterable, Type, Union, Any, List, Tuple, Literal, Callable, Awaitable, Coroutine
|
|
8
9
|
from datetime import datetime, UTC
|
|
9
10
|
|
|
10
11
|
import pyotp
|
|
@@ -67,7 +68,9 @@ class XUIClient:
|
|
|
67
68
|
def __init__(self, base_website: str, base_port: int, base_path: str,
|
|
68
69
|
*, username: str | None = None, password: str | None = None,
|
|
69
70
|
two_fac_code: str | None = None, session_duration: int = 3600,
|
|
70
|
-
custom_prod_string: str = "testing"
|
|
71
|
+
custom_prod_string: str = "testing",
|
|
72
|
+
custom_sub_generator: Callable[[int], str]|Callable[[int], Awaitable[str]] = util.default_sub_from_tgid
|
|
73
|
+
) -> None:
|
|
71
74
|
"""Initialize the XUIClient.
|
|
72
75
|
|
|
73
76
|
Args:
|
|
@@ -95,6 +98,7 @@ class XUIClient:
|
|
|
95
98
|
self.totp: pyotp.TOTP | None = None
|
|
96
99
|
self.max_retries: int = 5
|
|
97
100
|
self.retry_delay: int = 1
|
|
101
|
+
self.sub_gen = custom_sub_generator
|
|
98
102
|
# endpoints
|
|
99
103
|
self.server_end = endpoints.Server(self)
|
|
100
104
|
self.clients_end = endpoints.Clients(self)
|
|
@@ -421,6 +425,11 @@ class XUIClient:
|
|
|
421
425
|
production_inbounds: List[Inbound] = await self.get_production_inbounds()
|
|
422
426
|
|
|
423
427
|
tasks = []
|
|
428
|
+
custom_sub: str
|
|
429
|
+
if isawaitable(self.sub_gen(telegram_id)):
|
|
430
|
+
custom_sub = await self.sub_gen(telegram_id)
|
|
431
|
+
else:
|
|
432
|
+
custom_sub = self.sub_gen(telegram_id)
|
|
424
433
|
for inb in production_inbounds:
|
|
425
434
|
tmp_email = util.generate_email_from_tgid_inbid(telegram_id, inb.id)
|
|
426
435
|
client = SingleInboundClient.model_construct(
|
|
@@ -429,7 +438,7 @@ class XUIClient:
|
|
|
429
438
|
email=tmp_email,
|
|
430
439
|
limit_gb=0,
|
|
431
440
|
enable=True,
|
|
432
|
-
subscription_id=
|
|
441
|
+
subscription_id=custom_sub,
|
|
433
442
|
comment=f"{additional_remark}, created at {datetime.now(UTC)}",
|
|
434
443
|
expiry_time=expiry_time * 1000
|
|
435
444
|
)
|
|
@@ -460,15 +469,15 @@ class XUIClient:
|
|
|
460
469
|
Args:
|
|
461
470
|
telegram_id: The Telegram ID of the client
|
|
462
471
|
inbound_id: The ID of the inbound where the client exists
|
|
463
|
-
security: Client security setting
|
|
464
|
-
password: Client password
|
|
465
|
-
flow: VLESS flow type
|
|
466
|
-
limit_ip: IP connection limit
|
|
467
|
-
limit_gb: Data limit in GB
|
|
468
|
-
expiry_time: Client expiry time (UNIX timestamp)
|
|
469
|
-
enable: Whether the client is enabled
|
|
470
|
-
sub_id: Subscription ID
|
|
471
|
-
comment: Client comment/note
|
|
472
|
+
security: Client security setting (optional)
|
|
473
|
+
password: Client password (optional)
|
|
474
|
+
flow: VLESS flow type (optional)
|
|
475
|
+
limit_ip: IP connection limit (optional)
|
|
476
|
+
limit_gb: Data limit in GB (optional)
|
|
477
|
+
expiry_time: Client expiry time (UNIX timestamp) (optional)
|
|
478
|
+
enable: Whether the client is enabled (optional)
|
|
479
|
+
sub_id: Subscription ID (optional)
|
|
480
|
+
comment: Client comment/note (optional)
|
|
472
481
|
|
|
473
482
|
Returns:
|
|
474
483
|
Response from the API
|
|
@@ -79,7 +79,7 @@ def base64_from_string(string: str, omit_trailing_equals: bool = False) -> str:
|
|
|
79
79
|
return base64.b64encode(bytes(str(string).encode("utf-8"))).decode()
|
|
80
80
|
|
|
81
81
|
|
|
82
|
-
def
|
|
82
|
+
def default_sub_from_tgid(telegram_id: int) -> str:
|
|
83
83
|
"""Generate a subscription ID from a Telegram ID.
|
|
84
84
|
|
|
85
85
|
Args:
|
{python_3xui-0.0.8 → python_3xui-0.0.8.post1}/tests/test_non_idempotent_endpoints_clients.py
RENAMED
|
@@ -8,7 +8,7 @@ from pydantic import ValidationError
|
|
|
8
8
|
|
|
9
9
|
from python_3xui.api import XUIClient
|
|
10
10
|
from python_3xui.models import SingleInboundClient, ClientStats
|
|
11
|
-
from python_3xui.util import get_uuid_from_tgid,
|
|
11
|
+
from python_3xui.util import get_uuid_from_tgid, s_to_ms_timestamp, datetime_now_ms, generate_email_from_tgid_inbid, \
|
|
12
12
|
generate_random_email
|
|
13
13
|
|
|
14
14
|
|
|
@@ -72,7 +72,7 @@ class TestClientsEndpoint:
|
|
|
72
72
|
expiryTime=timestamp + 86400*1000, # Using alias 'expiryTime' for 'expiry_time'
|
|
73
73
|
enable=True,
|
|
74
74
|
tgId="", # Using alias 'tgId' for 'tg_id'
|
|
75
|
-
subId=
|
|
75
|
+
subId=xui_client.sub_gen(TestClientsEndpoint.test_telegram_id), # Using alias 'subId' for 'subscription_id'
|
|
76
76
|
comment=f"Test client created at {timestamp}, TEST SUITE",
|
|
77
77
|
created_at=timestamp,
|
|
78
78
|
updated_at=timestamp
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_3xui-0.0.8 → python_3xui-0.0.8.post1}/tests/test_non_idempotent_endpoints_inbounds.py
RENAMED
|
File without changes
|