Agregar datos a urllib2.Request

amigos.

Estoy escribiendo un pequeño script que tomará el inicio de session de Github de una persona y lo usará para consultar la API de Github para get un token de autorización. Aquí está el código:

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 declanetworking 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 

Si add_data llamada add_data , la request funciona y se devuelve un token de authentication. El problema es que necesito include los datos pasados ​​a add_data para recibir un token de authentication capaz de interactuar con las instalaciones de Github.

Mis dos preguntas

  1. ¿Cómo puedo agregar esta información a mi request para que Github la reconozca y la acepte?
  2. Espero encontrarme pronto en una situación similar que requerirá enviar un set más grande de datos; ¿Cómo pasaría un set de valores más complejo (como un dictionary de gran tamaño con valores nesteds, etc.)?

Lo que he intentado

He encontrado varias cosas en Internet que dicen que debería usar urllib.urlencode para codificar los valores antes de enviarlos, pero no he podido hacerlo porque desde scopes espera una list y urlencode espera una list de tuplas.

Estoy 100% seguro de que estoy haciendo algo estúpido aquí, así que si pudieras decirme qué es, te lo agradecería 🙂

Gracias, y díganme si proporcionar más información facilitará las respuestas.

Básicamente, estás haciendo todo bien. Probé tu código y funciona bien, con una pequeña modificación.

Esto es lo que sucede:

Cuando no incluye los datos, la request que se realiza es en realidad una request GET, que obtiene la list de autorizaciones. Esto no es lo que quiere, ya que no crea una nueva autorización.

Cuando incluye los datos, la request que se realiza es una request POST, que es lo que desea. Sin embargo, el código de estado devuelto no es 200, sino que es 201. Por lo tanto, simplemente modifique el código para verificar 201 y obtenga el token del cuerpo JSON.

Usar requests es un poco mejor:

 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']