How to parse data from API? - python

Am getting API response Like Below
https://imgur.com/a/uVcLfF4
{'s': 'ok', 'd':
[
{'n': 'NSE:SBIN22JUL485CE', 's': 'ok', 'v': {'ch': -2.25, 'chp': -17.05, 'lp': 10.95, 'spread': 0.25, 'ask': 10.95, 'bid': 10.7, 'open_price': 11.5, 'high_price': 15.05, 'low_price': 10.45, 'prev_close_price': 13.2, 'volume': 1161000, 'short_name': 'SBIN22JUL485CE', 'exchange': 'NSE', 'description': 'NSE:SBIN22JUL485CE', 'original_name': 'NSE:SBIN22JUL485CE', 'symbol': 'NSE:SBIN22JUL485CE', 'fyToken': '1011220728149794', 'tt': 1657584000, 'cmd': {'t': 1657620000, 'o': 10.95, 'h': 10.95, 'l': 10.95, 'c': 10.95, 'v': 1500, 'tf': '15:30'}}
},
{'n': 'NSE:SBIN22JUL480CE', 's': 'ok', 'v': {'ch': -2.65, 'chp': -16.46, 'lp': 13.45, 'spread': 0.1, 'ask':
13.45, 'bid': 13.35, 'open_price': 15.3, 'high_price': 18.45, 'low_price': 12.9, 'prev_close_price': 16.1, 'volume': 4270500, 'short_name': 'SBIN22JUL480CE', 'exchange': 'NSE', 'description': 'NSE:SBIN22JUL480CE', 'original_name': 'NSE:SBIN22JUL480CE', 'symbol': 'NSE:SBIN22JUL480CE', 'fyToken': '1011220728128799', 'tt': 1657584000, 'cmd': {'t': 1657619940, 'o': 13.45, 'h': 13.45, 'l': 13.45, 'c': 13.45, 'v': 28500, 'tf': '15:29'}}
}
]
}
How to read and print this in python like below.
Name= NSE:SBIN22JUL485CE
ch = -2.25
chp = -17.05
volume = 1161000
Name= NSE:SBIN22JUL480CE
ch = -2.65
chp = -16.46
volume = 4270500

It looks like json, if you have that text in a variable, you can use the python json librarie for decoding it, and get a dictionary.
import json
text = '...' # The variable that contains the response
data = json.loads(text)
for entry in data['d']:
print(f'Name = {entry["n"]}')
print(f'ch = {entry["v"]["ch"]}')
print(f'chp = {entry["v"]["chp"]}')
print(f'volume = {entry["v"]["volume"]}')
print('')
If for some reason, in the text, the quotes are single quotes ' insted of double ", you should need to replace it, before the json parsing:
text = text.replace("'", '"')

If it is already a dict, just print the content:
mydict = <API response>
if 's' in mydict and mydict['s'] == 'ok':
for data in mydict['d']:
print('Name:', data['n'])
print('ch:', data['v']['ch'])
print('chp:', data['v']['chp'])
print('volume:', data['v']['volume'])
print()
If it is not a dict then you need to convert the content before:
import json
content = <API response>
mydict = json.loads(content)
<code to print above>

Related

How to select some key values from a dictionary and assign to another dictionary in python

