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 theMessage
instances 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
sqlite3
for the session file. .get_entity()
now supports lists too, and it will make as little API calls as possible if you feed itInputPeer
types. Usernames will always be resolved, since they may have changed..set_proxy()
method, to avoid having to create a newTelegramClient
.- More
date
types 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
None
due to a race condition. - Correctly handle
None
dates when downloading media. .download_profile_photo
was failing for some channels..download_media
wasn't handlingPhoto
.
Internal changes
date
was being serialized as local date, but that was wrong.date
was being represented as afloat
instead of anint
..tl
parser 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
TLObject
from API responses, except for some special cases still. - A few more
except
low 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.markdown
module.
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
NullHandler
forlogging
as 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 someNone
errors. .get_message_history
was 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()
forTLMessage
andMessageContainer
.
Bug fixes
- The list of known peers could end "corrupted" and have users with
access_hash=None
, resulting instruct
error 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_peer
was 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
git
repository. - Code generation was using f-strings, which are only supported on Python ≥3.6.
Other changes
- The
auth_key
generation has been moved from.connect()
to.invoke()
. There were some issues were.connect()
failed and theauth_key
wasNone
so this will ensure to have a validauth_key
when needed, even ifBrokenAuthKeyError
is 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_entity
was failing for IDs and other cases, also making more requests than it should.- Use
basename
insteadabspath
when 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_handler
with 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 customDraft
class 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_photo
is now used in the generated code..process_entities
was being called from more places than only__call__
.MtProtoSender
now 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_in
accepts phones as integers..get_dialogs()
doesn't fail on Windows anymore, and returns the right amount of dialogs.- New method to
.delete_messages()
. - New
ChannelPrivateError
class - 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. GeneralProxyError
should 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,
None
will spawn. I recommend you to work withupdate_workers=4
to 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=False
when creating theTelegramClient
! - You can specify
limit=None
on.get_dialogs()
to get all of them[1]. - Updates are expanded, so you don't need to check if the update has
.updates
or an inner.update
anymore. - All
InputPeer
entities are saved in the session file, but you can disable this by settingsave_entities=False
. - New
.get_input_entity
method, 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 newTelegramClient
on 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_key
had been removed manually. Updates.check_error
was 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
TelegramClient
is 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 theTelegramBareClient
in a much more comfortable way.MtProtoSender
is 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).