Metadata-Version: 2.4
Name: telethon-cli
Version: 0.1.2
Summary: Command-line interface for Telethon and Telethon internals
Author: Axisrow
License-Expression: MIT
Project-URL: Homepage, https://github.com/axisrow/telethon-cli
Project-URL: Repository, https://github.com/axisrow/telethon-cli
Project-URL: Issues, https://github.com/axisrow/telethon-cli/issues
Keywords: telegram,telethon,cli,api,automation
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Communications :: Chat
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Utilities
Requires-Python: >=3.8
Description-Content-Type: text/markdown
Requires-Dist: Telethon>=1
Provides-Extra: proxy
Requires-Dist: python-socks[asyncio]>=2; extra == "proxy"

# telethon-cli

`telethon-cli` is a separate installable package that exposes:

- a stable command tree for the public `TelegramClient` API;
- a generic dispatcher for internal `telethon` and `telethon_generator` callables;
- env-first client configuration through `TG_API_ID` and `TG_API_HASH`,
  with optional session overrides.

## Installation

Install from PyPI:

```bash
python -m pip install telethon-cli
```

For local development, install the package in editable mode:

```bash
python -m pip install -e .
```

Set the required Telethon credentials before running commands. You can export
them directly in the shell:

```bash
export TG_API_ID=...
export TG_API_HASH=...
```

You can also keep them in a `.env` file in the current working directory or at
the project root:

```dotenv
TG_API_ID=...
TG_API_HASH=...
```

Legacy `TELETHON_API_ID`, `TELETHON_API_HASH`, `TELETHON_SESSION`, and
`TELETHON_PASSWORD` are still accepted as compatibility aliases. When both
namespaces are present, `telethon-cli` requires the values to match.

### User config

Settings that should persist across projects can live in an optional
user-level config file at `~/.config/telethon-cli/config.json` (override the
base directory with `XDG_CONFIG_HOME`):

```json
{
  "api_id": 12345,
  "api_hash": "...",
  "session": "/path/to/session",
  "proxy": "socks5://user:pass@host:1080"
}
```

A missing file is not an error. Unknown keys are rejected so typos never pass
silently, and secrets such as `api_hash` belong here or in the environment —
never in committed files. Inspect the effective configuration, including where
every value came from, with `telethon-cli config show`.

### Proxy

On networks where Telegram is throttled or blocked, route the client through a
proxy with `TG_PROXY` (or the `--proxy` flag, or legacy `TELETHON_PROXY`):

```dotenv
TG_PROXY=socks5://user:pass@host:1080
```

Supported schemes: `socks5`, `socks4`, `http`. DNS resolves on the proxy side
(`rdns=True`), which is what censored networks usually need. The proxy is used
by every command that connects.

The proxy support needs one extra dependency:

```bash
python -m pip install 'telethon-cli[proxy]'
```

Without it the CLI exits with an error instead of silently ignoring the proxy.

On first login, `telethon-cli` can create and store a Telethon session in the
project automatically. You can create it explicitly:

```bash
telethon-cli login
```

Typical first-run flow:

```bash
python -m pip install -e .
telethon-cli login
telethon-cli users get-me --output json
```

To remove the saved session and force a fresh login next time:

```bash
telethon-cli logout
```

Or just run the first command in an interactive terminal and let the CLI ask for
your phone number, login code, and Telegram 2FA password when needed:

```bash
telethon-cli users get-me --output json
```

By default the session is stored in `.telethon-cli/session` under the project
root. You can override it explicitly:

```bash
telethon-cli users get-me --session /path/to/session --output json
telethon-cli users get-me --env-file /path/to/telethon.env --output json
```

`telethon-cli` reads the current process environment and also loads `.env`
automatically when present. The user config file participates in the same
chain: CLI flags > environment/`.env` > user config > defaults. If the same
Telethon setting is defined in several sources with different values, the
command exits with an error instead of silently choosing one. CLI flags such
as `--api-id`, `--api-hash`, `--session`, and `--2fa-password` still override
everything.

In non-interactive environments, automatic login is not possible. In that case,
create the session in advance with `telethon-cli login` and reuse it later.

Smoke-test the installation:

```bash
telethon-cli --help
python -m telethon_cli registry public --output json
telethon-cli users get-me --output json
```

Dangerous features are gated behind project-wide developer mode. Enable it once
from settings and explicitly confirm the warning before using `call`,
`registry project`, `$ref`, or `$call` payload helpers:

