Keyerror when using Json in python - python

I'm using a basic script to retrieve some trading data from an exchange, here is the response:
{'info': {'symbol': 'ETHBTC',
'orderListId': -1,
'price': '0.01083700',
'origQty': '0.01800000',
'executedQty': '0.00000000',
'cummulativeQuoteQty': '0.00000000',
'status': 'NEW',
'timeInForce': 'GTC',
'type': 'LIMIT',
'side': 'BUY',
'stopPrice': '0.00000000',
'icebergQty': '0.00000000',
'time': 1567078061338,
'updateTime': 1567078061338,
'isWorking': True}}
Now i want to print some parts of this response individually.
If i try:
tot = exchange.fetch_open_orders()
for x in tot:
print(x['symbol'])
I'll get: 'ETHBTC'. Until now, everything is normal.
But if i try:
tot = exchange.fetch_open_orders()
for x in tot:
print(x['origQty'])
I get a KeyError: 'origQty', which is weird, because this error should appear when i try to reference a parameter which doesn't exist, but it exists, since it is in my response. What am i doing wrong?

Here you iterating dictionary on keys, so each time you are trying to get value from key, that's why it is giving KeyError.
This occurs when a key which is not present in a dictionary and still it accessed.
This can be achieved by following way.
for x in tot:
print(tot[x].get('symbol'))
print(tot[x].get('origQty'))
Give output
ETHBTC
0.01800000

I am not sure what is the format of tot. But you can try this.
for x, v in dict(tot).items():
print(v['symbol'])
print(v['origQty'])
Output:
ETHBTC
0.01800000

Related

How to close a margin order in OKX using CCXT

