Skip to Content
ReferencePythonopentele2.td

opentele2.td

Telegram Desktop folders and their accounts and keys, read and written by opentele2._native.

from opentele2.td import Account, AuthKey, AuthKeyType, TDesktop

TDesktop

A Telegram Desktop client: the accounts of one tdata folder, loaded and saved by the core.

opentele2/td/tdesktop.py
class TDesktop: kMaxAccounts: int = TData.MAX_ACCOUNTS # 6 kDefaultKeyFile: str = "data" kPerformanceMode: bool = True def __init__( self, basePath: str | None = None, api: type[APIData] | APIData = API.TelegramDesktop, passcode: str | None = None, keyFile: str | None = None, ) -> None: ...

With a basePath the folder is loaded at once; without one the instance is empty until LoadTData or until accounts are added through FromTelethon.

Methods

opentele2/td/tdesktop.py
def isLoaded(self) -> bool: ... def LoadTData(self, basePath: str | None = None, passcode: str | None = None, keyFile: str | None = None) -> None: ... def SaveTData(self, basePath: str | None = None, passcode: str | None = None, keyFile: str | None = None, *, draws: Iterable[bytes] | None = None) -> bool: ... async def ToTelethon(self, session: str | Session | None = None, flag: type[LoginFlag] = CreateNewSession, api: type[APIData] | APIData = API.TelegramDesktop, password: str | None = None, **kwargs: Unpack[TelethonClientKwargs]) -> tl.TelegramClient: ... @staticmethod async def FromTelethon(telethonClient: tl.TelegramClient, flag: type[LoginFlag] = CreateNewSession, api: type[APIData] | APIData = API.TelegramDesktop, password: str | None = None) -> TDesktop: ... @staticmethod async def FromSessionJson(session_path: str, json_path: str | None = None, flag: type[LoginFlag] = UseCurrentSession, api: type[APIData] | APIData | None = None, password: str | None = None) -> TDesktop: ... async def SaveSessionJson(self, session_path: str, api: type[APIData] | APIData | None = None, fetch_user_info: bool = False) -> tuple[str, str]: ... @classmethod def PerformanceMode(cls, enabled: bool = True) -> None: ...
MethodDescription
isLoaded()Whether accounts have been loaded from tdata, or a local key was made for new ones.
LoadTData(...)Loads the accounts of the folder at basePath; raises TDataBadDecryptKey for a missing or wrong passcode and TFileNotFound without a key file.
SaveTData(...)Writes the accounts listed in accounts to a folder; a new passcode, or a folder never loaded, gets a new local key, and a pre-7.3 key file is migrated once. Raises TDataSaveFailed.
ToTelethon(...)The main account as a TelegramClient; see TelegramClient.FromTDesktop.
FromTelethon(...)A new TDesktop holding the client’s account: its own session with UseCurrentSession, a new QR-login session with CreateNewSession.
FromSessionJson(...)A TDesktop from a .session + .json pair; api defaults to the profile stored in the .json.
SaveSessionJson(...)Writes the main account’s session as a .session + .json pair and returns both paths.
PerformanceMode(enabled)Sets kPerformanceMode: fixed keys for a new local key without a passcode, and no configs files on save.

draws, a testing hook, replays recorded os.urandom draws for one save instead of the OS random source, so a save can be compared byte for byte with a reference folder.

Properties

PropertyTypeDescription
apitype[APIData] or APIDataThe API profile of the folder; setting it sets every account’s.
basePathstr or NoneThe absolute folder path.
passcodestrThe local passcode, "" for none.
keyFilestrThe key file data name, "data" by default.
passcodeKeyAuthKey or NoneThe open or passcode key the local key is wrapped under.
localKeyAuthKey or NoneThe local key every file but the key file is encrypted with.
AppVersionint or NoneThe Telegram Desktop version in the key file header, for example 7003001.
accountsCountintHow many accounts are listed.
accountslist[Account]The accounts; removing one from the list or appending one is saved.
mainAccountAccount or NoneThe account at the active index.

Account

One account of a Telegram Desktop folder, owned by a TDesktop.

