I was learning some async/await in python, and i wanted to try it, but
I'm getting this error while trying to connect to chatango via websocket and i don't know what means.
I'm using python 3.6.1 and aiohttp 2.2.3
This is my code:
import asyncio
import aiohttp
msgs = []
async def main():
async with aiohttp.ClientSession() as session:
async with session.ws_connect("ws://s12.chatango.com:8081/") as ws:
for msg in ws:
msgs.append(msg)
print(msg)
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.close()
Full traceback:
Traceback (most recent call last):
File "C:\Program Files\Python36\lib\site-packages\aiohttp\client_reqrep.py", line 559, in start
(message, payload) = yield from self._protocol.read()
File "C:\Program Files\Python36\lib\site-packages\aiohttp\streams.py", line 509, in read
yield from self._waiter
File "C:\Program Files\Python36\lib\site-packages\aiohttp\client_proto.py", line 165, in data_received
messages, upgraded, tail = self._parser.feed_data(data)
File "aiohttp\_http_parser.pyx", line 274, in aiohttp._http_parser.HttpParser.feed_data (aiohttp/_http_parser.c:4364)
aiohttp.http_exceptions.BadHttpMessage: 400, message='invalid constant string'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "C:/Users/joseh/Desktop/a.ws.py", line 42, in <module>
loop.run_until_complete(main())
File "C:\Program Files\Python36\lib\asyncio\base_events.py", line 466, in run_until_complete
return future.result()
File "C:/Users/joseh/Desktop/a.ws.py", line 34, in main
async with session.ws_connect("ws://s12.chatango.com:8081/") as ws:
File "C:\Program Files\Python36\lib\site-packages\aiohttp\client.py", line 603, in __aenter__
self._resp = yield from self._coro
File "C:\Program Files\Python36\lib\site-packages\aiohttp\client.py", line 390, in _ws_connect
proxy_auth=proxy_auth)
File "C:\Program Files\Python36\lib\site-packages\aiohttp\helpers.py", line 91, in __iter__
ret = yield from self._coro
File "C:\Program Files\Python36\lib\site-packages\aiohttp\client.py", line 241, in _request
yield from resp.start(conn, read_until_eof)
File "C:\Program Files\Python36\lib\site-packages\aiohttp\client_reqrep.py", line 564, in start
message=exc.message, headers=exc.headers) from exc
aiohttp.client_exceptions.ClientResponseError: 400, message='invalid constant string'
invalid constant string is a custom response from chatango, they probably want a protocol or some kind of auth header.
If you don't know much about how chatango uses websockets, reverse engineering their system is probably not a good task for learning asyncio and aiohttp.
Better to use something like httparrot which just echos back the message you send it.
Here's your code modified to use httparrot and send 5 messages, get 5 responses, then exit.
import asyncio
import aiohttp
msgs = []
async def main():
async with aiohttp.ClientSession() as session:
async with session.ws_connect('ws://httparrot.herokuapp.com/websocket') as ws:
ws.send_str('hello')
async for msg in ws:
msgs.append(msg)
print(msg)
ws.send_str('hello')
if len(msgs) >= 5:
break
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.close()
print(msgs)
Related
I made a simple asynchronous python program to get the list of all Virtual Machines in a subscription. But I'm getting an error when iterating through the list.
The complete program:
from azure.identity.aio import AzureCliCredential
from azure.mgmt.compute.aio import ComputeManagementClient
from azure.mgmt.network.aio import NetworkManagementClient
from azure.mgmt.web.aio import WebSiteManagementClient
from azure.mgmt.sql.aio import SqlManagementClient
import asyncio
credential = AzureCliCredential()
compute_client = ComputeManagementClient(credential, "XXXXX")
web_client = WebSiteManagementClient(credential, "XXXX")
async def get_as_list():
as_list = web_client.web_apps.list()
async for _as in as_list:
pass
return as_list
async def get_vm_list():
vm_list = compute_client.virtual_machines.list_all()
async for vm in vm_list:
pass
return vm_list
async def main():
await get_as_list()
await get_vm_list()
if __name__ == '__main__':
asyncio.run(main())
The Error:
Traceback (most recent call last):
File "c:\Users\Kristian-Laptop\Desktop\Work\Azure Inventory\Inventory with UI\test.py", line 32, in <module>
asyncio.run(main())
File "C:\Users\Kristian-Laptop\AppData\Local\Programs\Python\Python39\lib\asyncio\runners.py", line 44, in run
return loop.run_until_complete(main)
File "C:\Users\Kristian-Laptop\AppData\Local\Programs\Python\Python39\lib\asyncio\base_events.py", line 647, in run_until_complete
return future.result()
File "c:\Users\Kristian-Laptop\Desktop\Work\Azure Inventory\Inventory with UI\test.py", line 28, in main
await get_vm_list()
File "c:\Users\Kristian-Laptop\Desktop\Work\Azure Inventory\Inventory with UI\test.py", line 22, in get_vm_list
async for vm in vm_list:
File "C:\Users\Kristian-Laptop\.virtualenvs\Inventory_with_UI-ioU1jGkq\lib\site-packages\azure\core\async_paging.py", line 163, in __anext__
return await self.__anext__()
File "C:\Users\Kristian-Laptop\.virtualenvs\Inventory_with_UI-ioU1jGkq\lib\site-packages\azure\core\async_paging.py", line 157, in __anext__
self._page = await self._page_iterator.__anext__()
File "C:\Users\Kristian-Laptop\.virtualenvs\Inventory_with_UI-ioU1jGkq\lib\site-packages\azure\core\async_paging.py", line 99, in __anext__
self._response = await self._get_next(self.continuation_token)
File "C:\Users\Kristian-Laptop\.virtualenvs\Inventory_with_UI-ioU1jGkq\lib\site-packages\azure\mgmt\compute\v2022_08_01\aio\operations\_virtual_machines_operations.py", line 1486, in get_next
request = prepare_request(next_link)
File "C:\Users\Kristian-Laptop\.virtualenvs\Inventory_with_UI-ioU1jGkq\lib\site-packages\azure\mgmt\compute\v2022_08_01\aio\operations\_virtual_machines_operations.py", line 1471, in prepare_request
_next_request_params["api-version"] = self._config.api_version
AttributeError: 'ComputeManagementClientConfiguration' object has no attribute 'api_version'
No problem iterating through the Web app list. I'm only getting the error with the VM list.
i have a bot which parses some links given by user. When clients want to parse realy huge amount of links, bot parses them, creates csv file from those links, sends it to user(user can download and view this file) and then raise TimeoutError
Cause exception while getting updates.
Traceback (most recent call last):
File "/Users/alex26/miniforge3/envs/rq/lib/python3.8/site-packages/aiogram/dispatcher/dispatcher.py", line 381, in start_polling
updates = await self.bot.get_updates(
File "/Users/alex26/miniforge3/envs/rq/lib/python3.8/site-packages/aiogram/bot/bot.py", line 110, in get_updates
result = await self.request(api.Methods.GET_UPDATES, payload)
File "/Users/alex26/miniforge3/envs/rq/lib/python3.8/site-packages/aiogram/bot/base.py", line 231, in request
return await api.make_request(await self.get_session(), self.server, self.__token, method, data, files,
File "/Users/alex26/miniforge3/envs/rq/lib/python3.8/site-packages/aiogram/bot/api.py", line 139, in make_request
async with session.post(url, data=req, **kwargs) as response:
File "/Users/alex26/miniforge3/envs/rq/lib/python3.8/site-packages/aiohttp/client.py", line 1138, in __aenter__
self._resp = await self._coro
File "/Users/alex26/miniforge3/envs/rq/lib/python3.8/site-packages/aiohttp/client.py", line 559, in _request
await resp.start(conn)
File "/Users/alex26/miniforge3/envs/rq/lib/python3.8/site-packages/aiohttp/client_reqrep.py", line 913, in start
self._continue = None
File "/Users/alex26/miniforge3/envs/rq/lib/python3.8/site-packages/aiohttp/helpers.py", line 721, in __exit__
raise asyncio.TimeoutError from None
asyncio.exceptions.TimeoutError
Some example how my bot looks like(that's not real code, that's EXAMPLE):
bot = Bot(token=API_TOKEN)
dp = Dispatcher(bot)
def parse_1000_links():
#it takes about 10 mins and therefore that's the same like sleep(600)
sleep(600)
#dp.message_handler()
async def msg_handler(message: types.Message):
if msg == 'parse 1000 links':
res = parse_1000_links()
create_csv_from_res(res)
file_open_obj = open('data.csv', 'rb')
await bot.send_document(message.from_user.id, file_open_obj)
.....
if __name__ == '__main__':
executor.start_polling(dp, skip_updates=True)
User can even get from bot this final file, but after sending this file to user, bot raises this error. That's strange. If user get message, it means that everything is fine(That's my opinion)
How to fix my issue?
Thanks
You should avoid using blocking operations, cause they freeze ALL event loop.
If you can't use async version of your dependency, use executor:
https://docs.python.org/3/library/asyncio-eventloop.html#executing-code-in-thread-or-process-pools
Good day!
I am writing a telegram bot and using aiogram library.
Everything seems to be working fine when I run my code.
However, if I leave the bot running for a while, after some time it throws a timeout error. Can't understand what seems to be the issue - my PC falling asleep or something else?
I run an infinite loop like this
from aiogram import Bot, Dispatcher, types
from aiogram.contrib.fsm_storage.memory import MemoryStorage
import asyncio
import logging
from data import config
from utils.db_api.postgresql import Database
loop = asyncio.get_event_loop()
logging.basicConfig(format=u'%(filename)s [LINE:%(lineno)d] #%(levelname)-8s [%(asctime)s] %(message)s',
level=logging.INFO,
# level=logging.DEBUG,
)
bot = Bot(token=config.BOT_TOKEN, parse_mode=types.ParseMode.HTML)
storage = MemoryStorage()
dp = Dispatcher(bot, storage=storage)
db = Database()
if __name__ == '__main__':
executor.start_polling(dp, on_startup=on_startup)
the error is this
Traceback (most recent call last):
File "/Library/Python/3.8/site-packages/aiogram/dispatcher/dispatcher.py", line 381, in start_polling
updates = await self.bot.get_updates(
File "/Library/Python/3.8/site-packages/aiogram/bot/bot.py", line 110, in get_updates
result = await self.request(api.Methods.GET_UPDATES, payload)
File "/Library/Python/3.8/site-packages/aiogram/bot/base.py", line 231, in request
return await api.make_request(await self.get_session(), self.server, self.__token, method, data, files,
File "/Library/Python/3.8/site-packages/aiogram/bot/api.py", line 139, in make_request
async with session.post(url, data=req, **kwargs) as response:
File "/Library/Python/3.8/site-packages/aiohttp/client.py", line 1138, in __aenter__
self._resp = await self._coro
File "/Library/Python/3.8/site-packages/aiohttp/client.py", line 559, in _request
await resp.start(conn)
File "/Library/Python/3.8/site-packages/aiohttp/client_reqrep.py", line 913, in start
self._continue = None
File "/Library/Python/3.8/site-packages/aiohttp/helpers.py", line 721, in __exit__
raise asyncio.TimeoutError from None
asyncio.exceptions.TimeoutError
My code is is similar to this example:
import discord
import tweepy
import asyncio
class Client(discord.Client):
async def on_ready(self):
print("ready")
global GUILD
GUILD = discord.utils.get(self.guilds, name = "Any Guild")
class TweepyStream(tweepy.Stream):
def on_connect(self):
print("connceted")
def on_status(self, status):
print(status.text)
channel = discord.utils.get(GUILD.channels, name = "twitter-posts")
asyncio.run(channel.send(status.text))
#From here the Discord message should be send
auth = tweepy.OAuthHandler(keys)
auth.set_access_token(tokens)
global api
api = tweepy.API(auth)
follow_list = []
follow = int(api.get_user(screen_name = "Any User").id)
print(follow)
follow_list.append(follow)
print(str(follow_list))
stream = TweepyStream(tokens and keys)
stream.filter(follow = follow_list, threaded=True) #track = track,
client = Client()
client.run(token)
I try to receive Twitter posts and send them into a Discord channel, but it doesn't work. How can I do this (maybe without asyncio)?
Or is there a way to work with a Python Twitter API, which works with async functions?
My error:
Stream encountered an exception
Traceback (most recent call last):
File "C:\Python39\lib\site-packages\tweepy\streaming.py", line 133, in _connect
self.on_data(line)
File "C:\Python39\lib\site-packages\tweepy\streaming.py", line 387, in on_data
return self.on_status(status)
File "c:\Users\morit\Desktop\FLL 2021 Bot\DiscordBot\DiscordBotV0.7\example.py", line 18, in on_status
asyncio.run(channel.send(status.text))
File "C:\Python39\lib\asyncio\runners.py", line 44, in run
return loop.run_until_complete(main)
File "C:\Python39\lib\asyncio\base_events.py", line 642, in run_until_complete
return future.result()
File "C:\Python39\lib\site-packages\discord\abc.py", line 1065, in send
data = await state.http.send_message(channel.id, content, tts=tts, embed=embed,
File "C:\Python39\lib\site-packages\discord\http.py", line 192, in request
async with self.__session.request(method, url, **kwargs) as r:
File "C:\Python39\lib\site-packages\aiohttp\client.py", line 1117, in __aenter__
self._resp = await self._coro
File "C:\Python39\lib\site-packages\aiohttp\client.py", line 448, in _request
with timer:
File "C:\Python39\lib\site-packages\aiohttp\helpers.py", line 635, in __enter__
raise RuntimeError(
RuntimeError: Timeout context manager should be used inside a task
asyncio.run creates a new event loop. You need to use the existing event loop that the discord.Client uses. You can retrieve this with Client.loop, asyncio.get_running_loop, or asyncio.get_event_loop.
You should probably also use asyncio.run_coroutine_threadsafe.
If you're using the current latest development version of Tweepy on the master branch, set to be released as v4.0, which it seems like you are, then you can also look into using AsyncStream
I'm trying to create an api, and when i try to convert the aiohttp.ClientResponse to text, my code never finishes (never go to the next line) and it raises TimeoutError, I tried to do this in terminal (with the same site), and it works, can someone help me?
Here's my current code:
async with aiohttp.ClientSession() as session:
# _base="https://frankerfacez.com"
# query="monka"
# sort="count-desc"
r = await session.get(f'{_base}/emoticons/wall?q={query}&sort={sort}')
txt = await r.text()
And it raises this:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Users\Kaigo\AppData\Local\Programs\Python\Python38\lib\asyncio\base_events.py", line 612, in run_until_complete
return future.result()
File "C:\Users\Kaigo\Desktop\FFZ Api\ffz\__init__.py", line 112, in search
txt = await r.text()
File "C:\Users\Kaigo\AppData\Local\Programs\Python\Python38\lib\site-packages\aiohttp\client_reqrep.py", line 1009, in text
await self.read()
File "C:\Users\Kaigo\AppData\Local\Programs\Python\Python38\lib\site-packages\aiohttp\client_reqrep.py", line 973, in read
self._body = await self.content.read()
File "C:\Users\Kaigo\AppData\Local\Programs\Python\Python38\lib\site-packages\aiohttp\streams.py", line 358, in read
block = await self.readany()
File "C:\Users\Kaigo\AppData\Local\Programs\Python\Python38\lib\site-packages\aiohttp\streams.py", line 380, in readany
await self._wait('readany')
File "C:\Users\Kaigo\AppData\Local\Programs\Python\Python38\lib\site-packages\aiohttp\streams.py", line 296, in _wait
await waiter
File "C:\Users\Kaigo\AppData\Local\Programs\Python\Python38\lib\site-packages\aiohttp\helpers.py", line 596, in __exit__
raise asyncio.TimeoutError from None
asyncio.exceptions.TimeoutError
you're trying to read from the request after clossing the session. Move the await r.text() to inside the async with block:
async with aiohttp.ClientSession() as session:
url = f'{_base}/emoticons/wall?q={query}&sort={sort}'
async with session.get(url) as r:
txt = await r.text()