Fix OAuth User-Agent header and improve error handling

- Set User-Agent on OAuth1Session during token fetch and access token
  exchange so Wikimedia doesn't reject the requests with 403
- Extract handle_post() from article_page() for clarity
- Catch api.MediawikiError in get_best_hit() to skip bad API responses
  rather than crashing the page
- Catch mediawiki_api.APIError on save and return a 502 with the error
  text instead of a 500 traceback

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Edward Betts 2026-05-09 18:10:13 +01:00
parent 1be844e57a
commit da83f0791d

View file

@ -186,6 +186,7 @@ def start_oauth() -> Response:
request_token_url = wiki_index_php + "?title=Special%3aOAuth%2finitiate"
oauth = OAuth1Session(client_key, client_secret=client_secret, callback_uri="oob")
oauth.headers.update({"User-Agent": api.ua})
fetch_response = oauth.fetch_request_token(request_token_url)
flask.session["owner_key"] = fetch_response.get("oauth_token")
@ -223,7 +224,7 @@ def oauth_callback() -> werkzeug.wrappers.response.Response:
resource_owner_secret=flask.session["owner_secret"],
verifier=verifier,
)
oauth.headers.update({"User-Agent": api.ua})
oauth_tokens = oauth.fetch_access_token(access_token_url)
flask.session["owner_key"] = oauth_tokens.get("oauth_token")
flask.session["owner_secret"] = oauth_tokens.get("oauth_token_secret")
@ -298,27 +299,37 @@ def get_best_hit(title: str, hits: list[Hit]) -> tuple[Hit, dict[str, typing.Any
except NoMatch:
print("no match")
continue
except api.MediawikiError as e:
print(f"MediawikiError for {hit['title']!r}: {e}")
continue
return (hit, found)
raise NoGoodHit
@app.route("/link/<path:url_title>", methods=["GET", "POST"])
def article_page(url_title: str) -> str | Response:
"""Article page."""
def handle_post(url_title: str) -> Response:
"""Handle POST request."""
from_title = url_title.replace("_", " ").strip()
if flask.request.method == "POST":
hit_title = flask.request.form["hit"]
try:
do_save(from_title, hit_title)
except mediawiki_oauth.LoginNeeded:
return flask.redirect(flask.url_for("start_oauth"))
except mediawiki_api.APIError as e:
return flask.make_response(f"Save failed: {e}", 502)
return flask.redirect(
flask.url_for("article_page", url_title=url_title, after=hit_title)
)
@app.route("/link/<path:url_title>", methods=["GET", "POST"])
def article_page(url_title: str) -> str | Response:
"""Article page."""
if flask.request.method == "POST":
return handle_post(url_title)
from_title = url_title.replace("_", " ").strip()
article_title = flask.request.args.get("title")
total = search_count(from_title)