KeyError: u'somestring' Json - python

I am trying to make a point system for my Twitch bot and I am encountering KeyErrors when trying to make a new entry for some odd reason. Here is my code:
import urllib2, json
def updateUsers(chan):
j = urllib2.urlopen('http://tmi.twitch.tv/group/user/' + chan + '/chatters')
j_obj = json.load(j)
with open('dat.dat', 'r') as data_file:
data = json.load(data_file)
for usr in j_obj['chatters']['viewers']:
data[usr]['Points'] = "0" # Were the KeyError: u'someguysusername' occurs
with open('dat.dat', 'w') as out_file:
json.dump(data, out_file)
updateUsers('tryhard_clan')
If you want to see the Json itself go to http://tmi.twitch.tv/group/user/tryhard_clan/chatters
I'm storing user data in a file in this format:
{"users": {"cupcake": {"Points": "0"}}}

a slightly more concise form than #Raunak suggested:
data.setdefault (usr, {}) ['Points'] = "0"
that will set data[usr] to an empty dict if it's not already there, and set the 'Points' element in any case.

It happens variable usr doesn't resolve to an existing key in data. Do this instead:
if usr not in data:
data[usr] = {}
data[usr]['Points'] = "0"

Related

Tweepy, how to pull count integer and use it

I trust all is well with everyone here. My apologies if this has been answered before, though I am trying to do the following.
cursor = tweepy.Cursor(
api.search_tweets,
q = '"Hello"',
lang = 'en',
result_type = 'recent',
count = 2
)
I want to match the number in count, to the number of json objects I will be iterating through.
for tweet in cursor.items():
tweet_payload = json.dumps(tweet._json,indent=4, sort_keys=True)
I have tried several different ways to write the data, though it would appear that the following does not work (currently is a single fire):
with open("Tweet_Payload.json", "w") as outfile:
outfile.write(tweet_payload)
time.sleep(.25)
outfile.close()
This is what it looks like put together.
import time
import tweepy
from tweepy import cursor
import Auth_Codes
import json
twitter_auth_keys = {
"consumer_key" : Auth_Codes.consumer_key,
"consumer_secret" : Auth_Codes.consumer_secret,
"access_token" : Auth_Codes.access_token,
"access_token_secret" : Auth_Codes.access_token_secret
}
auth = tweepy.OAuthHandler(
twitter_auth_keys["consumer_key"],
twitter_auth_keys["consumer_secret"]
)
auth.set_access_token(
twitter_auth_keys["access_token"],
twitter_auth_keys["access_token_secret"]
)
api = tweepy.API(auth)
cursor = tweepy.Cursor(
api.search_tweets,
q = '"Hello"',
lang = 'en',
result_type = 'recent',
count = 2
)
for tweet in cursor.items():
tweet_payload = json.dumps(tweet._json,indent=4, sort_keys=True)
with open("Tweet_Payload.json", "w") as outfile:
outfile.write(tweet_payload)
time.sleep(.25)
outfile.close()
Edit:
Using the suggestion by Mickael
also, the current code
tweet_payload = []
for tweet in cursor.items():
tweet_payload.append(tweet._json)
print(json.dumps(tweet_payload, indent=4,sort_keys=True))
with open("Tweet_Payload.json", "w") as outfile:
outfile.write(json.dumps(tweet_payload,indent=4, sort_keys=True))
time.sleep(.25)
Just loops, I am not sure why thats the case when the count is 10. I thought it would run just 1 call for 10 results or less, then end.
Opening the file with the write mode erases its previous data so, if you want to add each new tweet to the file, you should use the append mode instead.
As an alternative, you could also store all the tweets' json in a list and write them all at once. That should be more efficient and the list at the root of your json file will make it valid.
json_tweets = []
for tweet in cursor.items():
json_tweets.append(tweet._json)
with open("Tweet_Payload.json", "w") as outfile:
outfile.write(json.dumps(json_tweets,indent=4, sort_keys=True))
On a side note, the with closes the file automatically, you don't need to do it.

How to dump data into Json file using python

How to dump data into Json file
*as can see in the below python code I am trying the dump data in Json file so but I am struggling to do it in python code *
import time
import json
import os
def long_function(name):
cache_path = 'cache.json'
if not os.path.isfile(cache_path):
with open(cache_path, 't') as json_file:
cache_file_data = [name]
jsondump(cache_file_data, json_file)
else:
with open(cache_path, 'r') as json_file:
cache_file_data = json.load(json_file)
if name in cache_file_data:
print("Name already exist")
return name
else:
cache_file_data.append(name)
for e in range(5):
time.sleep(1)
print(e+1)
with open(cache_path, 'w') as json_file:
jsondump(cache_file_data, json_file)
print("New Name added in cache")
return name
print(long_function('nitu'))
so please resolve my problem......please help me
import json
# JSON data:
x = '{ "organization":"New_holn",
"city":"Noida",
"country":"India"}'
# python object to be appended
y = {"pin":117845}
# parsing JSON string:
z = json.loads(x)
# appending the data
z.update(y)
# the result is a JSON string:
print(json.dumps(z))
This is nothing but follow this pattern and your so your code error is ..you are not defined file mode correctly in if condition
with open (cache_path. "t") as json_file:
Instead of
with open (cache_path. "w") as json_file:
And second thing is you are not doing dump data

Delete key/value from a dictionary Json

