fastapi testing (RuntimeError("Task ... running at ... got Future ... attached to a different loop") - async-await

RuntimeError("Task <Task pending name='Task-5' coro=<test_root() running at /home/david/PycharmProjects/work/tests/main_test.py:12> cb=[_run_until_complete_cb() at /usr/lib/python3.8/asyncio/base_events.py:184]> got Future <Future pending cb=[Protocol._on_waiter_completed()]> attached to a different loop")
How to fix this issue? In docs there a mention of github comment with a solution, but it's outdated and unclear how to apply provided solution to my code (similar to code from docs).
My code:
import pytest
from httpx import AsyncClient
import main # File with uvicorn starting
from tests import conftest # File with code from a [link][2]
#pytest.mark.asyncio()
async def test_root():
async with AsyncClient(app=main.app, base_url="http://test") as ac:
response = conftest.event_loop(await ac.post("/register", json={
"phone_number": "+7 931 964 0000",
"full_name": "Alex Balex"
}))
assert response.status_code == 201

Related

Using Python's asyncio 'await' in ros2 callbacks: 'RuntimeError: await wasn't used with future'

I'm trying to call an asyncio async function from a ROS2 callback as seen in the code below. The callback always throws an error 'RuntimeError: await wasn't used with future' and I can't figure out why. It doesn't seem to have this error when awaiting a custom async function that doesn't await anything itself (see 'test_async()').
Minimal example
Subscriber - foo
import asyncio, rclpy
from rclpy.node import Node
from std_msgs.msg import Bool
from concurrent.futures import ThreadPoolExecutor
import rclpy.qos as qos
from rclpy.qos import QoSProfile
class Foo(Node):
def __init__(self):
super().__init__('foo')
# Setup test subscriber
qos_profile = QoSProfile(
reliability=qos.ReliabilityPolicy.BEST_EFFORT,
durability=qos.DurabilityPolicy.TRANSIENT_LOCAL,
history=qos.HistoryPolicy.KEEP_LAST,
depth=1
)
self.test_sub = self.create_subscription(
Bool,
'/foo_sub',
self.clbk,
qos_profile)
# Test callback function
async def clbk(self, msg):
self.get_logger().info(f'Received: {msg.data}. About to test async')
# This doesn't cause a problem
await self.test_async()
# This doesn't work
self.get_logger().info('About to sleep')
await asyncio.sleep(3)
# Workaround: This appears to run sleep in a separate thread.
# executor = ThreadPoolExecutor(max_workers=1)
# asyncio.get_event_loop().run_in_executor(executor, asyncio.run, asyncio.sleep(3))
# executor.shutdown(wait=True)
# The workaround doesn't work when getting a returned value
# executor = ThreadPoolExecutor(max_workers=1)
# asyncio.get_event_loop().run_in_executor(executor, asyncio.run, self.sleep_with_return())
# executor.shutdown(wait=True)
self.get_logger().info('Clbk complete')
# Working async function
async def test_async(self):
self.get_logger().info('Test async works!')
# Workaround failure case
async def sleep_with_return(self):
await asyncio.sleep(3)
return True
async def async_main():
rclpy.init()
# Create node and spin
foo = Foo()
rclpy.spin(foo)
def main():
asyncio.run(async_main())
if __name__ == '__main__':
main()
Publisher - bar
import asyncio, rclpy
from rclpy.node import Node
from std_msgs.msg import Bool
import rclpy.qos as qos
from rclpy.qos import QoSProfile
class Bar(Node):
def __init__(self):
super().__init__('bar')
# Setup test publisher
qos_profile = QoSProfile(
reliability=qos.ReliabilityPolicy.BEST_EFFORT,
durability=qos.DurabilityPolicy.TRANSIENT_LOCAL,
history=qos.HistoryPolicy.KEEP_LAST,
depth=1
)
self.test_pub = self.create_publisher(Bool, '/foo_sub', qos_profile)
def send_msg(self):
msg = Bool()
msg.data = True
self.test_pub.publish(msg)
def main():
rclpy.init()
# Create node
bar = Bar()
# Send messages
while True:
input('Press enter when you want to send msg')
bar.send_msg()
if __name__ == '__main__':
main()
Output
After running both nodes and sending a msg from bar (by pressing 'enter'), this is foo's error message:
[INFO] [1674748995.662302006] [foo]: Received: True. About to test async
[INFO] [1674748995.662621572] [foo]: Test async works!
[INFO] [1674748995.662859403] [foo]: About to sleep
Traceback (most recent call last):
File "/home/harvey/px4_ros_com_ros2/install/swarm_load_carry/lib/swarm_load_carry/foo", line 33, in <module>
sys.exit(load_entry_point('swarm-load-carry==0.0.0', 'console_scripts', 'foo')())
File "/home/harvey/px4_ros_com_ros2/install/swarm_load_carry/lib/python3.10/site-packages/swarm_load_carry/foo.py", line 74, in main
asyncio.run(async_main())
File "/usr/lib/python3.10/asyncio/runners.py", line 44, in run
return loop.run_until_complete(main)
File "/usr/lib/python3.10/asyncio/base_events.py", line 646, in run_until_complete
return future.result()
File "/home/harvey/px4_ros_com_ros2/install/swarm_load_carry/lib/python3.10/site-packages/swarm_load_carry/foo.py", line 71, in async_main
rclpy.spin(foo)
File "/opt/ros/humble/local/lib/python3.10/dist-packages/rclpy/__init__.py", line 222, in spin
executor.spin_once()
File "/opt/ros/humble/local/lib/python3.10/dist-packages/rclpy/executors.py", line 713, in spin_once
raise handler.exception()
File "/opt/ros/humble/local/lib/python3.10/dist-packages/rclpy/task.py", line 239, in __call__
self._handler.send(None)
File "/opt/ros/humble/local/lib/python3.10/dist-packages/rclpy/executors.py", line 418, in handler
await call_coroutine(entity, arg)
File "/opt/ros/humble/local/lib/python3.10/dist-packages/rclpy/executors.py", line 343, in _execute_subscription
await await_or_execute(sub.callback, msg)
File "/opt/ros/humble/local/lib/python3.10/dist-packages/rclpy/executors.py", line 104, in await_or_execute
return await callback(*args)
File "/home/harvey/px4_ros_com_ros2/install/swarm_load_carry/lib/python3.10/site-packages/swarm_load_carry/foo.py", line 39, in clbk
await asyncio.sleep(3)
File "/usr/lib/python3.10/asyncio/tasks.py", line 605, in sleep
return await future
RuntimeError: await wasn't used with future
[ros2run]: Process exited with failure 1
As you can see in the commented out section in 'clbk', I have found a workaround by running asyncio.run in a separate thread. This is unideal however as it makes the code more complex and I can't retrieve return values (say if asyncio.sleep(3) actually returned something).
As this works, my guess is it might have something to do with asyncio not being threadsafe and ros2 callbacks running in a different thread (I can't seem to find if this is true), or something to do with where the asyncio event loop is running... I've tried may other workarounds based on this assumption however (such as getting the event loop, using call_soon_threadsafe, setting new event loops) and none seem to work.
Running process
Each node 'foo' and 'bar' are run in their own terminals with 'ros2 run pkg module' where pkg (swarm_load_carry) is the name of the ros2 package in a colcon workspace and module is either foo or bar. I am confident that the workspace, package and launchfiles are set up correctly as they work with other test cases.
System details
Ubuntu 22.04.1
Python 3.10
Ros2 Humble

python-telegram-bot for (v20.x) TypeError: bad operand type for unary ~: 'type'

I am trying to build a telegram bot, I have just reproduce the code:
from telegram.ext import MessageHandler
from telegram.ext import filters
from telegram.ext import Application
from telegram import Update
from telegram.ext import ContextTypes
from decouple import config
def testFunc (update: Update, context: ContextTypes.DEFAULT_TYPE):
print('Hi')
def main():
BOT_TOKEN = config('TELE_BOT_API_KEY_2')
application = Application.builder().token(BOT_TOKEN).build()
application.add_handler(MessageHandler(filters.Text & ~filters.Command, testFunc))
application.run_polling()
if __name__ == '__main__':
main()
The error this code shows is:
Bot\AsyncAdvanceBot\test3.py", line 16, in main
application.add_handler(MessageHandler(filters.Text & ~filters.Command, testFunc))
TypeError: bad operand type for unary ~: 'type'
I am using python-telegram-bot api v20.x
I know this might be a naive problem that I might be missing.
Thanks!
I tried changing the code to different format but it doesn't work.
I got it! It was as I said naive error. I was not thinking straight😅
I have seen the document even earlier and was only focusing on making filters.Command to filters.COMMAND, but forgot to change filters.Text to filters.TEXT.
just replaced
filters.Text & ~filters.Command
with
filters.TEXT & ~filters.COMMAND

Discord Slash Command options not working

I am trying to make a slash command in discord.
import discord
import datetime
import pickle
import os
from discord.ext import commands
from dislash import *
bot = commands.Bot(command_prefix="-")
inter_client = InteractionClient(bot, test_guilds=[345328981039382528])
#bot.event
async def on_ready():
print("Nick ist online!")
#inter_client.slash_command(
name="kick", # Defaults to the function name
description="kick a user",
guild_ids=[345328981039382528],
options=[
create_option(
name="user",
description="Choose a user",
option_type=6,
required=True
)
]
)
async def kick(inter, user:str):
pass
bot.run("-")
If i am trying to run it it says:
Traceback (most recent call last):
line 20, in <module>
create_option(
NameError: name 'create_option' is not defined
So someone said i should add the following line:
from discord_slash.utils.manage_commands import create_option
But this does not help. After adding this it says:
line 7, in <module>
from discord_slash.utils.manage_commands import create_option
ModulNotFoundError: No module named 'discord_slash'
However if i go to cmd and do:
pip install discord-py-slash-command
It says its already installed.
Does anyone know what i am doing wrong? Thanks for helping
options=[
Option("user","Choose a user", OptionType.USER)
]
Try changing your options in the slash command to as follows.

Decorator function is not working as expected

I was doing some testing with imports, and I wanted to test how fast certain packages get imported using function decorators. Here is my code:
import time
def timeit(func):
def wrapper():
start = time.time()
func()
end = time.time()
print(f'{func.__name__} executed in {end - start} second(s)')
return wrapper
#timeit
def import_matplotlib():
import matplotlib.pyplot
#timeit
def import_numpy():
import numpy
import_matplotlib()
import_numpy()
Output
import_matplotlib executed in 0.4385249614715576 second(s)
import_numpy executed in 0.0 second(s)
This is not the expected output given that numpy isn't imported in an instant. What is happening here, and how can this be fixed? Thank you.
Edit
If I make this change to import_numpy():
#timeit
def import_numpy():
import numpy
time.sleep(2)
The output becomes this:
import_matplotlib executed in 0.4556155204772949 second(s)
import_numpy executed in 2.0041260719299316 second(s)
This tells me that there isn't anything wrong with my decorator function. Why is this behavior occurring?
Try using the timeit module? It was built for this purpose and makes that code simpler.
>>> import timeit
>>> timeit.timeit(stmt='import numpy')
0.13844075199995132

GAE + Python2.7 + webapp2 + AJAX

Are there any tutorials or code examples related to AJAX implementation for GAE + Python2.7 + webapp2.
I have tried to follow instructions below:
http://code.google.com/appengine/articles/rpc.html
but I receive the following error:
Traceback (most recent call last):
File "E:\dev\workspace\test\webapp2.py", line 1536, in __call__
rv = self.handle_exception(request, response, e)
File "E:\dev\workspace\test\webapp2.py", line 1530, in __call__
rv = self.router.dispatch(request, response)
File "E:\dev\workspace\test\webapp2.py", line 1278, in default_dispatcher
return route.handler_adapter(request, response)
File "E:\dev\workspace\test\webapp2.py", line 1101, in __call__
handler = self.handler(request, response)
TypeError: __init__() takes exactly 1 argument (3 given)
There is another similar discussion here:
Google App Engine Python Protorpc Error: __call__() takes exactly 1 argument (3 given)
heres is my code from Specialscope's example:
main.py
from BaseHandler import BaseHandler
from google.appengine.ext import blobstore
from google.appengine.ext.webapp import blobstore_handlers
import logging
from google.appengine.api import files
from google.appengine.api import images
import json
import webapp2
class FileuploadHandler(BaseHandler):
def get(self):
blobstore.create_upload_url('/static')
context={}
self.render_response("uploader.html",**context)
class FileDownloadHandler(blobstore_handlers.BlobstoreUploadHandler,BaseHandler):
def post(self):
upload_files=self.request.POST
#image=upload_files['file']
logging.error(upload_files)
keys=upload_files.keys()
imageurls=[]
for key in keys:
if key.find("uploadimage")!=-1:
image=upload_files[key]
file_name=files.blobstore.create(mime_type='image/jpg')
with files.open(file_name,'a') as f:
f.write(image.value)
files.finalize(file_name)
blob_key=files.blobstore.get_blob_key(file_name)
imageurls.append(images.get_serving_url(blob_key))
context={}
context['imagelinks']=imageurls
self.response.write(json.dumps(context))
app = webapp2.WSGIApplication([
('/upload', FileuploadHandler),
('/download', FileDownloadHandler),
], debug = True)
BaseHandler.py
import webapp2
import os
from webapp2_extras import jinja2
from google.appengine.ext import db
class BaseHandler(webapp2.RequestHandler):
#webapp2.cached_property
def jinja2(self):
# Returns a Jinja2 renderer cached in the app registry.
return jinja2.get_jinja2(app=self.app)
def render_response(self, _template, **context):
# Renders a template and writes the result to the response.
rv = self.jinja2.render_template(_template, **context)
self.response.write(rv)
The stack trace suggests that you have a url mapping in your WSGIApplication that has a group in it, but there's no handler with the corresponding arguments.
If you have
(r'/foo/(\s+)/(\s+)', FooHandler),
then you need
class FooHandler(webapp2.RequestHandler):
def get(self, arg1, arg2):
...
The doc you're using pre-dates Python 2.7 support by several years. Were I in your position, I'd be tempted to get the app working first on Python 2.5, then port to 2.7.
The problem is here:
import webapp2
app = webapp2.WSGIApplication([
('/upload', FileuploadHandler),
('/download', FileDownloadHandler),
], debug = True)
You can't use webapp2.WSGIApplication to construct your application, it doesn't understand protorpc. Instead, do this:
from protorpc.wsgi import service
app = service.service_mappings([
('/upload', FileuploadHandler),
('/download', FileDownloadHandler),
])

Resources