2016-05-22 8 views
0

Ich arbeite derzeit an einem Projekt, bei dem ich Daten aus einer REST-API online abrufen und zur weiteren Verarbeitung in einer lokalen Datenbank ablegen muss.Python Rest API-Aufrufgeschwindigkeit

Die API ist mit einer Online-Rechnungsplattform verbunden, und ich bin etwas besorgt über die Geschwindigkeit des Skripts.

Momentan öffnet mein Skript eine Verbindung, erstellt eine Liste von Rechnungen. Für jede Rechnung öffnet das Skript dann eine Verbindung für diese bestimmten Rechnungszeilen, die in eine andere Liste verschoben wird.

Ich lese gerade ein Konto mit 9 Rechnungen und insgesamt 15 Rechnungszeilen. Das dauert 7,4 Sekunden.

Kann mir jemand mit meinem Code helfen? vielleicht kann ich es etwas beschleunigen.

# -*- coding: utf-8 -*- 
import requests 
from datetime import datetime 
token = "b877aff346ec0c7d238c21a6c33929c84b13a110" 

def request(accessToken, url): 
    link = 'https://api.billysbilling.com/v2/' +str(url) 
    headers= {'X-Access-Token': accessToken} 
    data = requests.get(link, headers=headers).json() 
    return data 

def invoiceLines(token): 
    inv = request(accessToken = token, url = "invoices")["invoices"] 
    idList = [] 
    invoiceLinesList = [] 
    lines = [] 
    for r in inv: 
     if not r["id"] in idList: 
      idList.append(r["id"]) 
      invoiceLinesList.append(request(accessToken = token, 
            url = str("invoiceLines?invoiceId=") + 
              str(r["id"]))["invoiceLines"]) 
    for invoice in invoiceLinesList: 
     for line in invoice: 
      lines.append(line) 
    return [inv, lines] 

start = datetime.now() 
data = invoiceLines(token) 
print "Time spent - " + str(datetime.now()-start) 
print "Invoices - " + str(len(data[0])) 
print "Invoice lines - " +str(len(data[1])) 

Dank Henrik

+0

Wie lange dauert es, bis die Daten vom Remote-Server abgerufen werden? Wenn es 6,8 der 7 Sekunden insgesamt dauert, gibt es nicht viele Möglichkeiten zur Verbesserung. Werfen Sie einen Blick auf Zeit http://dabeaz.blogspot.co.uk/2010/02/context-manager-for-timing-benchmarks.html –

Antwort

1

Verwenden Sie eine Requests session, die automatisch eine Verbindung für mehrere Anfragen wiederverwendet werden. Beispiel:

class BillingAPI(object): 

    def __init__(self, token, root_url='https://api.billysbilling.com/v2/'): 
     self._session = requests.Session() 
     self._session.headers['X-Access-Token'] = token 
     self.root_url = root_url 

    def get(self, url_part): 
     url = self.root_url + str(url_part) 
     return self._session.get(url).json() 


def invoiceLines(token): 
    api = BillingAPI(token) 
    inv = api.get('invoices')['invoices'] 
    # ... 

Sie können auch versuchen, Rechnungszeilen für verschiedene Rechnungen parallel zu beantragen. Die requests-futures Erweiterung kann dabei helfen. Aber bitte seien Sie rücksichtsvoll, um den Server nicht zu überlasten.

Abgesehen davon werden Sie wahrscheinlich durch die Serverleistung der von Ihnen verwendeten API eingeschränkt sein.

Überlegen Sie, ob Sie eine allgemeine Optimierung wie Caching verwenden können. Die CacheControl-Bibliothek bietet einen einfachen HTTP-Cache für Anfragen, aber es ist unwahrscheinlich, dass diese API HTTP-Caching unterstützt. Daher müssen Sie Ihre eigenen rollen.

+0

Sehr schöne Lösung Vasiliy, dass nur die Zeit um zwei Drittel geschnitten, werde ich Blick in Anfragen-Futures-Erweiterung. –

Verwandte Themen