2

I'm trying to interpret data from the Twitch API with Python. This is my code:

from twitch.api import v3
import json

streams = v3.streams.all(limit=1)
list = json.loads(streams) 
print(list) 

Then, when running, I get:

TypeError, "the JSON object must be str, not 'dict'"

Any ideas? Also, is this a method in which I would actually want to use data from an API?

6
  • Try printing streams. It is likely that it has already been JSON parsed. Commented Mar 10, 2016 at 22:09
  • 2
    Aside: one ought not use list (or the name of any other built-in function) as a variable name. Subsequent code cannot invoke list() anymore and expect the standard result. Commented Mar 10, 2016 at 22:10
  • @DanD. Ah yes, so printing streams does work. Now, how would I take parts of this data and use it? Commented Mar 10, 2016 at 22:11
  • @Karrigan: Like literally any other dict. Look up keys in it, iterate it to get keys, call .items() on it to get key/value pairs, whatever. Commented Mar 10, 2016 at 22:12
  • @ShadowRanger Excellent, thank you. Sorry for my lack of knowledge. Commented Mar 10, 2016 at 22:14

2 Answers 2

1

Per the documentation json.loads() will parse a string into a json hierarchy (which is often a dict). Therefore, if you don't pass a string to it, it will fail.

json.loads(s, encoding=None, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw) Deserialize s (a str instance containing a JSON document) to a Python object using this conversion table.

The other arguments have the same meaning as in load(), except encoding which is ignored and deprecated.

If the data being deserialized is not a valid JSON document, a JSONDecodeError will be raised.

From the Twitch API we see that the object being returned by all() is a V3Query. Looking at the source and documentation for that, we see it is meant to return a list. Thus, you should treat that as a list rather than a string that needs to be decoded.

Specifically, the V3Query is a subclass of ApiQuery, in turn a subclass of JsonQuery. That class explicitly runs the query and passes a function over the results, get_json. That source explicitly calls json.loads()... so you don't need to! Remember: never be afraid to dig through the source.

Sign up to request clarification or add additional context in comments.

6 Comments

That's just saying it failed because it failed. In fact, the api is already doing the decode so you don't have to do it again.
No, that's saying it failed because the type being passed to the function is incorrect. Which is the cause of the cited error.
OP's problem is that he didn't realize that the JSON had already been decoded to python.
I think you're splitting hairs, but in terms of understanding why he got the TypeError it's important to determine what might throw it, understand what it expects and what it will return. We confirm that the input is bad by understanding that loads expects a string, and thinks it's getting a dict.
You say splitting hairs but then you changed your answer to include a description of what went wrong. That's what I meant.
|
0

after streams = v3.streams.all(limit=1) try using streams = json.dumps(streams)

As the streams should be a JSON string and be in the form: '{"key":value}' instead of just dict form: {"key":value}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.