Python: Parsing JSON data from API get - referring to the dictionary key? - python

I'm pretty new to Python so I'm only just starting to work with API's. I have retrieved the data I need from an API and it returns in the following format:
{u'id': u'000123', u'payload': u"{'account_title': u’sam b’, 'phone_num': ‘1234567890’, 'security_pin': u'000000', 'remote_word': u’secret123’, 'email_address': ‘email#gmail.com’, 'password': u’password123’}”}
So when I print my variable, it returns the above...
If I just want part of what it returns, how do I go about writing this? I was able to return id without issue, and if I specified 'payload' it returned everything after that. It seems like account_title, phone_num, security_pin, remote_word, email_address and password are all nested inside of 'payload'
Would would the best way be to have a variable, when printed, return just the email_address for example?
Thanks!

Welcome to Python! Sounds like you're getting right into it. It would be best to begin reading fundamentals, specifically about the Dictionary Data Structure
The Dictionary, or dict is what you are referencing in your question. It's a key-value store that is generally[1] un-ordered. The dict is a great way to represent JSON data.
Now you are asking how to extract information from a dictionary. Well, you seem to have it working out thus far! Let's use your example:
d = {u'id': u'000123', u'payload': u"{'account_title': u’sam b’, 'phone_num': ‘1234567890’, 'security_pin': u'000000', 'remote_word': u’secret123’, 'email_address': ‘email#gmail.com’, 'password': u’password123’}"}
Now if we write d['id'], we'll get the id (which is 000123)
If we write d['payload'], we'll get the dictionary within this larger dictionary. Cool part about dicts, they can be nested like this! As many times as you need.
d['payload']
"{'account_title': u’sam b’, 'phone_num': ‘1234567890’, 'security_pin': u'000000', 'remote_word': u’secret123’, 'email_address': ‘email#gmail.com’, 'password': u’password123’}"
Then as per your question, if you wanted to get email, it's the same syntax and you're just nesting the accessor. Like so:
d['payload']['email_address']
Hope that helps!
For the longest time, dicts were un-ordered in Python. In versions 3.6 and up, things began changing. This answer provides great detail on that. Otherwise, prior to that, using collections.OrderedDict was the only way to get a dict ordered by insertion-order

Related

Firebase Realtime Database - cannot read document as json/dictionary

In my realtime database I have a path /stats which contains a set of documents.
I want to using the python sdk get the /stats document as a dict. My code looks like that
path = "/stats"
ref = db.reference(path, firebase_app)
document = ref.get()
print(document)
And the output is
[None, {'name': 'Full Time Statistics', 'thumbnail': 'https://***', 'url': 'https://***'}]
which is a list not a dictionary. How to change it and read this document path as a dictionary something like that
{"1": {'name': 'Full Time Statistics', 'thumbnail': 'https://***', 'url': 'https://***'}}
On the other hand I can get other documents with similar structures as a dictionary with no issue. Why is it like that and how to solve it ?
Two things are happening here:
Since you are retrieving /stats you are getting all nodes under it. Since this is a repeated list and Firebase Realtime Database keys are strings, you'd normally get a dictionary (with the keys in the dictionary being the keys in the JSON).
Since your keys are numeric values, Firebase "thinks" you are trying to store an array/list and it tries to coerce the data into an array for you. That's why you get a None entry in the list: that's Firebase filling in the zeroth element for you.
There's unfortunately no way to disable this array coercion. I typically get around it by prefixing the keys with a fixed string, so that Firebase bypasses its array logic. So:
stats: {
stat1: { ... },
stat2: { ... }
}
Also see:
Best Practices: Arrays in Firebase

Extracting data using python from the steam api formatted in JSON

I want to get the name and percent data from the json string...
{'achievementpercentages': {'achievements': [{'name': 'camp_bonus_01_stalingrad_rail_german_engineering', 'percent': 42}, {'name': 'count_camp_1', 'percent': 41.5}
Ive been trying to do this using something like...
for achievementpercentages in repos:
print(achievementpercentages['name'])
print(achievementpercentages['percent'])
but this returns the error...
TypeError: string indices must be integers
That's not a valid json string but that doesn't mean you can't use it. The issue you're having is explained by the error. Your loop isn't saying what you want to do based on the structure of your dictionary. If your repo variable is filled with a list of many rows(dicts) that look like your example line then your code needs to be:
for row in repo:
for achievement in row['achievementpercentages']['achievements']:
print achievement['name']
print achievement['percent']
It's a little unclear what repos is... if repos is your entire string you pasted it needs to be:
for achievemnt in repo['achievementpercentages']['achievements']:
print achievement['name']
print achievement['percent']`

Representation of python dictionaries with unicode in database queries

I have a problem that I would like to know how to efficiently tackle.
I have data that is JSON-formatted (used with dumps / loads) and contains unicode.
This is part of a protocol implemented with JSON to send messages. So messages will be sent as strings and then loaded into python dictionaries. This means that the representation, as a python dictionary, afterwards will look something like:
{u"mykey": u"myVal"}
It is no problem in itself for the system to handle such structures, but the thing happens when I'm going to make a database query to store this structure.
I'm using pyOrient towards OrientDB. The command ends up something like:
"CREATE VERTEX TestVertex SET data = {u'mykey': u'myVal'}"
Which will end up in the data field getting the following values in OrientDB:
{'_NOT_PARSED_': '_NOT_PARSED_'}
I'm assuming this problem relates to other cases as well when you wish to make a query or somehow represent a data object containing unicode.
How could I efficiently get a representation of this data, of arbitrary depth, to be able to use it in a query?
To clarify even more, this is the string the db expects:
"CREATE VERTEX TestVertex SET data = {'mykey': 'myVal'}"
If I'm simply stating the wrong problem/question and should handle it some other way, I'm very much open to suggestions. But what I want to achieve is to have an efficient way to use python2.7 to build a db-query towards orientdb (using pyorient) that specifies an arbitrary data structure. The data property being set is of the OrientDB type EMBEDDEDMAP.
Any help greatly appreciated.
EDIT1:
More explicitly stating that the first code block shows the object as a dict AFTER being dumped / loaded with json to avoid confusion.
Dargolith:
ok based on your last response it seems you are simply looking for code that will dump python expression in a way that you can control how unicode and other data types print. Here is a very simply function that provides this control. There are ways to make this function more efficient (for example, by using a string buffer rather than doing all of the recursive string concatenation happening here). Still this is a very simple function, and as it stands its execution is probably still dominated by your DB lookup.
As you can see in each of the 'if' statements, you have full control of how each data type prints.
def expr_to_str(thing):
if hasattr(thing, 'keys'):
pairs = ['%s:%s' % (expr_to_str(k),expr_to_str(v)) for k,v in thing.iteritems()]
return '{%s}' % ', '.join(pairs)
if hasattr(thing, '__setslice__'):
parts = [expr_to_str(ele) for ele in thing]
return '[%s]' % (', '.join(parts),)
if isinstance(thing, basestring):
return "'%s'" % (str(thing),)
return str(thing)
print "dumped: %s" % expr_to_str({'one': 33, 'two': [u'unicode', 'just a str', 44.44, {'hash': 'here'}]})
outputs:
dumped: {'two':['unicode', 'just a str', 44.44, {'hash':'here'}], 'one':33}
I went on to use json.dumps() as sobolevn suggested in the comment. I didn't think of that one at first since I wasn't really using json in the driver. It turned out however that json.dumps() provided exactly the formats I needed on all the data types I use. Some examples:
>>> json.dumps('test')
'"test"'
>>> json.dumps(['test1', 'test2'])
'["test1", "test2"]'
>>> json.dumps([u'test1', u'test2'])
'["test1", "test2"]'
>>> json.dumps({u'key1': u'val1', u'key2': [u'val21', 'val22', 1]})
'{"key2": ["val21", "val22", 1], "key1": "val1"}'
If you need to take more control of the format, quotes or other things regarding this conversion, see the reply by Dan Oblinger.

how to parse a list to get a value

I need some ideas on how to parse a list and print a specific value,Lets say I want to parse dependsontext and then just print the number "249452",please suggest ideas
INPUT:-
dependsontext = [{u'isCurrentPatchSet': True, u'revision': u'ad0beef66e5890cde6f0961ed03d8bc7e3defc63', u'ref': u'refs/changes/52/249452/1', u'id': u'Iad0beef66e5890cde6f0961ed03d8bc7e3defc63', u'number': u'249452'}]
OUTPUT:-
249452
since you used the python tag, it looks like you want
dependsontext[0]['number']
dependsontext is a one-element list of dictionaries, so you can get the first element with [0]
Then you can retrieve a value from that dictionary with a key, like ['number']
Your question is a bit unclear though - it's hard to tell if you're using python data structures or strings. If it's the latter, I'd recommend looking at the simplejson module for json parsing.

How can I change urlencode to python dictionary

I have got data from POST like
first_name=jon&nick_name=harry
How can I change this to a python dictionary, like :
{
"first_name":"jon",
"nick_name":"harry"
}
>>> urlparse.parse_qs("first_name=jon&nick_name=harry")
{'nick_name': ['harry'], 'first_name': ['jon']}
If you trust that the URL arguments will always be properly formatted, this would be a minimal solution:
dict(pair.split("=") for pair in urlargs.split("&"))
In code that's going to be publicly accessible though, you'll probably want to use a library that does error checking. If you're using Django, you'll probably have access to them already in the dictionary-like object HttpRequest.POST.

Categories

Resources