2017-08-17 1 views
0

Ich möchte Python-Client für Last.fm-API erstellen. Ich möchte eine Art Bibliothek bauen.Last.fm API ungültige Methodensignatur, aber gültig beim Abrufen des Sitzungsschlüssels

Ich schaffte es, eine Sitzung zu bekommen und einzustellen, indem ich einen Sitzungsschlüssel erhielt. Danach versuche ich eine POST-Methode aufzurufen, die API_key, api_signature und Session-Key benötigt. Also verwende ich den APi-Schlüssel, den ich habe, dieselbe api_signature, die ich verwendet habe, um den Sitzungsschlüssel und den Sitzungsschlüssel selbst zu erhalten.

Aber ich bekomme eine "ungültige Methode Signatur", obwohl ich die gleiche api_signature für die POST-Aufrufe verwenden.

import json 
import webbrowser 
from hashlib import md5 
import urllib3 

class PyLast(): 

def __init__(self, API_KEY, SECRET, SESSION_KEY=None): 
    self.__API_KEY__ = API_KEY 
    self.__SECRET__ = SECRET 
    self.__SESSION_KEY__ = SESSION_KEY 
    self.__api_signature__ = None 
    if SESSION_KEY is None: 
     self.__is_authorized__ = False 
    else: 
     self.__is_authorized__ = True 

    self.__http__ = urllib3.PoolManager() 

def request_token(self): 
    print("Getting the token...") 
    url = 'http://ws.audioscrobbler.com/2.0/?method=auth.gettoken&api_key={}&format=json'.format(self.__API_KEY__) 
    req_response = self.__http__.request('GET', url, headers={'User-Agent' : 'Mozilla/5.0'}) 
    if req_response.status == 200: 
     json_data = json.loads(req_response.data.decode('utf-8')) 
     TOKEN = json_data['token'] 
     self.__TOKEN__ = TOKEN 
     return TOKEN 
    else: 
     print("Error with code " + req_response.status) 

def authorize(self): 
    if not self.__is_authorized__: 
     url = 'http://www.last.fm/api/auth/?api_key={}&token={}'.format(self.__API_KEY__, self.__TOKEN__) 
     # open browser to authorize app 
     webbrowser.open(url, new=0, autoraise=True) 
     # Make sure authorized 
     self.__is_authorized__ = True 


def start_session(self): 
    if self.__is_authorized__: 
     data = "api_key{}methodauth.getSessiontoken{}{}" \ 
            .format(self.__API_KEY__, self.__TOKEN__, self.__SECRET__).encode(
      encoding='utf-8') 
     self.__api_signature__ = md5(data).hexdigest() 
     url = 'http://ws.audioscrobbler.com/2.0/?method=auth.getSession&api_key={}&token={}&api_sig={}&format=json'.format(
      self.__API_KEY__, self.__TOKEN__, self.__api_signature__) 
     req_response = self.__http__.request('GET', url) 

     if req_response.status == 200: 
      json_data = json.loads(req_response.data.decode('utf-8')) 
      session_key = json_data['session']['key'] 
      self.__SESSION_KEY__ = session_key 

      url = 'http://ws.audioscrobbler.com/2.0/?method=track.love&api_key={}&api_sig={}&sk={}&artist=cher&track=believe&format=json'.format(
       self.__API_KEY__, self.__api_signature__, self.__SESSION_KEY__) 
      req_response = self.__http__.request('POST', url) 

      return self.__SESSION_KEY__ 
     else: 
      print("Error with code " + str(req_response.status)) 




    else: 
     print("Not authorized!") 

Antwort

0

Ich fand eine Lösung. Das Problem war, dass ich die gleichen Parameter verwendete, die verwendet wurden, um den Sitzungsschlüssel zu generieren, um einen POST-Anruf zu tätigen. Der richtige Weg, eine Methode für die Last.fm-API zu signieren, besteht darin, api_sig aus der POST-Methode zu erstellen, die wir verwenden möchten. Um zum Beispiel für track.love zu erzeugen, verwenden wir diese Parameter:

data = {"api_key": API_KEY, 
        "method": "track.love", 
        "track" : "yellow", 
        "artist" :"coldplay", 
        "sk" : SESSION_KEY 
        } 
keys = sorted(data.keys()) 
param = [k+data[k] for k in keys] 
param = "".join(param) + SECRET 
api_sig = md5(param.encode()).hexdigest() # this api_sig used to sign track.love call. 
Verwandte Themen