Python websocket asyncio using the same connection more than once - python

Hi all I am hoping someone here can help me with the jsonrpcclient using websockets. I am very new to using websockets and have to use jsonrpc for a project. I have searched the site but unfortunately I was unable to find the answer.
Below is the sample code from the documention which I can get working. But I wish to create the websockets.connect then use it with multiple responses.
【Base Code】
import asyncio
import websockets
from jsonrpcclient.clients.websockets_client import WebSocketsClient
async def main():
async with websockets.connect("ws://localhost:5000") as ws:
response = await WebSocketsClient(ws).request("ping")
print(response.data.result)
asyncio.get_event_loop().run_until_complete(main())
【What I Want】
import asyncio
import websockets
from jsonrpcclient.clients.websockets_client import WebSocketsClient
async def main():
async with websockets.connect("ws://localhost:5000") as ws:
response = await WebSocketsClient(ws).request("ping")
print(response.data.result)
response2 = await WebSocketsClient(ws).request("donkey")
print(response2.data.result)
asyncio.get_event_loop().run_until_complete(main())
Additional Question: Is it possible to set the client up like a server so it is always running and listing and if it gets a command from another script that it will call the main function?
Thank you in advance for any help!
https://jsonrpcclient.readthedocs.io/en/latest/examples.html#websockets
OS: Windows
Python: 3.8
Except Error when running code similar to 'What I want': code = 1000 (OK) No reason
EDIT
After trial and error and lots of Googling it seems you just have to have the server running in a while loop to process multiple requests in a row like I am after.
However if someone finds out a way to do this with out putting the server in a while loop I would love to hear how.
Thank you.

Related

Unable to get the same output from a python telegram bot between 2 linux computers

I have a python telegram bot running on my laptop. I am trying to run the same script on my Raspberry Pi4 but i am getting an warning message when I try to run it which isnt happening on the laptop. I am using python 3.9 on both systems and I have installed the same packages.
On the laptop this works fine, however when I ssh to the Pi to run it I get the warning below, when running direct from command line and through vscode ssh.
This is the warning message 'RuntimeWarning: coroutine 'Bot.send_message' was never awaited
bot.send_message(chat_id=chat_id, text=f'{message}')
RuntimeWarning: Enable tracemalloc to get the object allocation traceback'
Any help will be greatly appreciated, thank you.
# Telegram bot practice
from bs4 import BeautifulSoup as bs
from urllib import request
import telegram
import json
chat_id = '********'
token = '***********************************'
bot = telegram.Bot(token=token)
def send_message(message):
bot.send_message(chat_id=chat_id, text=f'{message}')
send_message('hey there')
I now have it working, I imported asyncio and used asyncio.run for the sending of the message.
I still have no idea why i had this issue on one system and not the oter buy either way it is now working.
from bs4 import BeautifulSoup as bs
from urllib import request
import telegram
import json
import asyncio
chat_id = '********'
token = '***********************************'
bot = telegram.Bot(token=token)
async def send_message(message):
bot.send_message(chat_id=chat_id, text=f'{message}')
asyncio.run(send_message('hey there'))

I keep getting same errors when trying to rerun Telethon script

