Add API version, warn if not present despite version >= 4.3.0

pull/419/head
Lorenz Diener 2025-08-15 13:02:50 +03:00
rodzic d959fa1906
commit 1af3e8d34d
3 zmienionych plików z 51 dodań i 16 usunięć

Wyświetl plik

@ -7,6 +7,9 @@ v2.1.0 (IN PROGRESS)
* Fixed to_json breaking on python 3.14 (Thanks @limburgher for the report)
* Replaced pytest-vcr (deprecated) with pytest-recording (Thanks @CyberTailor)
* Improved timeline documentation (Thanks @adamse)
* Improved docs for stream_healthy (thanks @codl)
* Add offset parameter to trending_tags and trending_links (Thanks @ghost)
* Added support for retrieving API version and a warning for if it is not present despite the mastodon version suggesting it should be.
v2.0.1
------
@ -313,7 +316,7 @@ of things changed, since this release covers two Mastodon versions and
then some !!!!!
* Several small bug fixes (Thanks goldensuneur, bowlercaptain, joyeusenoelle)
* Improved stream error handling (Thanks codl)
* Improved stream error handling (thanks @codl)
* Improvements to streaming:
* Added on_abort() handler to streams
* Added automatic reconnecting
@ -337,7 +340,7 @@ then some !!!!!
v1.2.2
------
* Several small bugfixes (thanks codl)
* Several small bugfixes (thanks @codl)
* Mastodon v2.1.2 compatibility
* Added instance_activity()
* Added instance_peers()
@ -371,17 +374,17 @@ v1.2.0
v1.1.2
------
* 2.0 id compatibility (thanks codl)
* 2.0 id compatibility (thanks @codl)
* Added emoji support
* Media alt-text support (thanks foozmeat)
* Python2 fixes (thanks ragingscholar)
* General code cleanup and small fixes (thanks codl)
* General code cleanup and small fixes (thanks @codl)
* Beginnings of better error handling (thanks Elizafox)
* Various documentation updates
v1.1.1
------
* Emergency fix to allow logging in to work (thanks codl)
* Emergency fix to allow logging in to work (thanks @codl)
v1.1.0
------

Wyświetl plik

@ -237,10 +237,20 @@ class Mastodon(Internals):
self.mastodon_major = 1
self.mastodon_minor = 0
self.mastodon_patch = 0
self.version_check_worked = None
self.version_check_tried = False
# new addition from 4.3.0 on: API versioning.
# For now, we retrieve and cache this along with the other version information,
# though do not use it to do version checks (yet). TBD on whether to go through
# the trouble of doing this for all new endpoints, we'll have to see if other
# API implementations start using this (fingers crossed).
# We also emit a warning if the version is >= 4.3.0 but no API version is found.
self.mastodon_api_version = 0
self.__version_check_worked = None
self.__version_check_tried = False
if not mastodon_version is None:
self.version_check_tried = True
self.__version_check_tried = True
# Cached version check
self.__streaming_base = None
@ -264,9 +274,10 @@ class Mastodon(Internals):
* Mastodon version
* Streaming base URL
"""
self.version_check_worked = None
self.version_check_tried = False
self.__version_check_worked = None
self.__version_check_tried = False
self.__streaming_base = None
self.__oauth_grant_info = None
def auth_request_url(self, client_id: Optional[Union[str, PurePath]] = None, redirect_uris: str = "urn:ietf:wg:oauth:2.0:oob",
scopes: List[str] =_DEFAULT_SCOPES, force_login: bool = False, state: Optional[str] = None,
@ -336,11 +347,18 @@ class Mastodon(Internals):
Returns the access token as a string.
"""
# Is the version > 4.4.0? Throw on trying to log in with password with a more informative message than the API error
# This is left in here even though we check for available grant types above because that way
# we can give a more informative error message to the user ("not supported after version 4.4.0") instead of the
# generic one.
if self.mastodon_major >= 4 and self.mastodon_minor >= 4 or self.mastodon_major > 4:
if password is not None:
raise MastodonIllegalArgumentError('Password flow is no longer supported in Mastodon 4.4.0 and later.')
#
if username is not None and password is not None:
params = self.__generate_params(locals(), ['scopes', 'to_file', 'code', 'refresh_token'])
params['grant_type'] = 'password'
@ -386,8 +404,9 @@ class Mastodon(Internals):
token_file.write(self.persistable_login_credentials())
self.__logged_in_id = None
# Retry version check if needed (might be required in limited federation mode)
if not self.version_check_worked:
# Retry version check if needed (might be required in limited federation mode since
# if the API is locked down, we need to auth before we can get the version)
if not self.__version_check_worked:
self.retrieve_mastodon_version()
return response['access_token']

Wyświetl plik

@ -4,6 +4,7 @@ import re
import dateutil
import datetime
import copy
import warnings
from mastodon.errors import MastodonAPIError, MastodonIllegalArgumentError
from mastodon.compat import IMPL_HAS_BLURHASH, blurhash
@ -32,13 +33,25 @@ class Mastodon(Internals):
"""
try:
version_str = self.__normalize_version_string(self.__instance()["version"])
self.version_check_worked = True
self.__version_check_worked = True
except Exception as e:
# instance() was added in 1.1.0, so our best guess is 1.0.0.
version_str = "1.0.0"
self.version_check_worked = False
self.__version_check_worked = False
self.mastodon_major, self.mastodon_minor, self.mastodon_patch = parse_version_string(version_str)
self.version_check_tried = True
# If the instance has an API version, we store that as well.
# If we have a version >= 4.3.0 but no API version, we throw a warning that this is a Weird Implementation,
# which might help with adoption of the API versioning or at least give us a better picture of how it is going.
found_api_version = False
if "api_versions" in self.__instance():
if "mastodon" in self.__instance()["api_versions"]:
self.mastodon_api_version = int(self.__instance()["api_versions"]["mastodon"])
found_api_version = True
if not found_api_version and self.mastodon_major >= 4 and self.mastodon_minor >= 3:
warnings.warn("Mastodon version is detected as >= 4.3.0, but no API version found. Please report this.")
self.__version_check_tried = True
return version_str
def verify_minimum_version(self, version_str, cached=False):
@ -49,7 +62,7 @@ class Mastodon(Internals):
Returns True if version requirement is satisfied, False if not.
"""
if not cached or not self.version_check_tried:
if not cached or not self.__version_check_tried:
self.retrieve_mastodon_version()
major, minor, patch = parse_version_string(version_str)
if major > self.mastodon_major: