You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用元组式认证调用GitHub API返回空数据的原因排查

问题分析与解决

代码示例

query = "https://api.github.com/repos/rhinstaller/anaconda/tags" 

response = requests.get(query,auth=(self.username,self.token))
response.raise_for_status()  # raises exception when not a 2xx 
    if response.status_code != 204:
        try:
            data = response.json()
            print("data = ",data)
        except:
            print("0")

问题描述

上述代码始终返回空data,但使用response = requests.get(query)无认证调用时,在触发限流前均可正常工作。此前Python中这种元组式认证调用GitHub API是正常的,请问导致该问题的原因是什么?

补充信息

执行print(response.__dict__)得到如下结果:

{'_content': b'{"message":"Bad credentials","documentation_url":"https://docs.github.com/rest"}', '_content_consumed': True, '_next': None, 'status_code': 401, 'headers': {'Server': 'GitHub.com', 'Date': 'Sat, 22 Oct 2022 14:01:13 GMT', 'Content-Type': 'application/json; charset=utf-8', 'Content-Length': '80', 'X-GitHub-Media-Type': 'github.v3; format=json', 'X-RateLimit-Limit': '60', 'X-RateLimit-Remaining': '56', 'X-RateLimit-Reset': '1666449620', 'X-RateLimit-Used': '4', 'X-RateLimit-Resource': 'core', 'Access-Control-Expose-Headers': 'ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset', 'Access-Control-Allow-Origin': '*', 'Strict-Transport-Security': 'max-age=31536000; includeSubdomains; preload', 'X-Frame-Options': 'deny', 'X-Content-Type-Options': 'nosniff', 'X-XSS-Protection': '0', 'Referrer-Policy': 'origin-when-cross-origin, strict-origin-when-cross-origin', 'Content-Security-Policy': "default-src 'none'", 'Vary': 'Accept-Encoding, Accept, X-Requested-With', 'X-GitHub-Request-Id': 'D2F0:13300:1D277E2:1D98791:6353F7A9'}, 'raw': <urllib3.response.HTTPResponse object at 0x7f596e77da90>, 'url': 'https://api.github.com/repos/rhinstaller/anaconda/tags', 'encoding': 'utf-8', 'history': [], 'reason': 'Unauthorized', 'cookies': <RequestsCookieJar[]>, 'elapsed': datetime.timedelta(microseconds=176914), 'request': <PreparedRequest [GET]>, 'connection': <requests.adapters.HTTPAdapter object at 0x7f596e76cbd0>}

原因与解决方案

从补充信息的_content字段能明确看到,GitHub返回了"Bad credentials"(凭据无效)错误,状态码为401(未授权),核心问题是认证方式不匹配:

  1. 元组式auth的本质是Basic Auth:当你用auth=(username, token)时,requests会自动封装成Basic Auth请求,但GitHub的Basic Auth要求「用户名+密码」,而你传入的是「用户名+个人访问令牌(PAT)」,直接导致认证失败。
  2. 代码逻辑的隐藏问题:response.raise_for_status()遇到401这类非2xx状态码时会直接抛出异常,后续解析data的代码根本不会执行,你看到的空data是异常抛出前的无效输出;同时代码里if语句的缩进错误,也会引发语法问题。

正确的认证方式

方式一:使用Bearer Token请求头(推荐)

GitHub API更推荐直接将PAT放在Authorization头里:

headers = {"Authorization": f"token {self.token}"}
response = requests.get(query, headers=headers)

方式二:使用HTTPBasicAuth(兼容写法)

如果要继续用auth参数,需明确使用HTTPBasicAuth,此时用户名可填任意值(比如你的GitHub用户名或空字符串),密码填PAT即可:

from requests.auth import HTTPBasicAuth
response = requests.get(query, auth=HTTPBasicAuth(self.username, self.token))

代码修复建议

同时修正缩进问题,并添加异常捕获避免程序直接崩溃:

query = "https://api.github.com/repos/rhinstaller/anaconda/tags" 
headers = {"Authorization": f"token {self.token}"}
try:
    response = requests.get(query, headers=headers)
    response.raise_for_status()
    if response.status_code != 204:
        data = response.json()
        print("data = ", data)
except requests.exceptions.HTTPError as e:
    print(f"请求错误: {e}")
    print(f"返回内容: {response.text}")
except Exception as e:
    print(f"解析错误: {e}")

内容的提问来源于stack exchange,提问作者PHV

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 23:50:31