I found an old thread ( how can I close position on OKX V5 based on CCXT Python? ) but is not working.
I'm having problem in closing my current margin-spot position. Here's my code:
params = {'tdMode': 'cross', 'ccy': 'USDT'}
order = await self.okx.create_order(
symbol='XRP/USDT', type='market', side='sell',
amount=99.43, price=0.39024, params=params
)
Result:
{'amount': 99.431119,
'average': 0.39005,
'clientOrderId': 'e847386590ce4dBCce71dedc37e12254',
'cost': 38.78310796595,
'datetime': '2022-12-02T17:29:58.048Z',
'fee': {'cost': 0.03878310796595, 'currency': 'USDT'},
'fees': [{'cost': 0.03878310796595, 'currency': 'USDT'}],
'filled': 99.431119,
'id': '518962064594153472',
Places the first order correctly. Now to close this order I use barrely the same code, changing sides:
params = {'tdMode': 'cross', 'ccy': 'USDT'}
order = await self.okx.create_order(
symbol='XRP/USDT', type='market', side='buy',
amount=99.43, price=0.39017, params=params
)
Problem is that the amount in the second order seeems to be 'contracts'/'price' instead:
result:
{'amount': 99.43111,
'average': 0.39015,
'clientOrderId': 'e847386590ce4dBC328bc6dfc937795f',
'cost': 99.43110980145,
'datetime': '2022-12-02T17:36:47.913Z',
'fee': {'cost': 0.254853543, 'currency': 'XRP'},
'fees': [{'cost': 0.254853543, 'currency': 'XRP'}],
'filled': 254.853543,
'id': '518963783692562432',
What am I doing wrong ?
Are you changing the default tgtCcy value?
Can you try to place the market order without the price (market orders execute at the market price so you don't need to specify it)?

How can I reformat JSON / Dictionaries in Python

I have the below list -
[{'metric': 'sales', 'value': '100', 'units': 'dollars'},
{'metric': 'instock', 'value': '95.2', 'units': 'percent'}]
I would like to reformat it like the below in Python -
{'sales': '100', 'instock': '95.2'}
I did the below -
a = [above list]
for i in a:
print({i['metric']: i['value']})
But it outputs like this -
{'sales': '100'}
{'instock': '95.2'}
I would like these 2 lines to be a part of the same dictionary
d = [{'metric': 'sales', 'value': '100', 'units': 'dollars'},
{'metric': 'instock', 'value': '95.2', 'units': 'percent'}]
new_d = {e["metric"]: e["value"] for e in d}
# output: {'sales': '100', 'instock': '95.2'}
I believe that it's best to try it first by yourself, and then post a question in case you don't succeed. You should consider posting your attempts next time.

Accessing keys/values in a paginated/nested dictionary

I know that somewhat related questions have been asked here: Accessing key, value in a nested dictionary and here: python accessing elements in a dictionary inside dictionary among other places but I can't quite seem to apply the answers' methodology to my issue.
I'm getting a KeyError trying to access the keys within response_dict, which I know is due to it being nested/paginated and me going about this the wrong way. Can anybody help and/or point me in the right direction?
import requests
import json
URL = "https://api.constantcontact.com/v2/contacts?status=ALL&limit=1&api_key=<redacted>&access_token=<redacted>"
#make my request, store it in the requests object 'r'
r = requests.get(url = URL)
#status code to prove things are working
print (r.status_code)
#print what was retrieved from the API
print (r.text)
#visual aid
print ('---------------------------')
#decode json data to a dict
response_dict = json.loads(r.text)
#show how the API response looks now
print(response_dict)
#just for confirmation
print (type(response_dict))
print('-------------------------')
# HERE LIES THE ISSUE
print(response_dict['first_name'])
And my output:
200
{"meta":{"pagination":{}},"results":[{"id":"1329683950","status":"ACTIVE","fax":"","addresses":[{"id":"4e19e250-b5d9-11e8-9849-d4ae5275509e","line1":"222 Fake St.","line2":"","line3":"","city":"Kansas City","address_type":"BUSINESS","state_code":"","state":"OK","country_code":"ve","postal_code":"19512","sub_postal_code":""}],"notes":[],"confirmed":false,"lists":[{"id":"1733488365","status":"ACTIVE"}],"source":"Site Owner","email_addresses":[{"id":"1fe198a0-b5d5-11e8-92c1-d4ae526edd6c","status":"ACTIVE","confirm_status":"NO_CONFIRMATION_REQUIRED","opt_in_source":"ACTION_BY_OWNER","opt_in_date":"2018-09-11T18:18:20.000Z","email_address":"rsmith#fake.com"}],"prefix_name":"","first_name":"Robert","middle_name":"","last_name":"Smith","job_title":"I.T.","company_name":"FBI","home_phone":"","work_phone":"5555555555","cell_phone":"","custom_fields":[],"created_date":"2018-09-11T15:12:40.000Z","modified_date":"2018-09-11T18:18:20.000Z","source_details":""}]}
---------------------------
{'meta': {'pagination': {}}, 'results': [{'id': '1329683950', 'status': 'ACTIVE', 'fax': '', 'addresses': [{'id': '4e19e250-b5d9-11e8-9849-d4ae5275509e', 'line1': '222 Fake St.', 'line2': '', 'line3': '', 'city': 'Kansas City', 'address_type': 'BUSINESS', 'state_code': '', 'state': 'OK', 'country_code': 've', 'postal_code': '19512', 'sub_postal_code': ''}], 'notes': [], 'confirmed': False, 'lists': [{'id': '1733488365', 'status': 'ACTIVE'}], 'source': 'Site Owner', 'email_addresses': [{'id': '1fe198a0-b5d5-11e8-92c1-d4ae526edd6c', 'status': 'ACTIVE', 'confirm_status': 'NO_CONFIRMATION_REQUIRED', 'opt_in_source': 'ACTION_BY_OWNER', 'opt_in_date': '2018-09-11T18:18:20.000Z', 'email_address': 'rsmith#fake.com'}], 'prefix_name': '', 'first_name': 'Robert', 'middle_name': '', 'last_name': 'Smith', 'job_title': 'I.T.', 'company_name': 'FBI', 'home_phone': '', 'work_phone': '5555555555', 'cell_phone': '', 'custom_fields': [], 'created_date': '2018-09-11T15:12:40.000Z', 'modified_date': '2018-09-11T18:18:20.000Z', 'source_details': ''}]}
<class 'dict'>
-------------------------
Traceback (most recent call last):
File "C:\Users\rkiek\Desktop\Python WIP\Chris2.py", line 20, in <module>
print(response_dict['first_name'])
KeyError: 'first_name'
first_name = response_dict["results"][0]["first_name"]
Even though I think this question would be better answered by yourself by reading some documentation, I will explain what is going on here. You see the dict-object of the man named "Robert" is within a list which is a value under the key "results". So, at first you need to access the value within results which is a python-list.
Then you can use a loop to iterate through each of the elements within the list, and treat each individual element as a regular dictionary object.
results = response_dict["results"]
results = response_dict.get("results", None)
# use any one of the two above, the first one will throw a KeyError if there is no key=="results" the other will return NULL
# this results is now a list according to the data you mentioned.
for item in results:
print(item.get("first_name", None)
# here you can loop through the list of dictionaries and treat each item as a normal dictionary

Accessing nested lists/dictionaries

I am extracting data from ebay using ebay-sdkpython. The end goal is to have a XLS dump of items with specific fields for each item. The output that I want to manipulate comes as a complex nested list/dict as below:
dict = {'ack': 'Success',
'timestamp': '2015-11-20T03:49:08.302Z',
'version': '1.13.0',
'searchResult':
{'item': [
{'itemId': '111827613927',
'topRatedListing': 'false',
'sellingStatus':
{'currentPrice':
{'_currencyId': 'AUD',
'value': '290.0'},
'convertedCurrentPrice': {'_currencyId': 'AUD', 'value': '290.0'},
'sellingState': 'EndedWithSales'},
'listingInfo':
{'listingType': 'FixedPrice',
'endTime': '2015-11-20T03:35:07.000Z'}
},
'_count': '100'},
'paginationOutput':
{'totalPages': '114',
'entriesPerPage': '100',
'pageNumber': '1',
'totalEntries': '11364'}}
I know that I can pull a specific key out using the following format:
print dict['searchResult']['item'][0]['itemId']
But I want to pull all of them, with the varying levels of nesting. I also need error handling as some fields are missing, these should return a ''. My code so far is:
x=1
for item in response.dict()['searchResult']['item']:
print x,
for field in ['itemId','topRatedListing']:
try:
print item[field]
except KeyError:
print ''
x=x+1
print '\n'
How would I modify this for loop to also include, for example, ['sellingstatus']['currentprice']['value'] ?

Accessing YAML data in Python

I have a YAML file that parses into an object, e.g.:
{'name': [{'proj_directory': '/directory/'},
{'categories': [{'quick': [{'directory': 'quick'},
{'description': None},
{'table_name': 'quick'}]},
{'intermediate': [{'directory': 'intermediate'},
{'description': None},
{'table_name': 'intermediate'}]},
{'research': [{'directory': 'research'},
{'description': None},
{'table_name': 'research'}]}]},
{'nomenclature': [{'extension': 'nc'}
{'handler': 'script'},
{'filename': [{'id': [{'type': 'VARCHAR'}]},
{'date': [{'type': 'DATE'}]},
{'v': [{'type': 'INT'}]}]},
{'data': [{'time': [{'variable_name': 'time'},
{'units': 'minutes since 1-1-1980 00:00 UTC'},
{'latitude': [{'variable_n...
I'm having trouble accessing the data in python and regularly see the error TypeError: list indices must be integers, not str
I want to be able to access all elements corresponding to 'name' so to retrieve each data field I imagine it would look something like:
import yaml
settings_stream = open('file.yaml', 'r')
settingsMap = yaml.safe_load(settings_stream)
yaml_stream = True
print 'loaded settings for: ',
for project in settingsMap:
print project + ', ' + settingsMap[project]['project_directory']
and I would expect each element would be accessible via something like ['name']['categories']['quick']['directory']
and something a little deeper would just be:
['name']['nomenclature']['data']['latitude']['variable_name']
or am I completely wrong here?
The brackets, [], indicate that you have lists of dicts, not just a dict.
For example, settingsMap['name'] is a list of dicts.
Therefore, you need to select the correct dict in the list using an integer index, before you can select the key in the dict.
So, giving your current data structure, you'd need to use:
settingsMap['name'][1]['categories'][0]['quick'][0]['directory']
Or, revise the underlying YAML data structure.
For example, if the data structure looked like this:
settingsMap = {
'name':
{'proj_directory': '/directory/',
'categories': {'quick': {'directory': 'quick',
'description': None,
'table_name': 'quick'}},
'intermediate': {'directory': 'intermediate',
'description': None,
'table_name': 'intermediate'},
'research': {'directory': 'research',
'description': None,
'table_name': 'research'},
'nomenclature': {'extension': 'nc',
'handler': 'script',
'filename': {'id': {'type': 'VARCHAR'},
'date': {'type': 'DATE'},
'v': {'type': 'INT'}},
'data': {'time': {'variable_name': 'time',
'units': 'minutes since 1-1-1980 00:00 UTC'}}}}}
then you could access the same value as above with
settingsMap['name']['categories']['quick']['directory']
# quick

Categories

Resources