Search code examples
pythonjsonkeyerror

Python JSON KeyError for non missing key


For some unknown reason, when I run the below script, the following error is returned along with the desired output. For some reason, this was working without any errors last night. The API output does change every minute but I wouldn't expect a KeyError to be returned. I can't simply pinpoint where this error is coming from:

[u'@AAPL  151204C00128000'] <----- What I want to see printed

Traceback (most recent call last):

File "Options_testing.py", line 60, in <module>
 main()
 File "Options_testing.py", line 56, in main
  if quotes[x]['greeks']['impvol'] > 0: #change this for different greek vals

KeyError: 'impvol'

Here is a little snippet of data:

{"results":{"optionchain":{"expire":"all","excode":"oprac","equityinfo":{"longname":"Apple Inc","shortname":"AAPL"},"money":"at","callput":"all","key":{"symbol":["AAPL"],"exLgName":"Nasdaq Global Select","exShName":"NGS","exchange":"NGS"},"symbolstring":"AAPL"},"quote":[{"delaymin":15,"contract":{"strike":108,"openinterest":3516,"contracthigh":6.16,"contractlow":0.02,"callput":"Put","type":"WEEK","expirydate":"2015-11-13"},"root":{"equityinfo":{"longname":"Apple Inc","shortname":"AAPL"},"key":{"symbol":["AAPL"],"exLgName":"Nasdaq Global Select","exShName":"NGS","exchange":"NGS"}},"greeks":{"vega":0,"theta":0,"gamma":0,"delta":0,"impvol":0,"rho":0}

Code:

#Options screener using Quotemedia's API
import json
import requests
#import csv        

def main():         


    url_auth= "https://app.quotemedia.com/user/g/authenticate/v0/102368/XXXXX/XXXXX"
    decode_auth = requests.get(url_auth)        

    #print decode_auth.json()
    #print(type(decode_auth))           

    auth_data = json.dumps(decode_auth.json())          

    #Parse decode_auth, grab 'sid'          

    sid_parsed = json.loads(auth_data)["sid"]
    #print sid_parsed           

    #Pass sid into qm_options
    #Construct URL          

    symbol = 'AAPL'
    SID  = sid_parsed
    url_raw = 'http://app.quotemedia.com/data/getOptionQuotes.json?webmasterId=102368'  


    url_data = url_raw + '&symbol=' + symbol + '&greeks=true' + '&SID=' + SID           

    #print url_data         

    response = requests.get(url_data)
    #print response
    data = json.dumps(response.json())
    #print data         

    #save data to a file            

    with open('AAPL_20151118.json', 'w') as outfile:
        json.dumps (data, outfile)          

    #Turn into json object
    obj = json.loads(data)        

    #slim the object
    quotes = obj['results']['quote']        

    #find the number of options contracts
    range_count = obj['results']['symbolcount']        

    #print all contracts with an implied vol > 0
    for x in range(0,range_count):
        if quotes[x]['greeks']['impvol'] > 0: #change this for different greek vals
            print quotes[x]['key']['symbol']        

if __name__ == '__main__':
  main()

I can provide sample data if necessary.


Solution

  • for x in range(0,range_count):
        if quotes[x]['greeks']['impvol'] > 0: #change this for different greek vals
            print quotes[x]['key']['symbol']
    

    This loops throug multiple quotes, so maybe there is even just one that does not have an impvol property.

    You should add some error handling, so you find out when that happens. Something like this:

    # no need to iterate over indexes, just iterate over the items
    for quote in quotes:
        if 'greeks' not in quote:
            print('Quote does not contain `greeks`:', quote)
        elif 'impvol' not in quote['greeks']:
            print('Quote does not contain `impvol`:', quote)
    
        elif quote['greeks']['impvol'] > 0:
            print quote['key']['symbol']