I have a variable which stores below dictionary
initial_ltp =
{'s': 'ok',
'd': [{'n': 'MCX:CRUDEOIL23JANFUT',
's': 'ok',
'v': {'ch': 47.0,
'chp': 0.74,
'lp': 6377.0,
'spread': 2.0,
'ask': 6379.0,
'bid': 6377.0,
'open_price': 6330.0,
'high_price': 6393.0,
'low_price': 6305.0,
'prev_close_price': 6330.0,
'volume': 8410,
'short_name': 'CRUDEOIL23JANFUT',
'exchange': 'MCX',
'description': 'MCX:CRUDEOIL23JANFUT',
'original_name': 'MCX:CRUDEOIL23JANFUT',
'symbol': 'MCX:CRUDEOIL23JANFUT',
'fyToken': '1120230119244999',
'tt': 1673481600,
'cmd': {'t': 1673518200,
'o': 6376.0,
'h': 6378.0,
'l': 6375.0,
'c': 6377.0,
'v': 19,
'tf': '15:40'}}},
{'n': 'MCX:SILVERMIC23FEBFUT',
's': 'ok',
'v': {'ch': 485.0,
'chp': 0.71,
'lp': 68543.0,
'spread': 5.0,
'ask': 68545.0,
'bid': 68540.0,
'open_price': 68200.0,
'high_price': 68689.0,
'low_price': 68200.0,
'prev_close_price': 68058.0,
'volume': 49595,
'short_name': 'SILVERMIC23FEBFUT',
'exchange': 'MCX',
'description': 'MCX:SILVERMIC23FEBFUT',
'original_name': 'MCX:SILVERMIC23FEBFUT',
'symbol': 'MCX:SILVERMIC23FEBFUT',
'fyToken': '1120230228242738',
'tt': 1673481600,
'cmd': {'t': 1673518200,
'o': 68525.0,
'h': 68543.0,
'l': 68524.0,
'c': 68543.0,
'v': 140,
'tf': '15:40'}}}]}
I am trying to collect ('n') and ('lp') and save it in a different dictionary using code:
if 'd' in initial_ltp.keys():
ltp[initial_ltp['d'][0]['n']] = initial_ltp['d'][0]['v']['lp']
But it is only taking the first n and lp
ltp
{'MCX:CRUDEOIL23JANFUT': 6377.0}
My expected output:
ltp
{'MCX:CRUDEOIL23JANFUT': 6377.0, 'MCX:SILVERMIC23FEBFUT': 68543.0}
How can I get both the values
You have to loop over the list. Using ltp[initial_ltp['d'][0] will just extract for the first element of the list.
Here is an example:
results = {}
for doc in initial_ltp["d"]:
results[doc["n"]] = doc["v"]["lp"]
print(results)
Use the following approach with dict comprehension:
ltp = {d['n']:d['v']['lp'] for d in initial_ltp['d']} if 'd' in initial_ltp else {}
{'MCX:CRUDEOIL23JANFUT': 6377.0, 'MCX:SILVERMIC23FEBFUT': 68543.0}
when you use the "=" operator, it replaces your value in the dictionary key.
you want to add keys to your dictionary so I suggest using this:
if 'd' in initial_ltp.keys():
for o in initial_ltp['d']:
if n in o:
ltp[initial_ltp['d'][0]['n']].append(initial_ltp['d'][0]['v']
['lp']
It's because you selected only first item in the 'd'.
try a loop like this:
ltp={}
if 'd' in initial_ltp.keys():
for i in range(len(initial_ltp['d'])):
ltp[initial_ltp['d'][i]['n']] = initial_ltp['d'][i]['v']['lp']
print (ltp)
Output:
{'MCX:CRUDEOIL23JANFUT': 6377.0, 'MCX:SILVERMIC23FEBFUT': 68543.0}

How to store incoming json via websocket to SQL database

to start I am very new to python (and coding period) so I apologize if I am going about this the wrong way.
I am receiving these json messages from a websocket stream:
import websocket, json, dateutil.parser
import dateparser
import csv
import itertools
current_tick = None
dataframe = []
symbols = 'AAPL', 'FB', 'AMZN', 'NFLX'
def on_open(ws):
print("opened")
auth_data = {
"action": "auth",
"params": 'APIKEY'
}
ws.send(json.dumps(auth_data))
for s in symbols:
channel_data = {
"action": "subscribe",
"params": s
}
ws.send(json.dumps(channel_data))
def on_message(ws, message):
global current_tick, dataframe
current_tick = json.loads(message)
print(current_tick)
if current_tick[0]['ev'] == 'T':
dataframe.append(current_tick)
def on_close(ws):
print("closed connection")
socket = "WEBSITE"
ws = websocket.WebSocketApp(socket, on_open=on_open, on_message=on_message, on_close=on_close)
#ws.run_forever()
OUTPUTS:
[{'ev': 'T', 'sym': 'AAPL', 'i': '227161', 'x': 4, 'p': 134.605, 's': 100, 't': 1609275343055, 'z': 3}]
[{'ev': 'T', 'sym': 'AAPL', 'i': '227162', 'x': 4, 'p': 134.605, 's': 3, 'c': [37], 't': 1609275343072, 'z': 3}]
[{'ev': 'T', 'sym': 'AAPL', 'i': '155273', 'x': 12, 'p': 134.6, 's': 25, 'c': [14, 37, 41], 't': 1609275343104, 'z': 3}]
[{'ev': 'T', 'sym': 'FB', 'i': '47501', 'x': 4, 'p': 276.5, 's': 1, 'c': [12, 37], 't': 1609276352067, 'z': 3}]
[{'ev': 'T', 'sym': 'NFLX', 'i': '10420', 'x': 11, 'p': 531.5, 's': 147, 'c': [14, 12, 41], 't': 1609276352376, 'z': 3}]
My goal is to to store these into SQL database as they come in, this is what I have so far
import psycopg2
postgresConnection = psycopg2.connect(
host='HOST',
user='USER',
password='PASSWORD',
database='DATABASE'
cursor= postgresConnection.cursor()
sqlCreateTable = "create table datas(sym varchar(256), price int, size int, exchange int, time int);"
cursor.execute(sqlCreateTable)
postgresConnection.commit()
sqlpoptable = "intert into datas(sym, price, size) VALUES(%(sym)s, %(price)s, %(size)s)", {"sym":current_tick['sym'],"price":current_tick['p'], "size":current_tick['s']}
cursor.execute(sqlpoptable)
postgresConnection.commit()
And my output is:
TypeError: list indices must be integers or slices, not str
Any thoughts? Thanks in advance.
As you may already know, you can access array data using an index. An index is a number that represents the data's position in the array, starting with the number zero.
If you have an array of items like this:
items = ['a', 'z', 'c', 'd']
Then the index of 'a' would be 0, the index of 'z' would be 1, the index of 'c' would be 2, and so on.
If you wrote some Python code that looked like this:
items = ['a', 'z', 'c', 'd']
myChosenItem = items[0]
Then myChosenItem would be equal to 'a'. Make sense?
The error you are getting is telling you that you tried to provide something other than an integer (a whole number) as an index when getting data out of an array.
That would be like writing this:
items = ['a', 'z', 'c', 'd']
myChosenItem = items['chicken']
Python would have no idea what you meant. Look at your code and figure out where you are accessing array data using an index, and then figure out if that index is an integer or not. Then you should be able to get this error to go away.

Molecular mass calculator

I am doing a project in university and I'm working on molecular mass calculator.
This is the code I made.
element_mass = {'H': 1.00794, 'He': 4.002602, 'Li': 6.941, 'Be': 9.012182, 'B': 10.811, 'C': 12.0107, 'N': 14.0067,
'O': 15.9994, 'F': 18.9984032, 'Ne': 20.1797, 'Na': 22.98976928, 'Mg': 24.305, 'Al': 26.9815386,
'Si': 28.0855, 'P': 30.973762, 'S': 32.065, 'Cl': 35.453, 'Ar': 39.948, 'K': 39.0983, 'Ca': 40.078,
'Sc': 44.955912, 'Ti': 47.867, 'V': 50.9415, 'Cr': 51.9961, 'Mn': 54.938045,
'Fe': 55.845, 'Co': 58.933195, 'Ni': 58.6934, 'Cu': 63.546, 'Zn': 65.409, 'Ga': 69.723, 'Ge': 72.64,
'As': 74.9216, 'Se': 78.96, 'Br': 79.904, 'Kr': 83.798, 'Rb': 85.4678, 'Sr': 87.62, 'Y': 88.90585,
'Zr': 91.224, 'Nb': 92.90638, 'Mo': 95.94, 'Tc': 98.9063, 'Ru': 101.07, 'Rh': 102.9055, 'Pd': 106.42,
'Ag': 107.8682, 'Cd': 112.411, 'In': 114.818, 'Sn': 118.71, 'Sb': 121.760, 'Te': 127.6,
'I': 126.90447, 'Xe': 131.293, 'Cs': 132.9054519, 'Ba': 137.327, 'La': 138.90547, 'Ce': 140.116,
'Pr': 140.90465, 'Nd': 144.242, 'Pm': 146.9151, 'Sm': 150.36, 'Eu': 151.964, 'Gd': 157.25,
'Tb': 158.92535, 'Dy': 162.5, 'Ho': 164.93032, 'Er': 167.259, 'Tm': 168.93421, 'Yb': 173.04,
'Lu': 174.967, 'Hf': 178.49, 'Ta': 180.9479, 'W': 183.84, 'Re': 186.207, 'Os': 190.23, 'Ir': 192.217,
'Pt': 195.084, 'Au': 196.966569, 'Hg': 200.59, 'Tl': 204.3833, 'Pb': 207.2, 'Bi': 208.9804,
'Po': 208.9824, 'At': 209.9871, 'Rn': 222.0176, 'Fr': 223.0197, 'Ra': 226.0254, 'Ac': 227.0278,
'Th': 232.03806, 'Pa': 231.03588, 'U': 238.02891, 'Np': 237.0482, 'Pu': 244.0642, 'Am': 243.0614,
'Cm': 247.0703, 'Bk': 247.0703, 'Cf': 251.0796, 'Es': 252.0829, 'Fm': 257.0951, 'Md': 258.0951,
'No': 259.1009, 'Lr': 262, 'Rf': 267, 'Db': 268, 'Sg': 271, 'Bh': 270, 'Hs': 269, 'Mt': 278,
'Ds': 281, 'Rg': 281, 'Cn': 285, 'Nh': 284, 'Fl': 289, 'Mc': 289, 'Lv': 292, 'Ts': 294, 'Og': 294,
'ZERO': 0}
import re
formula=input("화학식을 입력해주세요:")
s=re.findall('([A-Z][a-z]?)([0-9]*)',formula)
for element,count in s:
if count==' ':
count==1
totalmass=sum(int(count)*element_mass[element])
print('화학식량은',' ',total_mass,'입니다.')
'화학식을 입력해주세요' means 'Input chemical formula', and '화학식량은 total_mass입니다' means 'Molecular mass is total_mass'.
When I run the code, it keeps printing
Traceback (most recent call last):
File "C:\Users\Lenovo\Desktop\코딩기말\연습.py", line 28, in <module>
totalmass=sum(int(count)*element_mass[element])
ValueError: invalid literal for int() with base 10: ''
I don't know how to solve this problem.
Did you notice the '' in the error message:
ValueError: invalid literal for int() with base 10: ''
>>> int('')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: ''
So it basically means that you trying to convert an empty string to int.

Concatenating nested dictionary keys depending on number of values

I'm trying to manipulate nested dictionaries to combine backwards the keys of any nested dictionaries with only a single key.
I've tried to do this recursively, but I'm having a hard time being able to remove keys from the dictionary and replace them with the concatenated keys.
For example:
{'adv':
{'e':
{'r':
{
's':
{'e':
{'_end_': '_end_'}
},
't':
{'_end_': '_end_',
'i':
{'s':
{'e':
{'r':
{'_end_': '_end_'}
}
}
}
}
}
},
'i': {'c': {'e': {'_end_': '_end_'}
}
}
}
}
would become
{'adv':
{'er':
{
'se':
{'_end_': '_end_'},
't':
{'_end_': '_end_',
'iser':
{'_end_': '_end_'}
}
},
'ice':
{'_end_': '_end_'}
}
}
This was an interesting problem - there is probably a more elegant solution, but I did the following:
import pprint
t={'adv': {'e': {'r': {'s': {'e': {'_end_': '_end_'}},
't': {'_end_': '_end_',
'i': {'s': {'e': {'r': {'_end_': '_end_'}}}}}}},
'i': {'c': {'e': {'_end_': '_end_'}}}}}
def concat_dict(d):
if d == '_end_':
return '_end_'
rv = {}
for k, v in d.items():
if '_end_' in v:
rv[k] = concat_dict(v)
elif len(list(x for x in v.keys() if x != '_end_')) == 1:
top_str = k
next_str = list(v.keys())[0]
rv[top_str + next_str] = concat_dict(v[next_str])
else:
rv[k] = concat_dict(v)
return rv
def format_dict(d):
while concat_dict(d) != d:
d = concat_dict(d)
return d
pprint.pprint(format_dict(t))
Output:
{'adv': {'er': {'se': {'_end_': '_end_'},
't': {'_end_': '_end_', 'iser': {'_end_': '_end_'}}},
'ice': {'_end_': '_end_'}}}

Fill stock input in searchbox on moneycontrol site using beautifulsoup

I want to fetch stock information from Moneycontrol site. I want to fill stock name in searchbox.
html code:
<input class="txtsrchbox FL" id="search_str"
onkeyup="getAutosuggesionHeader('#form_topsearch');"
onclick="getAutosuggesionHeader('#form_topsearch');"
placeholder="Search Quotes, News, NAVs" name="search_str"
value="" type="text" autocomplete="off">
How can i achieve this using beautifulsoup.
I have tried following code:
from BeautifulSoup import BeautifulSoup
import urllib
post_params = {'value' : 'SBIN' }
post_args = urllib.parse.urlencode(post_params).encode("utf-8")
url = 'https://www.moneycontrol.com'
fp = urllib.request.urlopen(url, post_args)
soup = BeautifulSoup(fp)
I'm not familiar with financial info so this might not be of use, but maybe it is, or maybe QHarr can work off of it. Looks like it gives back some value for (t:time?, cp:closing price? v:volume? ap:???)
So I noticed you can get some response from the chart data, however it requires to enter a parameter to query (ie. a sc_id value, in this case for SBIN, is SBI.)
So I needed a way though to get that sc_id value, and saw they have a "suggested" text search return that can be accessed to enter your search word (ie: "sbin"), to get back that sc_id.
So here's a little script that was able to get some info back for SBIN. Hopefully this can get some use out of it:
import requests
import json
headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36'}
# Enter search text
query_input = input('Enter Search Text: ')
#Get suggested sc_id
suggest_query_url = 'https://www.moneycontrol.com/mccode/common/autosuggestion_solr.php'
query = {
'classic': 'true',
'query': query_input,
'type': '1',
'format': 'json',
'callback': 'suggest1'}
# Pull out the sc_id
suggested_response = requests.get(suggest_query_url , headers=headers, params=query).text
suggested_response = suggested_response.split('(',1)[1]
suggested_response = suggested_response.rsplit(')',1)[0]
sc_id = json.loads(suggested_response)[0]['sc_id']
# Use the sc_id to get BSE and NSE data
request_url = 'https://www.moneycontrol.com/stocks/company_info/get_vwap_chart_data.php'
query = {'sc_did': sc_id}
response = requests.get(request_url, headers=headers, params=query).json()
Output:
print (response)
{'BSE': [{'t': '1551949665', 'ap': '279.70', 'cp': '279.70', 'v': '2151'}, {'t': '1551949704', 'ap': '279.70', 'cp': '279.70', 'v': '2151'}, {'t': '1551949740', 'ap': '279.70', 'cp': '279.70', 'v': '2151'}, {'t': '1551950159', 'ap': '278.93', 'cp': '278.90', 'v': '18755'}, {'t': '1551950219', 'ap': '278.90', 'cp': '278.70', 'v': '23368'}, {'t': '1551950279', 'ap': '278.89', 'cp': '279.00', 'v': '32498'}, {'t': '1551950338', 'ap': '278.91', 'cp': '279.00', 'v': '36396'}, {'t': '1551950399', 'ap': '278.90', 'cp': '278.80', 'v': '42964'}, {'t': '1551950459', 'ap': '278.88', 'cp': '278.35', 'v': '45685'}, {'t': '1551950519', 'ap': '278.76', 'cp': '278.30', 'v': '54082'}, {'t': '1551950579', 'ap': '278.74', 'cp': '278.30', 'v': '56780'}, {'t': '1551950639', 'ap': '278.69', 'cp': '278.20', 'v': '62504'}, {'t': '1551950699', 'ap': '278.68', 'cp': '278.10', 'v': '63338'}, {'t': '1551950759', 'ap': '278.68', 'cp': '278.10', 'v': '63723'}, {'t': '1551950819', 'ap': '278.67', 'cp': '277.80', 'v': '64998'}, {'t': '1551950879', 'ap': '278.63', 'cp': '278.20', 'v': '68780'}, {'t': '1551950939', 'ap': '278.59', 'cp': '278.60', 'v': '77680'}, {'t': '1551950999', 'ap': '278.59', 'cp': '278.35', 'v': '79316'}, {'t': '1551951059', 'ap': '278.58', 'cp': '278.30', 'v': '80566'}, {'t': '1551951119', 'ap': '278.58', 'cp': '278.20', 'v': '81247'}, {'t': '1551951178', 'ap': '278.57', 'cp': '278.10', 'v': '82067'}, {'t': '1551951238', 'ap': '278.57', 'cp': '278.15', 'v': '82918'}, {'t': '1551951294', 'ap': '278.56', 'cp': '278.60', 'v': '85734'}, {'t': '1551951358', 'ap': '278.56', 'cp': '278.40', 'v': '87239'}, {'t': '1551951419', 'ap': '278.56', 'cp': '278.25', 'v': '88039'}, ...

Categories

Resources