Randomatically select from a json discord.py - json

I'm trying to create a command where a random meme is shown from a json.
Unfortunately I can't do it ... I can do it using random.choice normally but since I'm a lazy person to update the code I always created a command that would allow me to add them in a json. So I have to be able to randomly extract the main key of my json. How could I do?
code:
#client.command(aliases=["Meme","MEME"])
async def meme(ctx):
await ctx.message.delete()
meme_data_dict = meme_data.json
url = random.choice(list(meme_data_dict.keys))
print(url)
author = meme_data_dict[url]["autore"]
title = meme_data_dict[url]["titolo"]
channel = client.get_channel(638016878589116416)
if ctx.channel.id == channel.id:
embed = discord.Embed(
title=f'{title}',
color=0x003399
)
embed.set_author(name=f'fatto da {author}')
embed.set_footer(text=f'Richiesto da {ctx.author.name}')
embed.set_image(url=url)
await ctx.send(embed=embed)
else:
embed = discord.Embed(
color=0xa61022
)
embed.set_author(
name=f"Per questo comando devi usare {channel.name}!",
)
await ctx.send(embed=embed, delete_after=10.0)
return
Json (your name is meme_data.json):
{"https://cdn.discordapp.com/avatars/491769129318088714/f23fd300d377ab133db1d6ac7db5d10b.webp?size=1024": {"autore": "10", "titolo": "sesso pazzoide"}, "https://cdn.discordapp.com/attachments/638016878589116416/839977460384923659/soviet_soldier_2.jpg": {"autore": "pene", "titolo": "ciaociao"}}
This is how my json is active:
#client.event
async def on_ready():
global meme_data
try:
with open('meme_data.json') as f:
meme_data = json.load(f)
except FileNotFoundError:
print("Impossibile caricare meme_data.json")
meme_data = {}
error:
Ignoring exception in command meme:
Traceback (most recent call last):
File "C:\Users\PC GIUSEPPE\PycharmProjects\LMIIBot Development\venv\lib\site-packages\discord\ext\commands\core.py", line 85, in wrapped
ret = await coro(*args, **kwargs)
File "C:/Users/PC GIUSEPPE/PycharmProjects/LMIIBot Development/LMIIBot Development.py", line 2235, in meme
meme_data_dict = meme_data.json
AttributeError: 'dict' object has no attribute 'json'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "C:\Users\PC GIUSEPPE\PycharmProjects\LMIIBot Development\venv\lib\site-packages\discord\ext\commands\bot.py", line 903, in invoke
await ctx.command.invoke(ctx)
File "C:\Users\PC GIUSEPPE\PycharmProjects\LMIIBot Development\venv\lib\site-packages\discord\ext\commands\core.py", line 859, in invoke
await injected(*ctx.args, **ctx.kwargs)
File "C:\Users\PC GIUSEPPE\PycharmProjects\LMIIBot Development\venv\lib\site-packages\discord\ext\commands\core.py", line 94, in wrapped
raise CommandInvokeError(exc) from exc
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: AttributeError: 'dict' object has no attribute 'json'

To get a random object of a dictionary (imported json file), you use url = random.choice(list(meme_data_dict.keys)). That in your code would be:
#client.command(aliases=["Meme","MEME"])
async def meme(ctx):
await ctx.message.delete()
meme_data_dict = meme_data #you have to rename your variable meme, for example to meme_data, because there is already the function called meme
url = random.choice(list(meme_data_dict.keys()))
print(url)
author = meme_data_dict[url]["autore"]
title = meme_data_dict[url]["titolo"]
#the rest of your code can stay the same
If this doesn't answer your question, clarify more what the problem is.

Related

How to use marshmallow-sqlalchemy with async code?

