plerpsandplerps
plerpsandplerps

Reputation: 181

Fix keys must be str, int, float, bool or None, not Snowflake error

I am trying to write a list of users from a discord server into a json using python, but I keep receiving this error.

enter image description here

Ideally I want to turn my dict {Snowflake(USERID#): Member(user=User(id=Snowflake(USERID#), username='USERNAME', discriminator='#', bot=None), nick=None),

Into a JSON file only containing the bot=none users in a format like this:

{
    "USERID#1": {
        "Username": "USERNAME1"
  },
 "USERID#2": {
        "Username": "USERNAME2"
  },
...
}

Edit:

  1. Error text is TypeError: keys must be str, int, float, bool or None, not Snowflake
  2. My code to initially pull the data into the dict and attempt to write it to the json is:
    import interactions
    from interactions import Button, ButtonStyle, SelectMenu, SelectOption, ActionRow, spread_to_rows
    import json

    memberslist = await guild.get_all_members()
    print(memberslist)
    membersdict = {Member.id: Member for Member in memberslist}
    with open("playersbackup.json","w") as n:
      json.dump(membersdict,n, indent=4)

Upvotes: 0

Views: 1252

Answers (2)

Achxy_
Achxy_

Reputation: 1201

I wrote this sample bot which produced the json dumps you are looking for:

from discord import Intents, Member, Guild
from discord.ext import commands
from os import environ
import json


class StackOverFlowAnswer(commands.Bot):
    def convert_member_to_dict(self, member: Member) -> dict:
        return {
            "user": member.id,
            "username": member.name,
            "discriminator": member.discriminator,
            "nick": member.nick,
        }

    def get_member_backup(self, guild: Guild) -> str:
        to_dict = self.convert_member_to_dict
        data = {user.id: to_dict(user) for user in filter(lambda member: not member.bot, guild.members)}
        return json.dumps(data, indent=4)

    def dump_data(self, data: str, filename: str = "players.json") -> None:
        with open(filename, "w") as file:
            file.write(data)


# Code beyond this point is for demonstrational purposes
# The above code produced the json structure that you desired




bot = StackOverFlowAnswer(command_prefix="?", intents=Intents.all())


@bot.command(aliases=["dump"])
async def _dump(ctx: commands.Context):
    assert ctx.guild is not None
    backup = bot.get_member_backup(ctx.guild)
    bot.dump_data(backup)
    await ctx.send(f"Wrote:\n{backup}")


bot.run(environ["DISCORD_TOKEN"])

The command output: command output

Furthermore, here is the JSON file that was created: json output

Hope that helps.

Upvotes: 1

Nima.sa
Nima.sa

Reputation: 13

It seems that Member.id is neither of the suggested data types. If the key is a custom data type, it should conform to hashable.

Implement def __hash__(self): and def __eq__(self,other): for the Member.id data type to see if it helps.

i.e.:

def __hash__(self):
    return hash(str(self.id_num))

def __eq__(self, other):
    return self.id_num == other.id_num

Upvotes: 0

Related Questions