opentele2/td/account.py
class Account: kWideIdsTag: int = ~0 def __init__( self, owner: TDesktop, basePath: str | None = None, api: type[APIData] | APIData = API.TelegramDesktop, keyFile: str | None = None, index: int = 0, ) -> None: ... def isAuthorized(self) -> bool: ... def isLoaded(self) -> bool: ... def SaveTData(self, basePath: str | None = None, passcode: str | None = None, keyFile: str | None = None, *, draws: Iterable[bytes] | None = None) -> None: ... async def ToTelethon(self, session: str | Session | None = None, flag: type[LoginFlag] = CreateNewSession, api: type[APIData] | APIData = API.TelegramDesktop, password: str | None = None, **kwargs: Unpack[TelethonClientKwargs]) -> tl.TelegramClient: ... @staticmethod async def FromTelethon(telethonClient: tl.TelegramClient, flag: type[LoginFlag] = CreateNewSession, api: type[APIData] | APIData = API.TelegramDesktop, password: str | None = None, owner: TDesktop | None = None) -> Account: ...
NameDescription
isLoaded()Whether the account was loaded from a folder or built from a client.
isAuthorized()The account object’s authorization flag, which loading and conversion leave False.
SaveTData(...)Saves the owner’s folder; see TDesktop.SaveTData.
ToTelethon(...)This account as a TelegramClient; raises TDAccountNotLoaded before loading.
FromTelethon(...)Adds the client’s account to owner (a new TDesktop without one) at the lowest free index; raises MaxAccountLimit for a full folder.
PropertyTypeDescription
ownerTDesktopThe folder the account belongs to.
apitype[APIData] or APIDataThe account’s API profile; setting it sets the owner’s.
basePathstrThe absolute folder path.
keyFilestrThe key file data name; settable.
localKeyAuthKey or NoneThe folder’s local key; settable.
authKeyAuthKey or NoneThe auth key of the main DC.
UserIdintThe Telegram user id.
MainDcIdintThe main DC id.
indexintThe index of the account in the folder.
MtpConfigMtpConfigViewThe account’s stored MTP config, read only.

MtpConfigView

Account.MtpConfig: the MTP config of one loaded account as the core parses it, or the production default when the folder stores none or it does not parse. Every read returns a new copy, so editing a result changes nothing that is saved.

opentele2/td/account.py
class MtpConfigView: @property def environment(self) -> Literal["production", "test"]: ... def isTestMode(self) -> bool: ... @property def dcOptions(self) -> dict[int, list[Endpoint]]: ... @property def cdnPublicKeys(self) -> list[RsaPublicKey]: ... @property def fields(self) -> MtpConfigFields: ... def endpoints(self, dcId: int = 0) -> Endpoints: ...
NameDescription
environment"production" or "test".
isTestMode()Whether the environment is not production.
dcOptionsThe endpoints of every DC, by DC id, in the stored order.
cdnPublicKeysThe CDN RSA keys as {"dc_id", "n", "e"} dicts.
fieldsThe scalar config fields (chat_size_max, edit_time_limit, internal_links_domain and the rest).
endpoints(dcId)The endpoints of dcId by family and protocol: "ipv4" and "ipv6", each with "tcp" and "http", plus "selected_ipv4" and "selected_ipv6". Raises TDataDcIdNotFound for a DC the config does not list; the default 0 is never listed.

An Endpoint is a dict with id, flags, ip, port and secret; the flag bits are the MTP_FLAG_* constants of opentele2._native.

AuthKey

An MTProto auth key, its id and its old-MTP AES key derivation.

opentele2/td/auth.py
class AuthKeyType(IntEnum): Generated = 0 Temporary = 1 ReadFromFile = 2 Local = 3 class AuthKey: kSize = 256 def __init__(self, key: bytes = b"", type: AuthKeyType = AuthKeyType.Generated, dcId: int = 0) -> None: ... @property def dcId(self) -> int: ... @property def type(self) -> AuthKeyType: ... @property def key(self) -> bytes: ... @property def keyId(self) -> int: ... def prepareAES_oldmtp(self, msgKey: bytes, send: bool) -> tuple[bytes, bytes]: ...
NameDescription
dcIdThe DC the key belongs to; 0 for none.
typeHow the key was made.
keyThe 256 key bytes.
keyIdThe low 64 bits of SHA-1 of the key, little endian; a key of another size raises ValueError.
prepareAES_oldmtp(msgKey, send)The MTProto 1.0 AES key and IV for the first 16 bytes of msgKey; send picks the client-to-server half. Raises on a bad key or msg_key length.

TDataDcIdNotFound

opentele2/td/mtp.py
class TDataDcIdNotFound(OpenTeleException): def __init__(self, dcId: int, stack_index: int = 2) -> None: ... dcId: int

Raised by MtpConfigView.endpoints for a DC the config does not list.

Warning:

AuthKey.key, TDesktop.localKey and TDesktop.passcodeKey are raw key material. Never print or log them.

Last updated on