tastewaffle
tastewaffle

Reputation: 11

Send The Portion Of The Server ID Next To It

When I use the test command, I'd like to access the value that's being stored in the dictionary:

enter image description here

However, I keep getting this error:

discord.ext.commands.errors.CommandInvokeError: Command raised an exception: KeyError: '714235745140736080'

Here is my code:

def test1(client, message):
    with open('test.json', "r") as f:
        test = json.load(f)
    return (test[str(message.guild.id)])



@client.command()
async def test(ctx):
    with open('test.json', 'r') as f:
        test = json.load(f)
        test1 = (test[str(ctx.guild.id)])

        await ctx.send(f"{test1}")

Upvotes: 1

Views: 47

Answers (1)

Diggy.
Diggy.

Reputation: 6944

JSON files work similarly to dictionaries in Python. When you create a dictionary with keys and values, you're able to save it to the .json. These values are then able to be accessed when loading the file in, exactly as you would access a dictionary normally:

# Creating a dictionary with some arbitrary values
>>> data = {"foo": "bar", "key": "value"}

# Opening a file and writing to it
>>> with open("db.json", "w+") as fp:
...     json.dump(data, fp, sort_keys=True, indent=4) # Kwargs for beautification

# Loading in data from a file
>>> with open("db.json", "r") as fp:
...     data = json.load(fp)

# Accessing the values
>>> data["foo"]
'bar'
>>> data["key"]
'value'

With that out of the way, we can move onto your problem.


First off, I'd recommend choosing more sensible names for functions and variables. This will help to avoid namespace pollution.

Here's an example of some working code with better names:

# Adding a default paramter type will mean that you won't need to convert throughout the function
def get_data(guild_id: str):
    with open("guilds.json", "r") as f:
        data = json.load(f)
    return data[guild_id]

@client.command()
async def cmd(ctx):
    value = get_data(ctx.guild.id)
    await ctx.send(f"{value}")

One thing to note was that you weren't actually making use of the function you defined. You just rewrote its code later on in the script. The point of a function is to prevent you from repeating code like this. You want to call the function (e.g. my_func()) in order to do something with it.


I'm guessing you already have a method of writing/updating values to the file. If not, then there should be enough information in this answer to do so.

You'll get a KeyError when you try to access a key in a dictionary that doesn't exist. For this reason, I'd maybe recommend looking into an on_guild_join() event as to update the file when the bot joins a new guild.

I believe what caused the error in your case was trying to access the value of a key whose type was actually str and not an int - they are completely different. Consider the following:

>>> data = {"123": "value"}
>>> data[123] # This will throw a KeyError

>>> data["123"] # This will return the value
'value'

References:

Upvotes: 1

Related Questions