Timeout efter 1 sek mellan frågor till API? (python)

Added by Martin over 1 year ago

Hej hej

Det verkar som att om jag inte skickar en api-request varje sekund så svarar inte api:et längre. Jag har tagit exemplet för python och lagt till en loop som hämtar en lista på alla ens konton (/accounts) som man kan ändra hur länge den sover mellan varje varv:

import time
import base64
from M2Crypto import RSA
import httplib, urllib
import json

def print_json(j,prefix=''):
    for key, value in j.items():
        if isinstance (value,dict):
            print '%s%s' % (prefix,key)
            print_json(value, prefix+'  ')
        else:
            print '%s%s:%s' % (prefix,key,value)

username = 'username'
password = 'password'
service  = 'NEXTAPI'
URL='api.test.nordnet.se'
API_VERSION='2'

timestamp = int(round(time.time()*1000))
timestamp = str(timestamp)
buf = base64.b64encode(username)+':'+base64.b64encode(password)+':'+base64.b64encode(timestamp)
rsa=RSA.load_pub_key('NEXTAPI_TEST_public.pem')
encrypted_hash = rsa.public_encrypt(buf, RSA.pkcs1_padding)
hash = base64.b64encode(encrypted_hash)

headers = {"Accept": "application/json"}
conn = httplib.HTTPSConnection(URL)

# GET server status
conn.request('GET','/next/'+API_VERSION + '/', '', headers)
r=conn.getresponse()
response=r.read()
j = json.loads(response)
print_json(j)

# POST login
params = urllib.urlencode({'service': 'NEXTAPI', 'auth': hash})
conn.request('POST','/next/'+API_VERSION+'/login',params,headers)
r=conn.getresponse()
response=r.read()
j = json.loads(response)
print_json(j)

# get a list of all accounts
for i in range(10):
    headers = {"Accept": "application/json"}
    headers['Authorization'] = 'Basic ' + urllib.quote(base64.b64encode('%s:%s' % (j['session_key'],j['session_key'])).strip())
    conn.request('GET','/next/'+API_VERSION+'/accounts', '', headers)
    r = conn.getresponse()
    response = r.read()
    print(json.loads(response))

    # set seconds to sleep each iteration
    time.sleep(1)

Koden ovan funkar felfritt när man bara sover 1 sekund mellan varven,

time.sleep(1)
men om man ändrar det till
time.sleep(2)
så slutar det funka med felmeddelande
httplib.BadStatusLine: ''
direkt efter första varvet.

Är det någon som stött på samma problem och är det något uppenbart jag har missuppfattat? Problemet jag har är att min kod som ska interagera med api:et kommer ibland ta längre än 1 sekund på sig att dona mellan requests och då kraschar det. Kör med Python 2.7.12 om det spelar någon roll.

Mvh
Martin


Replies (1)

RE: Timeout efter 1 sek mellan frågor till API? (python) - Added by Martin over 1 year ago

Hittade lösningen i en gammal tråd, https://api.test.nordnet.se/boards/2/topics/2357?r=2362#message-2362

Jag bytte till att göra allt via modulen requests istället (pip install requests) och nu funkar det automagiskt. Moddat exempel nedan:

import time
import base64
from M2Crypto import RSA
import httplib, urllib
import json
import requests

def print_json(j,prefix=''):
    for key, value in j.items():
        if isinstance (value,dict):
            print '%s%s' % (prefix,key)
            print_json(value, prefix+'  ')
        else:
            print '%s%s:%s' % (prefix,key,value)

username = 'username'
password = 'password'
service  = 'NEXTAPI'
URL='https://api.test.nordnet.se'
API_VERSION='2'

timestamp = int(round(time.time()*1000))
timestamp = str(timestamp)
buf = base64.b64encode(username)+':'+base64.b64encode(password)+':'+base64.b64encode(timestamp)
rsa=RSA.load_pub_key('NEXTAPI_TEST_public.pem')
encrypted_hash = rsa.public_encrypt(buf, RSA.pkcs1_padding)
hash = base64.b64encode(encrypted_hash)

headers = {"Accept": "application/json"}

# GET server status
response = requests.get(
    URL+'/next/'+API_VERSION+'/',
    headers=headers
)
j = json.loads(response.text)
print_json(j)

# POST login
data = {'service': 'NEXTAPI', 'auth': hash}
response = requests.post(
    URL+'/next/'+API_VERSION+'/login',
    data=data,
    headers=headers
)
j = json.loads(response.text)
print_json(j)

# get a list of all accounts
for i in range(10):
    headers['Authorization'] = 'Basic ' + urllib.quote(base64.b64encode('%s:%s' % (j['session_key'],j['session_key'])).strip())
    response = requests.get(
        URL+'/next/'+API_VERSION+'/accounts',
        headers=headers
    )
    print(response.text)

    # set seconds to sleep each iteration
    time.sleep(2)

(1-1/1)