In a simple Telegram bot with Telebot I have a dictionary in json format (parole.json). I'm trying a function that allows me to delete an entry (key value pair) from the dictionary and I used this code example found right on this forum:
import json
with open("parole.json", "r") as json_file:
Dizio = json.load(json_file)
#bot.message_handler(commands=['cut'])
def removeKey(message):
parola = extract_arg(message.text.lower())
res = Dizio.get(message.text.lower(), parola)
trova = str(parola)
with open("parole.json", "r") as f:
data = json.load(f)
if trova in data:
del data[trova]
with open("parole.json", "w") as f:
json.dump(data, f)
Have you read this question? It's basically the same question and the answer is already given.
You need to iterate over the keys by using a for loop that checks if the input == ['key']['value']
Also, your indenting is incorrect in your removekey(message) function:
def removeKey(message):
parola = extract_arg(message.text.lower())
res = Dizio.get(message.text.lower(), parola)
trova = str(parola)
with open("parole.json", "r") as f:
data = json.load(f)
if trova in data:
del data[trova]
with open("parole.json", "w") as f:
json.dump(data, f)
Edit: I see that the indentation was edited just now
if trova in data:
del data[trova]
Calling dict.__del__ removes the key/value pair, so if your file is unchanged it's because the flow never enters the if statement.
Maybe it would work with
if trova in data.keys():
but I'm not sure if it makes any difference.

python error while looping from a list json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

I'm making a script that fills a text document with responses from an api. The api is being asked to convert usernames from a list to universally unique identifiers. I keep getting this error and can't find a way around it. "json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)"
Sample of accounts.txt
knapplace
Coppinator
tynow
Pman59
ButterMusty
FlyHighGuy13
Seyashi
fluzzygirl1
SquidMan55
leonrules9
BarthGimble
MTR_30
Darkshadow402
Deathmyster
Team_Everlook
Sheathok
KCFrost
mendog
Allfaal117
theLP25D
Zimyx
Blurrnis
redboy678
moose_breeder
kaser12345
import requests
import json
file1 = open('accounts.txt', 'r')
usernames = []
for line in file1:
stripped_line = line.strip()
usernames.append(stripped_line)
file1.close()
for x in usernames:
username = str(x)
url = ("https://api.mojang.com/users/profiles/minecraft/"+username+"?at=1462770000")
y = requests.get(url)
y_data = y.json()
uuid = y_data['id']
uuids = []
uuids.append(uuid)
file2 = open('uuids.txt', 'w')
file2.writelines(uuids)
file2.close()
file2 = open('uuids.txt', 'r')
lines = file2.readlines()
Note: #Ali makes a great point about checking for an empty reply. With that fix it works like a champ for me with a few other minor changes:
Used usernames provided by OP instead of reading them in from a file.
Moved initialization of uuids out of for loop to avoid it being reset for each username.
Modfied file i/o stuff to what I am more used to working with. ;^)
import requests
import json
usernames = [
"knapplace",
"Coppinator",
"tynow",
]
uuids = []
for x in usernames:
username = str(x)
url = ("https://api.mojang.com/users/profiles/minecraft/"+username+"?at=1462770000")
y = requests.get(url)
if len(y.content) == 0:
continue # Skip processing this username
y_data = y.json()
uuid = y_data['id']
uuids.append(uuid)
with open('uuids.txt', 'w') as f:
for uuid in uuids:
f.write(uuid + '\n')
with open('uuids.txt', 'r') as f:
read_data = f.read()
print(read_data)
Output:
c9998bafea3146d5935f4e215b6b4351
5c321f81409847a0907c4b30c342217f
9f206def69bf407fbab6de7c9b70ff80
I checked the URL you pasted. If the user does not exist, the API does not return any content but still returns a successful status. That is what the error means — it expected there to be a JSON object starting at char 0.
Essentially, you need to handle the case when the response is empty before you try to execute a y.json() by checking y.content. If y.content is empty, skip processing the current username and go to the next one.
y = requests.get(url)
if len(y.content) == 0:
continue # Skip processing this username
# The rest of the code only runs if y.content is not empty.
y_data = y.json()
uuid = y_data['id']

how do I add a string to a json value in python 3

So I'm trying to setup json so i can store data in-between user sessions I like a name but i don't know how to add or change a specific value in an external json file like for example {"name": ""} how do i fill that "" for the json file using python?
I have already tried to use dumps and all the tutorials use dumps
the json in another file
{
"human_name": "",
"oracle_name": "",
"human_age": "",
"human_gender": "",
"oracle_gender": ""
}
the python
import json
with open('data.json', '+') as filedata:
data = filedata.read()
used_data = json.loads(data)
if str(used_data(['human_name'])) == "":
print("what is your name")
name = input()
json.dumps(name)
if str(used_data(['oracle_name'])) == "":
print("what is my name")
oracle_name = input()
json.dumps(oracle_name)
print(str(['human_name']))
The expected result is when I print the data it displays input, but when i run it it goes
File "rember.py", line 3, in
with open('data.json', '+') as filedata: ValueError: Must have exactly one of create/read/write/append mode and at most one plus
Try this code.
json.loads loads the entire json string as a python dict object. The values in a dict are changed/added using dict[key] = value. You can't call a dict object to change its value.
The json.dumps method serializes an object to a JSON formatted str. Which you can then write into the same file or a different file based on your requirement.
import json
with open('data.json', 'r') as filedata:
data = filedata.read()
used_data = json.loads(data)
if used_data['human_name'] == "":
print("what is your name")
name = input()
used_data['human_name'] = name
if used_data['oracle_name'] == "":
print("what is my name")
oracle_name = input()
used_data['oracle_name'] = oracle_name
print(used_data)
with open('data.json', 'w') as filewrite:
filewrite.write(json.dumps(used_data, indent=4))
Basically what you need to do is load json file as dictionary, add value, and save it.
import json
with open('./data.json', 'r') as f:
d = json.load(f)
d['human_name'] = 'steve'
d['oracle_name'] = 'maria'
with open('./data.json', 'w') as f:
json.dump(d, f, indent=4)

Categories

Resources