1

朋友们。

我正在编写一个简短的脚本,它将获取一个人的 Github 登录名并使用它来查询 Github API 以获取授权令牌。这是代码:

def getGithubAuth():
    "Get a Github auth token and return it"
    gist_data = json.dumps({"scopes":["gist"]})
    req = urllib2.Request(auth_url)
    base64str = base64.encodestring("%s:%s" % \
        (github_user, github_pass)).replace('\n','') # user/pass vars are declared elsewhere
    req.add_header("Authorization", "Basic %s" % base64str);
    req.add_data(gist_data) # <- including this makes problems

    try:
        response = urllib2.urlopen(req)
    except urllib2.URLError, e:
        print "Something broke connecting to Github: %s" % e
        return None

    if response.getcode() == 200:
        jresp = json.loads('\n'.join(response.readlines()))[0]
        return jresp['token']
    return None 

如果我删除add_data呼叫,则请求有效并返回身份验证令牌。问题是,我需要包含传递给的数据add_data,以便接收能够与 Github 的 gist 工具交互的身份验证令牌。

我的两个问题

  1. 如何将此数据添加到我的请求中,以便 Github 识别并接受它?
  2. 我希望很快会发现自己处于需要发送更多数据集的类似情况;我将如何传递一组更复杂的值(例如带有嵌套值的大型字典等)?

我试过的

我发现一些互联网上的东西说我应该在发送它们之前对值进行编码,但是由于需要一个列表并需要一个元组列表urllib.urlencode,所以我无法完成这项工作。scopesurlencode

我 100% 确定我在这里做了一些愚蠢的事情,所以如果你能告诉我它是什么,我将不胜感激:)

谢谢 - 请告诉我提供更多信息是否会使回答更容易。

4

2 回答 2

1

基本上,你做的一切都是正确的。我试过你的代码,它工作正常,稍作修改。

这是发生的事情:

当您不包含数据时,发出的请求实际上是一个 GET 请求,它获取授权列表。这不是您想要的,因为它不会创建新的授权。

当您确实包含数据时,发出的请求是一个 POST 请求,这就是您想要的。但是,返回的状态码不是 200,而是 201。因此,只需修改代码以检查 201 并从 JSON 正文中获取令牌。

于 2012-12-20T20:28:43.253 回答
0

使用requests更好一点:

app_name = 'your_app'

import requests, json

def create_github_oauth_token(user, password):

    # Check there isn't already an auth code for your app:
    r = requests.get('https://api.github.com/authorizations',
        auth=(user, password))
    for auth in r.json():
        if auth['note'] == app_name \
            and 'repo' in auth['scopes']:
            print "Retrieving existing token"
            print json.dumps(auth, indent=4)
            return auth['token']

    print "Creating new token"
    # Otherwise create a new token
    r = requests.post('https://api.github.com/authorizations',
        data=json.dumps({
            'scopes':['repo'],
            'note':app_name
            }),
        headers={'content-type':'application/json'},
        auth=(user, password)
    )
    return r.json()['token']
于 2013-01-06T14:51:42.533 回答