adding new dict to json output python - python

Very new to json so please forgive if I am using the wrong terms here. Any ways I am trying to create a json file every x minutes with updated twitter info. Now I know i could just use the twitter api and grab what I need but I am wanting to mess around a bit. My problem is getting a new key/dict? or what ever it is called for each new item added in a for statement.
What im trying to get
[
{
"name": "thename",
"date": "thedate",
"text": "thetext"
}, <--- trying to get that little comma
{
"name": "thename",
"date": "thedate",
"text": "thetext"
}
]
Now i am getting the data that i want and all but not that comma. It outputs it all but not like it should be with that little one character thing that makes it valid.
[
{
"name": "thename",
"date": "thedate",
"text": "thetext"
} <--- I get this instead for each new object
{
"name": "thename",
"date": "thedate",
"text": "thetext"
}
]
Here is just a snippet of the code as the rest should be explanatory since its just Twitter oauth stuff.
for player in users:
statuses = api.GetUserTimeline(screen_name=player, count=10)
print "["
for s in statuses:
print json.dumps('timestamp': s.created_at,'username': s.user.name,'status': s.text)
print "]"
Also is there a better way to do the [ ] at the start and end because I know that is ugly and way un-proper i bet XD . Like I said newbie on json/python stuff but its a good learning experience.

Instead of trying to build the JSON array yourself, you should just let the JSON encoder do that for you too. To do that, you just need to pass a list of objects to json.dumps. So instead of printing each JSON object on its own, just collect them in a list, and dump that:
allstatuses = []
for player in users:
statuses = api.GetUserTimeline(screen_name=player, count=10)
for s in statuses:
allstatuses.append({'timestamp': s.created_at, 'username': s.user.name, 'status': s.text})
print(json.dumps(allstatuses))

Related

Extract specific JSON field from Twitter streaming API using Python

I am using Twitter's streaming API code (found here). I am able to get my desired output which is a series of filtered results. However, I specifically need to assign the 'text' field from the JSON result to a variable and I am unable to come up with the right way to do it.
I have isolated the part of the code that returns the streaming data and display it in the terminal when I run it:
for response_line in response.iter_lines():
if response_line:
json_response = json.loads(response_line)
print(json.dumps(json_response, indent=4, sort_keys=True))
What I need is to just get the text part of the tweet that is returned. Here's an output example, noting I only need to set a variable - twitterVariable to the "text" result:
{
"data": {
"id": "125855555555",
"text": "hello this is a test"
},
"matching_rules": [
{
"id": 1234567890,
"tag": ""
}
]
}
As you have already loaded the response into dict object of python, you can use key to get the text field as below:
twitter_variable = json_response['data']['text']

Trouble in comparison JSON with Python

I have to implement a web service using Flask and MongoDB. I have two collections. The JSON files are shown below:
File products.json:
{ "name":"red apples", "price":0.5, "description":"Apples from Greece", "category":"fruits", "stock":25 }
{ "name":"fish", "price":5, "description":"Fresh fish", "category":"fish", "stock":25 }
{ "name":"pasta", "price":1.5, "description":"Pasta from Italia", "category":"pasta", "stock":25 }
File users.json:
{"name":"George Vaios", "password":"321", "email":"george#gmail.gr", "category":"admin"}
{"name":"Admin", "password":"admin", "email":"admin#gmail.gr", "category":"admin"}
What I'm trying to do?
I'm trying to implement a function called add_product. This function allows users whose category is admin ("category": "admin"). As a route has a POST method because I'm parsing the email of a user and the details are needed to import a new product in products.json.
Code:
(lines of code for loading data)
user = users.find_one({"email":data['email']})
if (user['category']=="admin"):
product = {
"name": data['name'],
"price": data['price'],
"description": data['description'],
"category": data['category'],
"stock": data['stock']
}
products.insert_one(product)
return Response("Product was added succesfully", status=200, mimetype='application/json')
else:
return Response("Account has no permission. Must be an admin", status=400, mimetype='application/json')
With that code I'm trying to check if the user is an admin by finding him in the JSON file using the find_one method and then compare the user['category'] with the string 'admin'.
Data that I'm parsing to postman:
{
"email": "george#gmail.gr",
"name": "chocolate",
"price": 25,
"description": "mklkgj",
"category": "sweets",
"stock": 30
}
Error that I get:
File "/home/michael/main.py", line 241, in add_product_admin
if (user['category']=="admin"):
TypeError: 'NoneType' object is not subscriptable
I can't understand why the if statement doesn't make the comparison. Any thoughts?
Mongo is telling you that nothing came up when searching for that value. I would start by checking if data['email'] has the value you would expect and if your collection is initialized correctly.
Thanks to everyone who explained to me what's going on. The actual problem was on MongoDB and client parameters on Python script. That's why the entries and JSON files were unreadable. If anyone comes up again with this problem be sure that you have checked:
# Choose database
database = client['database you want to access']
Then don't forget to check with mongo shell if your expected collections exist:
db.(your database name).find({})
Thank you for your time!

