Metadata-Version: 2.4
Name: Python-3xui
Version: 0.1.3
Summary: 3x-ui wrapper for python
Project-URL: Homepage, https://github.com/Artem-Potapov/3x-py
Project-URL: Issues, https://github.com/Artem-Potapov/3x-py/issues
Author-email: JustMe_001 <justme001.causation755@passinbox.com>
License-Expression: Apache-2.0
License-File: LICENSE
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Requires-Python: >=3.11
Requires-Dist: async-lru~=2.3.0
Requires-Dist: cachetools~=7.1.1
Requires-Dist: httpx~=0.28.1
Requires-Dist: pybase62~=1.0.0
Requires-Dist: pydantic<3,~=2.12.5
Requires-Dist: pyotp~=2.9.0
Requires-Dist: python-dotenv==1.2.2
Provides-Extra: testing
Requires-Dist: pytest; extra == 'testing'
Requires-Dist: pytest-asyncio; extra == 'testing'
Requires-Dist: pytest-dependency; extra == 'testing'
Requires-Dist: requests; extra == 'testing'
Description-Content-Type: text/markdown

<h1>Hi! This is my example python 3x-ui wrapper!</h1>
<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>
<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>

<h2>0.1.3 Release Notes</h2>
Adds Hysteria2 support for inbounds and client provisioning.

<h3>New: Hysteria2 support</h3>

- `Inbound.protocol` now accepts `"hysteria"` alongside `"vless"` and `"vmess"`.
- `SingleInboundClient` gains an `auth` field (the Hysteria2 secret). A new `model_validator`, `ensure_auth_or_id_present`, requires either `auth` (Hysteria2) or `uuid` (everything else). `uuid` now defaults to `""`, and both fields are dropped from the serialized payload when empty.
- `create_and_add_prod_client` detects `hysteria` inbounds and emits a random per-client `auth` instead of the deterministic Telegram-ID-derived UUID it uses for VLESS/VMess.

<h3>Misc</h3>

- New `trust_env` constructor kwarg, forwarded to `httpx.AsyncClient`. Defaults to `True`; set `False` to make httpx ignore the environment's proxy/SSL config — handy behind a socks4 proxy httpx can't use.

<h2>0.1.1r1 Release Notes</h2>
First "middle" version. Brings 3X-UI 3.0.0+ panel support and a client-side workaround for the panel's new duplicate-email behavior.

<h3>New: 3.0.0+ panel auth</h3>

Three new `XUIClient` constructor kwargs:

- `use_new_schema=True` — switches `login()` to the 3.0.0+ flow. Required for any 3.0.0+ panel.
- `bearer_token=...` — long-lived API token from the panel. Required when `use_new_schema=True`; wrapped in `SecretStr` internally and sent as `Authorization: Bearer <...>` on every request.
- `force_login=True` — additive on top of bearer. Coins a CSRF token (`/csrf-token`) and runs the cookie-login on top, for routes that still need it.

`SessionCore.login()` becomes a 3-branch dispatcher; the existing 2.X.X cookie-only flow is unchanged when `use_new_schema=False`.

Three new exceptions, all re-exported via `python_3xui.exceptions`:

- `SchemaMismatchError` — constructor-time. `use_new_schema=True` with no `bearer_token`.
- `InvalidBearerTokenError` — runtime. A 404 in pure-bearer mode would otherwise loop into `login()` re-setting the same (bad) header; the request now fast-fails instead.
- `CsrfTokenNotCoined` — runtime. `/csrf-token` didn't return a usable `obj`; the panel is almost certainly down.

<h3>New: client-side duplicate-email guard</h3>

3X-UI 3.0.0+ silently accepts duplicate client emails on add instead of hard-rejecting them, which broke the `"duplicate email"` response-msg scan that drove `exist_ok` / `replace_if_exist` in `create_and_add_prod_client`. Workaround landed in this release:

- New `guard_duplicate_emails` `XUIClient` kwarg. Defaults to `use_new_schema` (on for 3.0.0+, off for 2.X.X). Pass `True`/`False` to force.
- New `guard_duplicates` per-call override on `create_and_add_prod_client`.
- When active, the method burst-probes `get_client_with_email` for every production inbound's deterministic `(tgid, inbid)` email before adding. Hits become a `conflicts: dict[int, ClientStats]` map; the panel add is skipped for those inbounds.
- `exist_ok`, `replace_if_exist`, and raise-on-default all keep their original semantics — the guard just feeds them. `replace_if_exist` even saves a round-trip vs the old path, since the guard already has the existing client's uuid.
- Return type widens to `dict[int, Response | None]`. `None` appears only with `exist_ok=True` and no `replace_if_exist`, for the inbounds the guard short-circuited.

<h3>Fixes & misc</h3>

- `SchemaMismatchError` message rendered as a tuple instead of formatted; switched the call site to an f-string.
- `tests/conftest.py` now requires `BEARER` in the env-var precheck; without it the fixture would raise `SchemaMismatchError` at construction instead of skipping cleanly.
- Stale `FIXME` comment removed from `SessionCore.login`.
- `cachetools` pin relaxed to `~=7.1.1`.
- Public exception surface now also exports `CsrfTokenNotCoined`, `SchemaMismatchError`, and `InvalidBearerTokenError` via `python_3xui.exceptions`.

<h2>0.0.12 Release Notes</h2>
Mainly just bugfixes. Fix email fallback, fix adding clients, add inbound management.