I am using libpagure to read data from pagure tickets using an authentication token and my script doesn't work any more because of the anubis deployment.
Minimal reproducer: I have a pagure token with the following permissions:
$ cat /tmp/pagure_minimal.py #!/usr/bin/python3 from libpagure import Pagure import sys print("Access issue without any token") pg = Pagure(pagure_repository="freeipa") data = pg.issue_info("7979") print(data) print("Access issue with token") pg2 = Pagure(pagure_repository="freeipa", pagure_token=sys.argv[1]) data2 = pg2.issue_info("7979") print(data2)
My token is set in $PAGURE_TOKEN and when I use libpagure to access the issue: - the API works if I don't provide any token - the API fails if I provide my token
Example:
$ python /tmp/pagure_minimal.py $PAGURE_TOKEN Access issue without any token {'assignee': None, 'blocks': [], 'close_status': None, 'closed_at': None, 'closed_by': None, 'comments': [], 'content': '### Request for enhancement\r\n\r\nlibgssapi / python-gssapi use syslog to log events to the system journal. syslog uses the process name argv[0] from ``int main(int argc, char **argv)``. This means that the process name in the syslog is just ``python3`` and not the script name.\r\n\r\nIPA should set a syslog ident to make it easier to identify issues with gssapi, e.g. ``syslog.openlog(os.path.basename(sys.argv[0]))``.', 'custom_fields': [], 'date_created': '1560760555', 'depends': [], 'full_url': 'https://pagure.io/freeipa/issue/7979', 'id': 7979, 'last_updated': '1560760555', 'milestone': None, 'priority': None, 'private': False, 'related_prs': [], 'status': 'Open', 'tags': [], 'title': 'Set syslog ident', 'user': {'full_url': 'https://pagure.io/user/cheimes', 'fullname': 'Christian Heimes', 'name': 'cheimes', 'url_path': 'user/cheimes'}} Access issue with token Traceback (most recent call last): File "/usr/lib/python3.13/site-packages/requests/models.py", line 976, in json return complexjson.loads(self.text, **kwargs) ~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib64/python3.13/site-packages/simplejson/__init__.py", line 514, in loads return _default_decoder.decode(s) ~~~~~~~~~~~~~~~~~~~~~~~^^^ File "/usr/lib64/python3.13/site-packages/simplejson/decoder.py", line 386, in decode obj, end = self.raw_decode(s) ~~~~~~~~~~~~~~~^^^ File "/usr/lib64/python3.13/site-packages/simplejson/decoder.py", line 416, in raw_decode return self.scan_once(s, idx=_w(s, idx).end()) ~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^ simplejson.errors.JSONDecodeError: Expecting value: line 1 column 1 (char 0) During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/usr/lib/python3.13/site-packages/libpagure/libpagure.py", line 99, in _call_api output = req.json() File "/usr/lib/python3.13/site-packages/requests/models.py", line 980, in json raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) requests.exceptions.JSONDecodeError: Expecting value: line 1 column 1 (char 0) During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/tmp/pagure_minimal.py", line 13, in <module> data2 = pg2.issue_info("7979") File "/usr/lib/python3.13/site-packages/libpagure/libpagure.py", line 441, in issue_info return_value = self._call_api(request_url) File "/usr/lib/python3.13/site-packages/libpagure/libpagure.py", line 103, in _call_api raise Exception("Error while decoding JSON: {0}".format(err)) Exception: Error while decoding JSON: Expecting value: line 1 column 1 (char 0)
The debugger shows that the request receives the following result:
'<!doctype html><html lang="en"><head><title>Making sure you're not a bot!</title><link rel="stylesheet" href="/.within.website/x/xess/xess.min.css?cachebuster=v1.23.0"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="robots" content="noindex,nofollow"><style>\n body,\n html {\n height: 100%;\n display: flex;\n justify-content: center;\n align-items: center;\n margin-left: auto;\n margin-right: auto;\n }\n\n .centered-div {\n text-align: center;\n }\n\n #status {\n font-variant-numeric: tabular-nums;\n }\n\n #progress {\n display: none;\n width: 90%;\n width: min(20rem, 90%);\n height: 2rem;\n border-radius: 1rem;\n overflow: hidden;\n margin: 1rem 0 2rem;\n\t\t\t\t\toutline-offset: 2px;\n\t\t\t\t\toutline: #b16286 solid 4px;\n\t\t\t\t}\n\n .bar-inner {\n background-color: #b16286;\n height: 100%;\n width: 0;\n transition: width 0.25s ease-in;\n }\n \t</style><script id="anubis_version" type="application/json">"v1.23.0"\n</script><script id="anubis_challenge" type="application/json">{"rules":{"algorithm":"metarefresh","difficulty":1,"report_as":1},"challenge":{"id":"019a4a94-144d-713b-b4e7-f9f65c51b768","method":"metarefresh","randomData":"73e16841762699df84fe500476a5d4d655b3d750e8916ba36611222f42a48b9a3c5a4d81967ba0b5bf9256f7e57e6c2a71a7b709aaa3116e59b57753aefef282","issuedAt":"2025-11-03T16:36:49.869085641Z","metadata":{"User-Agent":"python-urllib3/2.3.0","X-Real-Ip":"2.7.242.138"},"spent":false}}\n</script><script id="anubis_base_prefix" type="application/json">""\n</script><script id="anubis_public_url" type="application/json">""\n</script></head><body id="top"><main><h1 id="title" class="centered-div">Making sure you're not a bot!</h1><div class="centered-div"><img id="image" style="width:100%;max-width:256px;" src="/.within.website/x/cmd/anubis/static/img/pensive.webp?cacheBuster=v1.23.0"> <img style="display:none;" style="width:100%;max-width:256px;" src="/.within.website/x/cmd/anubis/static/img/happy.webp?cacheBuster=v1.23.0"><p id="status">Loading...</p><p>Please wait a moment while we ensure the security of your connection.</p></div><footer><div class="centered-div"><p>Protected by <a href="https://github.com/TecharoHQ/anubis">Anubis</a> From <a href="https://techaro.lol">Techaro</a>. Made with ❤️ in 🇨🇦.</p><p>Mascot design by <a href="https://bsky.app/profile/celphase.bsky.social">CELPHASE</a>.</p><p>This website is running Anubis version <code>v1.23.0</code>.</p></div></footer></main></body></html>'
Metadata Update from @james: - Issue priority set to: Waiting on Assignee (was: Needs Review) - Issue tagged with: low-gain, medium-trouble
You might want to ping upstream, if there is one.
Might be easy to fix, but might not (nobody really knew about this library, and what uses it) ... Also pagure will be going away.
Changing the useragent might be enough though.
A follow-up. Changing User-Agent did not help but adding some other header did help. Perhaps we should open a PR to libpagure to fix it.
libpagure had its last commit 4 years ago and has several PRs multiple years old.
Same issue happens with Forgejo code that runs migration from pagure.io. It simply does not work, I had to add headers there too: https://codeberg.org/forgejo/forgejo/pulls/9973
When did this start happening?
I am wondering if its a bug in the recently anubis... I upgraded it on sunday. Was it ok before then?
We first noticed Monday morning around 8am EST.
Yeah, so it's likely the new version then.
So, what shall we do here? Should we try and get anubis to handle this case? Or since we are patching the tools, just do that and leave anubis alone?
I think we can leave it alone. The change in the tools is due -- for example, this uncovered a real bug in handling authenticated requests in libpagure.
ok, closing this then. Please let us know if there's anything more we can do from our end if needed.
Metadata Update from @kevin: - Issue close_status updated to: Fixed - Issue status updated to: Closed (was: Open)
Log in to comment on this ticket.