so i`m trying to learn Telethon and wrote some script from tutorial. It works fine for the first time, when i have to confirm authorization.
from telethon import TelegramClient
api_id = 1234567
api_hash = ''
client = TelegramClient('anon', api_id, api_hash)
async def main():
me = await client.get_me()
print(me.username)
with client:
client.loop.run_until_complete(main())
but when i try to run it again with the same .session file i keep getting same error, which doesn`t help to understand the problem.
Server sent a very new message with ID 7144059125492611077, ignoring
Server sent a very new message with ID 7144059125964561409, ignoring
Also, program doesn`t stop running after this error.
After a couple of days searching for a fix, i just switched to pyrogram, which works perfectly fine. So if someone got the same problem I recommend just to change Telethon to something else.
Make sure your system time is correct. If the issue persists, it may be a bug you which you should report to https://github.com/LonamiWebs/Telethon/issues/new/choose. However recent versions of the library (v1.25.2) should not have this issue.

Cannot Host Discord Bot on repl.it

I recently made a discord bot and ran in on repl.it as it has free hosting (I use uptime robot). But, when I run main.py the uptime robot says that the website that I use for keep_alive() is "Down" and when I try to access the website from my browser it doesn't load either saying that the site "can't be reached". When I close the repl.it tab my bot goes offline as well.
Repl.it is not made for hosting discord bot's it's prone to rate limits.
It's good for writing code online and hosting basic web apps or collaborating with others while coding.
You should definitely invest in a proper host like PebbleHost, PloxHost and etc if you need something to write code online. However, a VPS provider like Linode, Digitalcoean or even PloxHost would be more beneficial as you have your own dedicated IP and are not affected by rate limits from other users. However, this does require knowledge of Linux.
For your issue of your keep_alive you should try this:
from flask import Flask
from threading import Thread
import time
app = Flask('')
#app.route('/')
def home():
return "Hello World!"
def run():
app.run(host='0.0.0.0',port=8080)#127.0.0.1 or ::
def keep_alive():
t = Thread(target=run)
t.start()
Then in your main.py:
from keep_alive import keep_alive
keep_alive()
You should take a look at UptimeRobot to send pings to the URL of the web server associated with the repl. This video is for node.js but should apply to python as well on the UptimeRobot chunk

FastAPI websocket can not connect

I am trying to let my Vue.js app communicate with my FastAPI(based on starlette) local server using websockets. I tried using the exact same code as in their example: https://fastapi.tiangolo.com/tutorial/websockets/. However something weird happens, because my server can not start with the reason: AttributeError: 'FastAPI' object has no attribute 'websocket'. That is strange because this exact code is the official docs of FastAPI.
After that I used the Starlette example code: https://www.starlette.io/websockets/. However when I try to connect to it, the FastApi prints to the terminal: WARNING: Invalid HTTP request received.
I tried using another client, the Simple WebSocket Client: https://chrome.google.com/webstore/detail/simple-websocket-client/pfdhoblngboilpfeibdedpjgfnlcodoo, but the same error appears on the terminal.
What am I doing wrong here? In the first place I find it weird that the FastAPI code does not seem to work on my computer, does anyone know why?
Thanks in advance!
Apparently the WebSocket functionality was added in FastAPI 0.24, which was just released. I was using an older version.
run pip install websockets and configure it as following:
from fastapi import FastAPI, WebSocket
#app.websocket("/ws")
async def send_data(websocket:WebSocket):
print('CONNECTING...')
await websocket.accept()
while True:
try:
await websocket.receive_text()
resp = {
"message":"message from websocket"
}
await websocket.send_json(resp)
except Exception as e:
print(e)
break
print("CONNECTION DEAD...")

How to handle DNS timeouts with aiohttp?

The aiohttp readme says:
If you want to use timeouts for aiohttp client please use standard asyncio approach:
yield from asyncio.wait_for(client.get(url), 10)
But that doesn't handle DNS timeouts which are, I guess, handled by the OS. Also the with aiohttp.Timeout doesn't handle OS DNS lookups.
There has been a discussion at the asyncio repo without final conclusion and Saghul has made aiodns but I'm not sure how to mix it into aiohttp and whether that will allow asyncio.wait_for functionality.
Testcase (takes 20 sec on my linux box):
async def fetch(url):
url = 'http://alicebluejewelers.com/'
with aiohttp.Timeout(0.001):
resp = await aiohttp.get(url)
Timeout works as expected but unfortunately your example hangs on python shutdown procedure: it waits for termination of background thread which performs DNS lookup.
As a solution I can suggest using aiodns for manual IP resolving:
import asyncio
import aiohttp
import aiodns
async def fetch():
dns = 'alicebluejewelers.com'
# dns = 'google.com'
with aiohttp.Timeout(1):
ips = await resolver.query(dns, 'A')
print(ips)
url = 'http://{}/'.format(ips[0].host)
async with aiohttp.get(url) as resp:
print(resp.status)
loop = asyncio.get_event_loop()
resolver = aiodns.DNSResolver(loop=loop)
loop.run_until_complete(fetch())
Maybe solution worth to be included into TCPConnector as optional feature.
Pull Request is welcome!

Categories

Resources