Skip to content
Advertisement

Can’t open and write a file twice in a command in discord.py

I want to open a json file, to safe things in there and after a few seconds I want to delete that again. I asked already in dpy support. They said, I can’t open a file in write mode. But how can I open the file anyway? Or how can I get out of this write mode?

I tried this:

@bot.command()
@commands.has_permissions(administrator=True)
async def knastmute(ctx, member: discord.Member = None, arg1= None, *, arg2=None):
    guild = bot.get_guild(597135532111167622)
    knastmute = get(guild.roles, id=696100186149224545)
    Knast = 686657535427739804

    guildemojisbtv = bot.get_guild(712671329123303504)
    Epositiv = get(guildemojisbtv.emojis, id=712679512873369610)
    Eerror = get(guildemojisbtv.emojis, id=713187214586282054)

    if member:
        if any(role.id == Knast for role in member.roles):
                    if arg1 == '1m':

                        with open(r'./knastmuteusers.json', 'r')as f:
                            users = json.load(f)
                        if not f"{member.id}" in users:
                            users[member.id] = f"{member}: {arg1}"
                            with open(r"./knastmuteusers.json", 'w') as f:
                                json.dump(users, f, indent=4)

                                await member.add_roles(knastmute)

                                await asyncio.sleep(5)

                                with open(r'./knastmuteusers.json', 'r')as f:
                                    users = json.load(f)
                                    del users[member.id]

                                    with open(r"./knastmuteusers.json", 'w') as f:
                                        json.dump(users, f, indent=4)

                                        await member.remove_roles(knastmute)

I get this error:

I get this error:
    ```Ignoring exception in command knastmute:
Traceback (most recent call last):
  File "C:UsersuserAppDataLocalProgramsPythonPython37libsite-packagesdiscordextcommandscore.py", line 83, in wrapped
    ret = await coro(*args, **kwargs)
  File "F:DiscordBotPyCharmblacktv.py", line 2327, in knastmute
    users = json.load(f)
  File "C:UsersuserAppDataLocalProgramsPythonPython37libjson__init__.py", line 296, in load
    parse_constant=parse_constant, object_pairs_hook=object_pairs_hook, **kw)
  File "C:UsersuserAppDataLocalProgramsPythonPython37libjson__init__.py", line 348, in loads
    return _default_decoder.decode(s)
  File "C:UsersuserAppDataLocalProgramsPythonPython37libjsondecoder.py", line 337, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "C:UsersuserAppDataLocalProgramsPythonPython37libjsondecoder.py", line 355, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "C:UsersuserAppDataLocalProgramsPythonPython37libsite-packagesdiscordextcommandsbot.py", line 892, in invoke
    await ctx.command.invoke(ctx)
  File "C:UsersuserAppDataLocalProgramsPythonPython37libsite-packagesdiscordextcommandscore.py", line 797, in invoke
    await injected(*ctx.args, **ctx.kwargs)
  File "C:UsersuserAppDataLocalProgramsPythonPython37libsite-packagesdiscordextcommandscore.py", line 92, in wrapped
    raise CommandInvokeError(exc) from exc
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: JSONDecodeError: Expecting value: line 1 column 1 (char 0)

Advertisement

Answer

What’s happening there is you’re trying to open the file while it’s still open. Unindenting from the context manager automatically closes the file.

The error itself is stating that the file is malformed and most likely looks like this:

{

That’ll happen if you don’t write data in a valid format to the .json.


Here’s an example command with reading/writing to a file multiple times:

import os # necessary if you wish to check the file exists

@bot.command()
async def cmd(ctx):
    if os.path.isfile("file.json"):
        with open("file.json", "r") as fp:
            data = json.load(fp) # loads the file contents into a dict with name data
        data["users"].append(ctx.author.id) # add author's id to a list with key 'users'
    else: # creating dict for json file if the file doesn't exist
        data = {
            "users": []
        }
        data["users"].append(ctx.author.id)

    # outside of if statement as we're writing to the file no matter what
    with open("file.json", "w+") as fp:
        json.dump(data, fp, sort_keys=True, indent=4) # kwargs are for formatting

    print(data) # you're still able to access the dict after closing the file
    await ctx.send("Successfully updated a file!")

References:

User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement