Releases: LonamiWebs/Telethon
Changelog moved
Please refer to Read The Docs - Changelog (Version History) for the changelog from now on! You should read it every time you update the library, a considerable amount of effort is put into it and should save you from some "my code worked but not anymore".
Sessions as sqlite databases
In the beginning, session files used to be pickle. This proved to be bad as soon as one wanted to add more fields. For this reason, they were migrated to use JSON instead. But this proved to be bad as soon as one wanted to save things like entities (usernames, their ID and hash), so now it properly uses sqlite3, which has been well tested, to save the session files! Calling .get_input_entity using a username no longer will need to fetch it first, so it's really 0 calls again. Calling .get_entity will always fetch the most up to date version.
Furthermore, nearly everything has been documented, thus preparing the library for Read the Docs (although there are a few things missing I'd like to polish first), and the logging are now better placed.
Breaking changes
.get_dialogs()now returns a single list instead a tuple consisting of a custom class that should make everything easier to work with..get_message_history()also returns a single list instead a tuple, with theMessageinstances modified to make them more convenient.
Both lists have a .total attribute so you can still know how many dialogs/messages are in total.
New stuff
- The mentioned use of 
sqlite3for the session file. .get_entity()now supports lists too, and it will make as little API calls as possible if you feed itInputPeertypes. Usernames will always be resolved, since they may have changed..set_proxy()method, to avoid having to create a newTelegramClient.- More 
datetypes supported to represent a date parameter. 
Bug fixes
- Empty strings weren't working when they were a flag parameter (e.g., setting no last name).
 - Fix invalid assertion regarding flag parameters as well.
 - Avoid joining the background thread on disconnect, as it would be 
Nonedue to a race condition. - Correctly handle 
Nonedates when downloading media. .download_profile_photowas failing for some channels..download_mediawasn't handlingPhoto.
Internal changes
datewas being serialized as local date, but that was wrong.datewas being represented as afloatinstead of anint..tlparser wasn't stripping inline comments.- Removed some redundant checks on 
update_state.py. - Use a synchronized queue instead a hand crafted version.
 - Use signed integers consistently (e.g. 
salt). - Always read the corresponding 
TLObjectfrom API responses, except for some special cases still. - A few more 
exceptlow level to correctly wrap errors. - More accurate exception types.
 invokeWithLayer(initConnection(X))now wraps every first request after.connect().
As always, report if you have issues with some of the changes!
IPv6 support
Scheme layer used: 73 | 
It's here, it has come! The library now supports IPv6! Just pass use_ipv6=True when creating a TelegramClient. Note that I could not test this feature because my machine doesn't have IPv6 setup. If you know IPv6 works in your machine but the library doesn't, please refer to #425.
Additions
- IPv6 support.
 - New method to extract the text surrounded by 
MessageEntity's, in theextensions.markdownmodule. 
Enhancements
- Markdown parsing is Done Right.
 - Reconnection on failed invoke. Should avoid "number of retries reached 0" (#270).
 - Some missing autocast to 
Input*types. - The library uses the 
NullHandlerforloggingas it should have always done. TcpClient.is_connected()is now more reliable.
Bug fixes
- Getting an entity using their phone wasn't actually working.
 - Full entities aren't saved unless they have an 
access_hash, to avoid someNoneerrors. .get_message_historywas failing when retrieving items that had messages forwarded from a channel.
General enhancements
Scheme layer used: 72 | 
This update brings a few general enhancements that are enough to deserve a new release, with a new feature: beta markdown-like parsing for .send_message()!
Additions
.send_message()supportsparse_mode='md'for Markdown! It works in a similar fashion to the official clients (defaults to double underscore/asterisk, like**this**). Please report any issues with emojies or enhancements for the parser!- New 
.idle()method so your main thread can do useful job (listen for updates). - Add missing 
.to_dict(),__str__and.stringify()forTLMessageandMessageContainer. 
Bug fixes
- The list of known peers could end "corrupted" and have users with 
access_hash=None, resulting instructerror for it not being an integer. You shouldn't encounter this issue anymore. - The warning for "added update handler but no workers set" wasn't actually working.
 .get_input_peerwas ignoring a case forInputPeerSelf.- There used to be an exception when logging exceptions (whoops) on update handlers.
 - "Downloading contacts" would produce strange output if they had semicolons (
;) in their name. - Fix some cyclic imports and installing dependencies from the 
gitrepository. - Code generation was using f-strings, which are only supported on Python ≥3.6.
 
Other changes
- The 
auth_keygeneration has been moved from.connect()to.invoke(). There were some issues were.connect()failed and theauth_keywasNoneso this will ensure to have a validauth_keywhen needed, even ifBrokenAuthKeyErroris raised. - Support for higher limits on 
.get_history()and.get_dialogs(). - Much faster integer factorization when generating the required 
auth_key. Thanks @delivrance for making me notice this, and for the pull request. 
Bug fixes with updates
Hopefully a very ungrateful bug has been removed. When you used to invoke some request through update handlers, it could potentially enter an infinite loop. This has been mitigated and it's now safe to invoke things again! A lot of updates were being dropped (all those gzipped), and this has been fixed too.
More bug fixes include a correct parsing of certain TLObjects thanks to @stek29, and some wrong calls that would cause the library to crash thanks to @andr-04, and the ReadThread not re-starting if you were already authorized.
Internally, the .to_bytes() function has been replaced with __bytes__ so now you can do bytes(tlobject).
Bug fixes and new small features
This release primarly focuses on a few bug fixes and enhancements. Although more stuff may have broken along the way.
Bug fixes:
.get_input_entitywas failing for IDs and other cases, also making more requests than it should.- Use 
basenameinsteadabspathwhen sending a file. You can now also override the attributes. EntityDatabase.__delitem__wasn't working..send_message()was failing with channels..get_dialogs(limit=None)should now return all the dialogs correctly.- Temporary fix for abusive duplicated updates.
 
Enhancements:
- You will be warned if you call 
.add_update_handlerwith noupdate_workers. - New customizable threshold value on the session to determine when to automatically sleep on flood waits. See 
client.session.flood_sleep_threshold. - New 
.get_drafts()method with a customDraftclass by @JosXa. - Join all threads when calling 
.disconnect(), to assert no dangling thread is left alive. - Larger chunk when downloading files should result in faster downloads.
 - You can use a callable key for the 
EntityDatabase, so it can be any filter you need. 
Internal changes:
- MsgsAck is now sent in a container rather than its own request.
 .get_input_photois now used in the generated code..process_entitieswas being called from more places than only__call__.MtProtoSendernow relies more on the generated code to read responses.
Custom Entity Database
The main feature of this release is that Telethon now has a custom database for all the entities you encounter, instead depending on @lru_cache on the .get_entity() method.
The EntityDatabase will, by default, cache all the users, chats and channels you find in memory for as long as the program is running. The session will, by default, save all key-value pairs of the entity identifiers and their hashes (since Telegram may send an ID that it thinks you already know about, we need to save this information).
You can prevent the EntityDatabase from saving users by setting client.session.entities.enabled = False, and prevent the Session from saving input entities at all by setting client.session.save_entities = False. You can also clear the cache for a certain user through client.session.entities.clear_cache(entity=None), which will clear all if no entity is given.
More things:
.sign_inaccepts phones as integers..get_dialogs()doesn't fail on Windows anymore, and returns the right amount of dialogs.- New method to 
.delete_messages(). - New 
ChannelPrivateErrorclass - Changing the IP to which you connect to is as simple as 
client.session.server_address = 'ip', since now the server address is always queried from the session. GeneralProxyErrorshould be passed to the main thread again, so that you can handle it.
Updates Overhaul Update
After hundreds of lines changed on a major refactor, it's finally here. It's the Updates Overhaul Update; let's get right into it!
New stuff and enhancements
- You can invoke requests from update handlers. And any other thread. A new temporary will be made, so that you can be sending even several requests at the same time!
 - Several worker threads for your updates! By default, 
Nonewill spawn. I recommend you to work withupdate_workers=4to get started, these will be polling constantly for updates. - You can also change the number of workers at any given time.
 - The library can now run in a single thread again, if you don't need to spawn any at all. Simply set 
spawn_read_thread=Falsewhen creating theTelegramClient! - You can specify 
limit=Noneon.get_dialogs()to get all of them[1]. - Updates are expanded, so you don't need to check if the update has 
.updatesor an inner.updateanymore. - All 
InputPeerentities are saved in the session file, but you can disable this by settingsave_entities=False. - New 
.get_input_entitymethod, which makes use of the above feature. You should use this when a request needs aInputPeer, rather than the whole entity (although both work). 
Less important enhancements
- Assert that either all or None dependent-flag parameters are set before sending the request.
 - Phone numbers can have dashes, spaces, or parenthesis. They'll be removed before making the request.
 - You can override the phone and its hash on 
.sign_in(), if you're creating a newTelegramClienton two different places. 
Compatibility breaks
.create_new_connection()is gone for good. No need to deal with this manually since new connections are now handled on demand by the library itself.
Bugs fixed
.log_out()was consuming all retries. It should work just fine now.- The session would fail to load if the 
auth_keyhad been removed manually. Updates.check_errorwas popping wrong side, although it's been completely removed.ServerError's will be ignored, and the request will immediately be retried.- Cross-thread safety when saving the session file.
 - Some things changed on a matter of when to reconnect, so please report any bugs!
 
Internal changes
TelegramClientis now only an abstraction over theTelegramBareClient, which can only do basic things, such as invoking requests, working with files, etc. If you don't need any of the abstractions theTelegramClient, you can now use theTelegramBareClientin a much more comfortable way.MtProtoSenderis not thread-safe, but it doesn't need to be since a new connection will be spawned when needed.- New connections used to be cached and then reused. Now only their sessions are saved, as temporary connections are spawned only when needed.
 - Added more RPC errors to the list.
 
[1]: Broken due to a condition which should had been the opposite (sigh), fixed 4 commits ahead on 62ea77c.
That's pretty much it, although there's more work to be done to make the overall experience of working with updates even better. Stay tuned!
Serialization bug fixes
Two bug fixes, one of them quite important, related to the serialization. Every object or request that had to serialize a True/False type was always being serialized as false!
Another bug that didn't allow you to leave as None flag parameters that needed a list has been fixed.
Other internal changes include a somewhat more readable .to_bytes() function and pre-computing the flag instead using bit shifting. The TLObject.constructor_id has been renamed to TLObject.CONSTRUCTOR_ID, and .subclass_of_id is also uppercase now.
Farewell, BinaryWriter
Version v0.14 had started working on the new .to_bytes() method to dump the BinaryWriter and its usage on the .on_send() when serializing TLObjects, and this release finally removes it. The speed up when serializing things to bytes should now be over twice as fast wherever it's needed.
Other internal changes include using proper classes (including the generated code) for generating authorization keys and to write out TLMessage's.
For bug fixes, this version is again compatible with Python 3.x versions below 3.5 (there was a method call that was Python 3.5 and above).