How to remove <adinsight> sting from json object from facebook insight API Python

I am making api call via python sdk to get facebook insights dat and I am getting the following response from API. I would like to remove from response json object. can you please guide me how to do this? I have tried to serialize it by .dumps() but it does not serialize.
[
{
"account_id": "123"
},
{
"account_id": "123"
},
{
"account_id": "123"
}
]
I'm pretty sure you can just cast the insights list into a Pandas Dataframe like:
insights_list = campaign.get_insights()
insights_df = pd.Dataframe(insights_list)
In this way you can have your metrics in the dataframe columns and it will improve the readability.

How to build Python Lambda for Alexa skill with sequence of statements?

I am building Alexa skill for my application. When your ask's 'what is my account status?' this intent return sequence of statements related to user's account. API gives following response
response = [{
..
text: 'Total orders are 41, Delivered 28'
..
},
{
..
text: 'Today orders are 12, Delivered 2'
..
},
{}]
How to build response sequence based on API response?
With this intent, I get the response from API with set statements Alexa should prompt each statement one by one. If the user said 'next' in between any of the statement while Alexa prompting then it goes to next statement in the response array.
First when user says "what is my account status?" your intent will be called and you will get response in a list where in the first call you will display 0th item.
API Result:
response = [{
..
text: 'Total orders are 41, Delivered 28'
..
},
{
..
text: 'Today orders are 12, Delivered 2'
..
},
{}]
You need to store information in Session attributes, like intent name, index which you displayed (0 in case of first call) etc.
Now you need to setup one more intent which will be triggered on keywords like next. In the code you will check values of session attributes and make your response according to the values. For example you would want to check previous intent name, previous index. If all is fine you will modify the session attributes and respond to user.
Hope it helps.
Since you mentioned Python, I would suggest to take a look at Flask-ask, which provides you with two main responses type: statement and question.
As sid8491 mentioned, you will need to store info in sessions to keep track of which response (from json) needs to be returned. You can use redis for this purpose, using this python library.
Assuming the json response is stored in db (or somewhere), and can be accessed in a list, let's say your interaction model looks something like this:
{
"languageModel": {
"intents": [
{
"name": "NextIntent",
"samples": ["next", "tell me more"]
},
{
"name": "StopIntent",
"samples": ["stop"]
},
{
"name": "StatusIntent",
"samples": ["what is my account status"]
}
],
"invocationName": "orders"
}
}
You can use following steps (using redis and flask-ask for this example):
on 'StatusIntent', store session and return first response:
redis.set("session_key", 0)
return statement(response[0]) # assuming responses are stored in a list
on 'NextIntent', get value stored in session, if present return next response
value = redis.get("session_key")
if not value: # session is expired
return statement("I don't understand")
redis.set("session_key", int(value)+1)
return statement(response[int(value)+1])
on 'StopIntent', remove "session_key" from redis
redis.delete("session_key")
return statement("Ok. I am here if you need me.")
It's not the actual code but simply intended to give you an idea. Hope it helps.
:)

Facebook API - Paging - limit of 270 items?

I've been playing around with the Facebook API for a bit now, and I think I got it working quite well, however, when fetching my friends list I bump into a limit of 270 (271?) items returned with a paging key in the json data.
Naturally I try to iterate threw the next page in the paging key, however, the array returned from the next page is empty, it contains a next and previous key but no actual data, anyone know what's wrong?
Tried it straight in the browser just to ignore all programming errors and it's the same there as it is in the code:
https://graph.facebook.com/me/friends?access_token=[ACCESS_TOKEN]&limit=5000
I've also tried with &offset=269 etc, nothing really works, here's the output:
{
"data": [
{
"name": "Person A",
"id": "..."
},
{
"name": "Person B",
"id": "..."
},
{
"name": "Person C",
"id": "..."
}
],
"paging": {
"next": "https://graph.facebook.com/me/friends?limit=5000&offset=5268&value=1&access_token=[ACCESS_TOKEN]&__after_id=[Person C ID]",
"previous": " Previous URL ... "
}
}
When trying this URL in the browser (or via code), I get this:
{
"data": [
],
"paging": {
"previous": "https://graph.facebook.com/me/friends?limit=5000&offset=268&value=1&access_token=[ACCESS_TOKEN]"
}
}
Why is this and how do you go about fixing it?
Appreciate all the help i can get, thank you!
Edit: I have 284 friends, so there should be 10+ on the "next" paging.
(Programming done in Python via the "Official Python SDK" (modified to handle paging)
Maybe it's cos you might only have 270 (271) friends? Unless you are sure you have more friends...
If you have more than 270 friends. There could be two other reasons:
Those 14 users have prevented apps from accessing their data via the API
Facebook has cached your friend's list and you need to wait for the cache to be updated.

Categories

Resources