Assinando solicitações no Python para OAuth

Atualmente, estou fazendo interface com a API do Twitter usando o protocolo OAuth e escrevendo o código em Python. Como a maioria dos usuários por aí, acho que a parte mais difícil das especificações é lidar com assinaturas.

Depois de passear pela web em busca de uma solução, decidi seguir meu código personalizado, para entender melhor o que está acontecendo.

Para o bem de outros usuários, estou postando aqui uma implementação muito simples e curta das especificações de assinatura SHA1 no Python:

import hmac

from hashlib import sha1
from urllib import quote, urlencode
from base64 import b64encode
from urlparse import urlparse

def sign_request_sha1(url,method,data,secret=""):
  pu = urlparse(urlparse(url).geturl())

  normUrl = "%s://%s%s%s" % (
      pu.scheme,
      pu.hostname,
      "" if not pu.port or {"http":80,"https":443}[pu.scheme] == pu.port else ":%d" % pu.port,
      pu.path,
                            )

  names = data.keys()
  names.sort()

  sig = "%s&%s&%s" % (
          method.upper(),
          quote(normUrl,''),
          quote("&".join(["%s=%s" % (k,quote(data[k].encode('utf-8'),'')) for k in names]),''),
                     )

  key = "%s&%s" % (quote(CONSUMER_SECRET.encode('utf-8'),''),secret)

  return b64encode(hmac.new(key,sig,sha1).digest())

Os parâmetros de entrada para a função são:

url: o URL que você chamará para a solicitação específica do OAuth.método: deve ser "GET" ou "POST", dependendo de como você vai emitir sua solicitação.data: um dicionário contendo todos os parâmetros das solicitações, incluindo qualquer argumento personalizado, mas excluindo o "oauth_signature" (por razões óbvias).segredo: um token secreto que você recebeu na fase inicial do protocolo.

Eu testei com o Twitter e parece funcionar, mas gostaria de receber alguns comentários sobre erros, melhorias e assim por diante.

Por fim, aqui você encontra um trecho de código que chama o código para a fase inicial de "token de solicitação":

from random import getrandbits
from base64 import b64encode
from time import time

def twitter_request_token(req,callback,errback):
  req_url="http://twitter.com:80/oauth/request_token"

  data = { \
    "oauth_consumer_key" : CONSUMER_KEY,
    "oauth_nonce" : b64encode("%0x" % getrandbits(256))[:32],
    "oauth_timestamp" : str(int(time())),
    "oauth_signature_method" : "HMAC-SHA1",
    "oauth_version" : "1.0",
    "oauth_callback" : "http://localhost:8080/",
         }

  data["oauth_signature"] = sign_request_sha1(req_url,"GET",data)

Obrigado.

questionAnswers(1)

yourAnswerToTheQuestion