From fa1c6c97d22f07a54e57a50cf3e9fcd9d288aa0a Mon Sep 17 00:00:00 2001 From: Junpei Kawamoto Date: Fri, 30 Dec 2022 22:31:38 -0600 Subject: [PATCH] Supports User-Agent header in create_app method Following #240, it's helpful if `create_app` also supports the User-Agent header. This commit fixes https://github.com/halcy/Mastodon.py/issues/213#issuecomment-1276999193. --- mastodon/authentication.py | 15 +++++++++++---- tests/test_create_app.py | 10 ++++++++-- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/mastodon/authentication.py b/mastodon/authentication.py index 9f42587..03eaf12 100644 --- a/mastodon/authentication.py +++ b/mastodon/authentication.py @@ -14,13 +14,15 @@ from .utility import parse_version_string, api_version from .internals import Mastodon as Internals +_DEFAULT_USER_AGENT = "mastodonpy" + class Mastodon(Internals): ### # Registering apps ### @staticmethod def create_app(client_name, scopes=_DEFAULT_SCOPES, redirect_uris=None, website=None, to_file=None, - api_base_url=None, request_timeout=_DEFAULT_TIMEOUT, session=None): + api_base_url=None, request_timeout=_DEFAULT_TIMEOUT, session=None, user_agent=_DEFAULT_USER_AGENT): """ Create a new app with given `client_name` and `scopes` (The basic scopes are "read", "write", "follow" and "push" - more granular scopes are available, please refer to Mastodon documentation for which) on the instance given @@ -36,6 +38,8 @@ class Mastodon(Internals): Specify `session` with a requests.Session for it to be used instead of the default. This can be used to, amongst other things, adjust proxy or SSL certificate settings. + Specify `user_agent` if you want to use a specific name as `User-Agent` header, otherwise "mastodonpy" will be used. + Presently, app registration is open by default, but this is not guaranteed to be the case for all Mastodon instances in the future. @@ -50,6 +54,9 @@ class Mastodon(Internals): 'client_name': client_name, 'scopes': " ".join(scopes) } + headers = { + 'User-Agent': user_agent + } try: if redirect_uris is not None: @@ -61,10 +68,10 @@ class Mastodon(Internals): if website is not None: request_data['website'] = website if session: - ret = session.post(f"{api_base_url}/api/v1/apps", data=request_data, timeout=request_timeout) + ret = session.post(f"{api_base_url}/api/v1/apps", data=request_data, headers=headers, timeout=request_timeout) response = ret.json() else: - response = requests.post(f"{api_base_url}/api/v1/apps", data=request_data, timeout=request_timeout) + response = requests.post(f"{api_base_url}/api/v1/apps", data=request_data, headers=headers, timeout=request_timeout) response = response.json() except Exception as e: raise MastodonNetworkError(f"Could not complete request: {e}") @@ -83,7 +90,7 @@ class Mastodon(Internals): ### def __init__(self, client_id=None, client_secret=None, access_token=None, api_base_url=None, debug_requests=False, ratelimit_method="wait", ratelimit_pacefactor=1.1, request_timeout=_DEFAULT_TIMEOUT, mastodon_version=None, - version_check_mode="created", session=None, feature_set="mainline", user_agent="mastodonpy", lang=None): + version_check_mode="created", session=None, feature_set="mainline", user_agent=_DEFAULT_USER_AGENT, lang=None): """ Create a new API wrapper instance based on the given `client_secret` and `client_id` on the instance given by `api_base_url`. If you give a `client_id` and it is not a file, you must diff --git a/tests/test_create_app.py b/tests/test_create_app.py index 97556c6..c7d2205 100644 --- a/tests/test_create_app.py +++ b/tests/test_create_app.py @@ -8,7 +8,7 @@ try: except ImportError: from unittest.mock import Mock -def test_create_app(mocker, to_file=None, redirect_uris=None, website=None): +def test_create_app(mocker, to_file=None, redirect_uris=None, website=None, user_agent="mastodonpy"): # there is no easy way to delete an anonymously created app so # instead we mock Requests resp = Mock() @@ -22,7 +22,8 @@ def test_create_app(mocker, to_file=None, redirect_uris=None, website=None): api_base_url="example.com", to_file=to_file, redirect_uris=redirect_uris, - website=website + website=website, + user_agent=user_agent ) assert app == ('foo', 'bar') @@ -43,6 +44,11 @@ def test_create_app_website(mocker): kwargs = requests.post.call_args[1] assert kwargs['data']['website'] == 'http://example.net' +def test_create_app_user_agent(mocker): + test_create_app(mocker, user_agent="pytest") + kwargs = requests.post.call_args[1] + assert kwargs['headers']['User-Agent'] == 'pytest' + @pytest.mark.vcr() def test_app_verify_credentials(api): app = api.app_verify_credentials()