```bash
telethon-cli settings developer-mode --enable --accept-dangerous-features
```

Examples:

```bash
telethon-cli users get-me --output json
telethon-cli messages send-message --entity me --message "hello"
telethon-cli call telethon.utils.parse_phone --args-json '["+1 234 567"]'
telethon-cli call telethon.tl.functions.help.GetConfigRequest --client-invoke --output json
telethon-cli settings show --output json
telethon-cli config show --output json
```

## Schema Drift (temporary)

Telethon releases lag the live Telegram TL schema. When a channel's history
contains constructors the installed telethon does not know, iterating it fails
with `TypeNotFoundError`. `telethon-cli schema` is an explicitly **temporary**
bridge for that gap until upstream telethon ships a release covering the live
schema.

Check for drift — bundled layer vs a published schema, optionally with a
read-only live probe of a channel (requires a logged-in session):

```bash
telethon-cli schema status --schema-file path/to/api.tl
telethon-cli schema status --schema-file path/to/api.tl --probe @somechannel
```

`status` is read-only and needs no developer mode. It exits non-zero when the
published layer cannot be determined, or when the probe hits unknown
constructors (their ids are listed).

Where to get a schema text: there is no public auto-updating source — the
PyPI sdist stopped shipping `telethon_generator` data, and the upstream v1
branch and docs pages lag the releases. Take `telethon_generator/data/api.tl`
from the telethon source tree of the release you want to match (or any
fresher TL schema text). `schema status --probe` is the ground truth when no
fresher text exists.

Patch the drift — generates deserialization-only classes for the constructors
missing from the installed telethon and registers them in telethon's runtime
lookup table. Gated behind developer mode; prints what it is about to do first:

```bash
telethon-cli schema patch --schema-file path/to/api.tl --dry-run
telethon-cli schema patch --schema-file path/to/api.tl --yes
telethon-cli schema patch --schema-file path/to/api.tl --probe @somechannel --yes
```

Notes:

- The artifact is a single generated file, `.telethon-cli/tl_patch.py` at the
  project root. It is applied automatically at startup for every subsequent
  command in the project. Delete the file to undo.
- Patched constructors are receive-only: sending them back is not supported.
- Re-run `schema patch` after upgrading telethon (the override detects the
  upgrade and disables itself).
- Constructors newer than the newest obtainable schema cannot be synthesized;
  the probe lists such ids as unpatchable.

## Release Process

Build and validate release artifacts locally before uploading:

```bash
rm -rf dist build src/*.egg-info
python -m pip install --upgrade build twine
python -m build
python -m twine check dist/*
```

Optional local smoke-test from the built wheel:

```bash
python -m pip install --force-reinstall dist/*.whl
telethon-cli --help
python -m telethon_cli registry public --output json
```

Upload to TestPyPI first:

```bash
python -m twine upload --repository testpypi dist/*
```

Verify installation from TestPyPI:

```bash
python -m pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple telethon-cli
telethon-cli --help
python -m telethon_cli registry public --output json
```

Then upload the same artifacts to PyPI:

```bash
python -m twine upload dist/*
```

When `twine` prompts for credentials, use username `__token__` and your
`pypi-...` API token as the password. Keep PyPI tokens out of the repository
and provide them through the environment or `twine` prompt.

### PyPI Token Scoping

PyPI API tokens can be **account-wide** or **project-scoped**:

- **Project-scoped** tokens only allow uploads to the specific project they were
  created for. A token scoped to `telethon-cli` cannot upload `direct-cli` —
  you will get **403 Forbidden**.
- **Account-wide** tokens allow uploads to any project under your account.
- For the **first publication** of a new project, you **must** use an
  account-wide token (project-scoped tokens cannot be created until the project
  exists on PyPI).
- After the first successful upload, create a project-scoped token at
  https://pypi.org/manage/account/token/ and replace the account-wide token in
  `.env`.

For every subsequent release, bump `version` in `pyproject.toml` before
building. PyPI rejects uploads for versions that already exist.

You can also keep PyPI credentials in the project-local `.env` file, because
`.env` is gitignored in this repository. The release helper script reads `.env`
automatically and publishes with `twine`:

```dotenv
TWINE_USERNAME=__token__
TEST_PYPI_TOKEN=pypi-...
PYPI_TOKEN=pypi-...
```

```bash
chmod +x scripts/release_pypi.sh
./scripts/release_pypi.sh testpypi
./scripts/release_pypi.sh pypi
./scripts/release_pypi.sh all
```