I'm trying to use marshmallow-sqlalchemy with aiohttp and I have followed their docs with the basic example and I'm getting an error.
I have this schema:
from marshmallow_sqlalchemy import SQLAlchemyAutoSchema
from db.customer import Customer
class CustomerSchema(SQLAlchemyAutoSchema):
class Meta:
model = Customer
include_relationships = True
load_instance = True
And then the following code for the query:
from sqlalchemy import select
from db import db_conn
from db.customer import Customer
from queries.schema import CustomerSchema
customer_schema = CustomerSchema()
async def get_all_users():
async with db_conn.get_async_sa_session() as session:
statement = select(Customer)
results = await session.execute(statement)
_ = (results.scalars().all())
print(_)
response = customer_schema.dump(_, many=True)
print(response)
For the first print statement I'm getting
[<db.customer.Customer object at 0x10a183340>, <db.customer.Customer object at 0x10a183940>, <db.customer.Customer object at 0x10b0cd9d0>]
But then it fails with
File "/Users/ruslan/.local/share/virtualenvs/cft-RKlbQ9iX/lib/python3.9/site-packages/sqlalchemy/util/_concurrency_py3k.py", line 60, in await_only
raise exc.MissingGreenlet(
sqlalchemy.exc.MissingGreenlet: greenlet_spawn has not been called; can't call await_() here. Was IO attempted in an unexpected place? (Background on this error at: http://sqlalche.me/e/14/xd2s)
So how can I use marshmallow-sqlalchemy to serialize the SqlAlchemy reponse?
Another options (packages, etc) or a generic custom solutions are OK too.
For the time being I'm using this:
statement = select(Customer)
results = await session.execute(statement)
_ = (results.scalars().all())
response = {}
for result in _:
value = {k: (v if not isinstance(v, sqlalchemy.orm.state.InstanceState) else '_') for k, v in result.__dict__.items()}
response[f'customer {value["id"]}'] = value
return response
Full traceback:
Traceback (most recent call last):
File "/Users/ruslan/.local/share/virtualenvs/cft-RKlbQ9iX/lib/python3.9/site-packages/aiohttp/web_protocol.py", line 422, in _handle_request
resp = await self._request_handler(request)
File "/Users/ruslan/.local/share/virtualenvs/cft-RKlbQ9iX/lib/python3.9/site-packages/aiohttp/web_app.py", line 499, in _handle
resp = await handler(request)
File "/Users/ruslan/.local/share/virtualenvs/cft-RKlbQ9iX/lib/python3.9/site-packages/aiohttp/web_urldispatcher.py", line 948, in _iter
resp = await method()
File "/Users/ruslan/OneDrive/Home/Dev/projects/code/education/other/cft/views/user.py", line 24, in get
await get_all_users()
File "/Users/ruslan/OneDrive/Home/Dev/projects/code/education/other/cft/queries/user.py", line 18, in get_all_users
response = customer_schema.dump(_, many=True)
File "/Users/ruslan/.local/share/virtualenvs/cft-RKlbQ9iX/lib/python3.9/site-packages/marshmallow/schema.py", line 547, in dump
result = self._serialize(processed_obj, many=many)
File "/Users/ruslan/.local/share/virtualenvs/cft-RKlbQ9iX/lib/python3.9/site-packages/marshmallow/schema.py", line 509, in _serialize
return [
File "/Users/ruslan/.local/share/virtualenvs/cft-RKlbQ9iX/lib/python3.9/site-packages/marshmallow/schema.py", line 510, in <listcomp>
self._serialize(d, many=False)
File "/Users/ruslan/.local/share/virtualenvs/cft-RKlbQ9iX/lib/python3.9/site-packages/marshmallow/schema.py", line 515, in _serialize
value = field_obj.serialize(attr_name, obj, accessor=self.get_attribute)
File "/Users/ruslan/.local/share/virtualenvs/cft-RKlbQ9iX/lib/python3.9/site-packages/marshmallow/fields.py", line 310, in serialize
value = self.get_value(obj, attr, accessor=accessor)
File "/Users/ruslan/.local/share/virtualenvs/cft-RKlbQ9iX/lib/python3.9/site-packages/marshmallow_sqlalchemy/fields.py", line 27, in get_value
return super(fields.List, self).get_value(obj, attr, accessor=accessor)
File "/Users/ruslan/.local/share/virtualenvs/cft-RKlbQ9iX/lib/python3.9/site-packages/marshmallow/fields.py", line 239, in get_value
return accessor_func(obj, check_key, default)
File "/Users/ruslan/.local/share/virtualenvs/cft-RKlbQ9iX/lib/python3.9/site-packages/marshmallow/schema.py", line 472, in get_attribute
return get_value(obj, attr, default)
File "/Users/ruslan/.local/share/virtualenvs/cft-RKlbQ9iX/lib/python3.9/site-packages/marshmallow/utils.py", line 239, in get_value
return _get_value_for_key(obj, key, default)
File "/Users/ruslan/.local/share/virtualenvs/cft-RKlbQ9iX/lib/python3.9/site-packages/marshmallow/utils.py", line 253, in _get_value_for_key
return getattr(obj, key, default)
File "/Users/ruslan/.local/share/virtualenvs/cft-RKlbQ9iX/lib/python3.9/site-packages/sqlalchemy/orm/attributes.py", line 480, in __get__
return self.impl.get(state, dict_)
File "/Users/ruslan/.local/share/virtualenvs/cft-RKlbQ9iX/lib/python3.9/site-packages/sqlalchemy/orm/attributes.py", line 931, in get
value = self.callable_(state, passive)
File "/Users/ruslan/.local/share/virtualenvs/cft-RKlbQ9iX/lib/python3.9/site-packages/sqlalchemy/orm/strategies.py", line 879, in _load_for_state
return self._emit_lazyload(
File "/Users/ruslan/.local/share/virtualenvs/cft-RKlbQ9iX/lib/python3.9/site-packages/sqlalchemy/orm/strategies.py", line 1036, in _emit_lazyload
result = session.execute(
File "/Users/ruslan/.local/share/virtualenvs/cft-RKlbQ9iX/lib/python3.9/site-packages/sqlalchemy/orm/session.py", line 1689, in execute
result = conn._execute_20(statement, params or {}, execution_options)
File "/Users/ruslan/.local/share/virtualenvs/cft-RKlbQ9iX/lib/python3.9/site-packages/sqlalchemy/engine/base.py", line 1582, in _execute_20
return meth(self, args_10style, kwargs_10style, execution_options)
File "/Users/ruslan/.local/share/virtualenvs/cft-RKlbQ9iX/lib/python3.9/site-packages/sqlalchemy/sql/lambdas.py", line 481, in _execute_on_connection
return connection._execute_clauseelement(
File "/Users/ruslan/.local/share/virtualenvs/cft-RKlbQ9iX/lib/python3.9/site-packages/sqlalchemy/engine/base.py", line 1451, in _execute_clauseelement
ret = self._execute_context(
File "/Users/ruslan/.local/share/virtualenvs/cft-RKlbQ9iX/lib/python3.9/site-packages/sqlalchemy/engine/base.py", line 1813, in _execute_context
self._handle_dbapi_exception(
File "/Users/ruslan/.local/share/virtualenvs/cft-RKlbQ9iX/lib/python3.9/site-packages/sqlalchemy/engine/base.py", line 1998, in _handle_dbapi_exception
util.raise_(exc_info[1], with_traceback=exc_info[2])
File "/Users/ruslan/.local/share/virtualenvs/cft-RKlbQ9iX/lib/python3.9/site-packages/sqlalchemy/util/compat.py", line 207, in raise_
raise exception
File "/Users/ruslan/.local/share/virtualenvs/cft-RKlbQ9iX/lib/python3.9/site-packages/sqlalchemy/engine/base.py", line 1770, in _execute_context
self.dialect.do_execute(
File "/Users/ruslan/.local/share/virtualenvs/cft-RKlbQ9iX/lib/python3.9/site-packages/sqlalchemy/engine/default.py", line 717, in do_execute
cursor.execute(statement, parameters)
File "/Users/ruslan/.local/share/virtualenvs/cft-RKlbQ9iX/lib/python3.9/site-packages/sqlalchemy/dialects/postgresql/asyncpg.py", line 449, in execute
self._adapt_connection.await_(
File "/Users/ruslan/.local/share/virtualenvs/cft-RKlbQ9iX/lib/python3.9/site-packages/sqlalchemy/util/_concurrency_py3k.py", line 60, in await_only
raise exc.MissingGreenlet(
sqlalchemy.exc.MissingGreenlet: greenlet_spawn has not been called; can't call await_() here. Was IO attempted in an unexpected place? (Background on this error at: http://sqlalche.me/e/14/xd2s)
The problem in this case is that the Marshmallow schema is configured to load related models (include_relationships=True). Since the initial query doesn't load them automatically, the schema triggers a query to fetch them, and this causes the error.
The simplest solution, demonstrated in the docs, is to eagerly load the related objects with their "parent":
async def get_all_users():
async with db_conn.get_async_sa_session() as session:
# Let's assume a Customer has a 1 to many relationship with an Order model
statement = select(Customer).options(orm.selectinload(Customer.orders))
results = await session.execute(statement)
_ = (results.scalars().all())
print(_)
response = customer_schema.dump(_, many=True)
print(response)
There is more discussion in the Preventing Implicit IO when Using AsyncSession section of the docs.

why i am getting a error while using json with discord.py

Hi i am trying to add a money system in my discord.py. i am using json with it. i am following a tutorial on youtube. bot and i am trying this code:
#client.command()
async def bal(ctx):
user = ctx.author
await open_account(ctx.author)
users = await get_bank_data()
wallet_amt = users[str(user.id)]["wallet"]
bank_amt = users[str(user.id)]["bank"]
em = discord.Embed(title=f"{ctx.author.name}'s balance")
em.add_field(name = "Wallet", value = wallet_amt)
em.add_field(name = "Bank", value = bank_amt)
await ctx.send(embed=em)
async def open_account(user):
users = await get_bank_data()
if str(user.id) in users:
return False
else:
users[str(user.id)] = {}
users[str(user.id)]["wallet"] = 0
users[str(user.id)]["bank"] = 0
with open("mainBank.json", "r") as f:
json.dump(users, f)
return True
async def get_bank_data():
with open("mainBank.json", "r") as f:
users = json.load(f)
return users
but i am getting a error:
Ignoring exception in command bal:
Traceback (most recent call last):
File "C:\Users\saheb\AppData\Local\Programs\Python\Python38-32\lib\site-packages\discord\ext\commands\core.py", line 85, in wrapped
ret = await coro(*args, **kwargs)
File "c:/Users/saheb/Documents/Discord Bot/DiscordBot.py", line 49, in bal
await open_account(ctx.author)
File "c:/Users/saheb/Documents/Discord Bot/DiscordBot.py", line 84, in open_account
json.dump(users, f)
File "C:\Users\saheb\AppData\Local\Programs\Python\Python38-32\lib\json\__init__.py", line 180, in dump
fp.write(chunk)
io.UnsupportedOperation: not writable
please help if you know how to fix this.
You need to open files in the write mode to write to them (json.dumps writes to a file), you can open a file by doing open("filename", "w"), the "w" says to open in write mode.
Because you use with open("mainBank.json", "r") as f:. That 'r' means just read. If you just want to append new values, use 'a', if you want to read and write, use 'r+'.

How to use mock_open with json.load()?

I'm trying to get a unit test working that validates a function that reads credentials from a JSON-encoded file. Since the credentials themselves aren't fixed, the unit test needs to provide some and then test that they are correctly retrieved.
Here is the credentials function:
def read_credentials():
basedir = os.path.dirname(__file__)
with open(os.path.join(basedir, "authentication.json")) as f:
data = json.load(f)
return data["bot_name"], data["bot_password"]
and here is the test:
def test_credentials(self):
with patch("builtins.open", mock_open(
read_data='{"bot_name": "name", "bot_password": "password"}\n'
)):
name, password = shared.read_credentials()
self.assertEqual(name, "name")
self.assertEqual(password, "password")
However, when I run the test, the json code blows up with a decode error. Looking at the json code itself, I'm struggling to see why the mock test is failing because json.load(f) simply calls f.read() then calls json.loads().
Indeed, if I change my authentication function to the following, the unit test works:
def read_credentials():
# Read the authentication file from the current directory and create a
# HTTPBasicAuth object that can then be used for future calls.
basedir = os.path.dirname(__file__)
with open(os.path.join(basedir, "authentication.json")) as f:
content = f.read()
data = json.loads(content)
return data["bot_name"], data["bot_password"]
I don't necessarily mind leaving my code in this form, but I'd like to understand if I've got something wrong in my test that would allow me to keep my function in its original form.
Stack trace:
Traceback (most recent call last):
File "test_shared.py", line 56, in test_credentials
shared.read_credentials()
File "shared.py", line 60, in read_credentials
data = json.loads(content)
File "/home/philip/.local/share/virtualenvs/atlassian-webhook-basic-3gOncDp4/lib/python3.6/site-packages/flask/json/__init__.py", line 205, in loads
return _json.loads(s, **kwargs)
File "/usr/lib/python3.6/json/__init__.py", line 367, in loads
return cls(**kw).decode(s)
File "/usr/lib/python3.6/json/decoder.py", line 339, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/usr/lib/python3.6/json/decoder.py", line 357, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
I had the same issue and got around it by mocking json.load and builtins.open:
import json
from unittest.mock import patch, MagicMock
# I don't care about the actual open
p1 = patch( "builtins.open", MagicMock() )
m = MagicMock( side_effect = [ { "foo": "bar" } ] )
p2 = patch( "json.load", m )
with p1 as p_open:
with p2 as p_json_load:
f = open( "filename" )
print( json.load( f ) )
Result:
{'foo': 'bar'}
I had the exact same issue and solved it. Full code below, first the function to test, then the test itself.
The original function I want to test loads a json file that is structured like a dictionary, and checks to see if there's a specific key-value pair in it:
def check_if_file_has_real_data(filepath):
with open(filepath, "r") as f:
data = json.load(f)
if "fake" in data["the_data"]:
return False
else:
return True
But I want to test this without loading any actual file, exactly as you describe. Here's how I solved it:
from my_module import check_if_file_has_real_data
import mock
#mock.patch("my_module.json.load")
#mock.patch("my_module.open")
def test_check_if_file_has_real_data(mock_open, mock_json_load):
mock_json_load.return_value = dict({"the_data": "This is fake data"})
assert check_if_file_has_real_data("filepath") == False
mock_json_load.return_value = dict({"the_data": "This is real data"})
assert check_if_file_has_real_data("filepath") == True
The mock_open object isn't called explicitly in the test function, but if you don't include that decorator and argument you get a filepath error when the with open part of the check_if_file_has_real_data function tries to run using the actual open function rather than the MagicMock object that's been passed into it.
Then you overwrite the response provided by the json.load mock with whatever you want to test.

Getting an AttributeError when I try to create a Oracle BMC SecurityList

I am trying to automate the creation of resources in Oracle BMC. I have this python code:
import oraclebmc
config = oraclebmc.config.from_file()
network = oraclebmc.core.virtual_network_client.VirtualNetworkClient(config)
compartment_id = ...
vcn_id = ....
details = oraclebmc.core.models.CreateSecurityListDetails()
details.compartment_id = compartment_id
details.display_name = "baseline"
details.ingress_security_rules = ()
details.egress_security_rules = ()
details.vcn_id = vcn_id
network.create_security_list(details)
But when I run this code I get:
Traceback (most recent call last):
File "deploy/cloudresources/foo.py", line 16, in <module>
network.create_security_list(details)
File "/Users/jwmcclai/bmcs_env/lib/python2.7/site-packages/oraclebmc/core/virtual_network_client.py", line 668, in create_security_list
response_type="SecurityList")
File "/lib/python2.7/site-packages/oraclebmc/base_client.py", line 124, in call_api
body = self.sanitize_for_serialization(body)
File "/lib/python2.7/site-packages/oraclebmc/base_client.py", line 230, in sanitize_for_serialization
for key, val in obj_dict.items()}
File "/lib/python2.7/site-packages/oraclebmc/base_client.py", line 230, in <dictcomp>
for key, val in obj_dict.items()}
File "/lib/python2.7/site-packages/oraclebmc/base_client.py", line 226, in sanitize_for_serialization
for attr, _ in obj.swagger_types.items()
AttributeError: 'tuple' object has no attribute 'swagger_types'
I can create security lists through console and I can create other resources (VCN, instances, etc.) using the Python API. Any ideas?
Thanks
This is because you are defining the security rules fields as tuples, not as lists.
Your code:
details.ingress_security_rules = ()
details.egress_security_rules = ()
Should be:
details.ingress_security_rules = []
details.egress_security_rules = []
As the docs mention, these fields should be of type list, not type tuple.

TypeError Object id is not JSON serializable

I have a Django view that is raising an error when the template tries to render:
TypeError: is not JSON serializable
(Where 76 is the id field)
Here is the view
def view2(request, model1object_id):
model1object = Model1.objects.get(pk=model1object_id)
# HERE
session_object = request.session.get('content')
if session_object:
del request.session['content']
request.session['content'] = model1object
context = {
"model1object": model1object,
....
}
return render(request, 'app/template2.html', context)
Here's my model for Model1:
class Model1(models.Model):
date_field = models.DateField()
another_field = models.CharField(max_length= 50, default="...")
def __str__(self):
return unicode(self.id) or u''
def get_absolute_url(self):
return reverse('app:model1', kwargs={'id': self.id})
EDIT: Traceback ->
Traceback (most recent call last):
File "/Library/Python/2.7/site-packages/django/core/handlers/base.py", line 235, in get_response
response = middleware_method(request, response)
File "/Library/Python/2.7/site-packages/django/contrib/sessions/middleware.py", line 50, in process_response
request.session.save()
File "/Library/Python/2.7/site-packages/django/contrib/sessions/backends/db.py", line 82, in save
obj = self.create_model_instance(data)
File "/Library/Python/2.7/site-packages/django/contrib/sessions/backends/db.py", line 68, in create_model_instance
session_data=self.encode(data),
File "/Library/Python/2.7/site-packages/django/contrib/sessions/backends/base.py", line 91, in encode
serialized = self.serializer().dumps(session_dict)
File "/Library/Python/2.7/site-packages/django/core/signing.py", line 95, in dumps
return json.dumps(obj, separators=(',', ':')).encode('latin-1')
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/__init__.py", line 250, in dumps
sort_keys=sort_keys, **kw).encode(obj)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/encoder.py", line 207, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/encoder.py", line 270, in iterencode
return _iterencode(o, 0)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/encoder.py", line 184, in default
raise TypeError(repr(o) + " is not JSON serializable")
TypeError: <Model1: 76> is not JSON serializable
thanks
The error is because you are trying to save a model instance in the session, and the session middleware cannot serialize it to JSON.
request.session['content'] = model1object
It may be enough to store the id of the object instead of the object itself.
request.session['content_id'] = model1object.id
...
# retrieve from db later
model1object = Model1.objects.get(id=request.session['content_id'])
If you need to store more information in the session than the id, then you'll have to convert it to a format that is JSON serializable. For a simple model, it might be easiest to create a Python dict.
request.session['content'] = {
'id': model1object.id,
'name': model1object.name,
...
}
For more complicated models, you could look at the docs on serializing Django objects.