FastAPI websocket can not connect - python

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...")

Related

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.

Python websocket asyncio using the same connection more than once

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.

How to do a get request inside a Django Channels consumer connect method?

I'm trying to do a get request for a seperate django CRUD API app inside a Django Channels app connect method
So inside the consumers.py I'm doing this
class AssistantConsumer(AsyncWebsocketConsumer):
async def connect(self):
self.commands = requests.get('http://localhost:8000/api/commands')
print(self.commands)
Doing this results in the websocket getting stuck on
WebSocket HANDSHAKING /ws/assistant/user/ [127.0.0.1:64374]
Can anyone tell me why?
The API is working on it's own, I'm posting to it from React, which also connects to the websocket. All that is working - I just need to fetch some data from the database in the consumer.
Couldn't find anything anywhere about this situation.
OK I found a solution - don't know if it's the right one or how stable it is but this package on PyPi does the trick.
https://pypi.org/project/requests-async/
Thanks to Timothee for pointing out that I needed to be doing it async.
This now works.
import requests_async as requests
async def connect(self):
self.commands = await requests.get('http://localhost:8000/api/commands/')
print(self.commands)
await self.accept()
Maybe this will help someone else and if anyone knows of a reason I shouldn't be doing this I'd be interested to know.
async def connect is only called when a client attempts a connection and your routing file sends the incoming connection to your AssistantConsumer. In your case, you are getting stuck on this initial 'handshake'. This means that you are receiving the request to connect from the client but you are not accepting that connection and therefore the WebSocket connection is never opened.
Adding await self.accept() should accept the incoming connection and therefore open the WebSocket.
This is what it would look like:
class AssistantConsumer(AsyncWebsocketConsumer):
async def connect(self):
self.commands = requests.get('http://localhost:8000/api/commands')
print(self.commands)
await self.accept()

405 Client Error: Method Not Allowed for url: https://rinkeby.infura.io PYTHON

I Can't call create filter on my contract, this is my code below- I am able to get the contract and run functions on it, but I cant listen to events:
myContract = w3.eth.contract(address="some_address",abi=contract_abi)
This is where I run into issues:
myfilter_new= myContract.events.Transfer.createFilter(fromBlock=0, toBlock='latest')
this is the issue I get:
HTTPError at /testing/
405 Client Error: Method Not Allowed for url: https://rinkeby.infura.io/my_api_key
As #smarx said, INFURA does not supports filters over HTTP. They do have some support over sockets, but I believe it is not yet production ready. It's worth a try, though.
Web3.py has a built-in way to connect using websockets that you can initialize like so:
from web3 import Web3
w3 = Web3(Web3.WebsocketProvider("wss://mainnet.infura.io/ws"))

Python 3.6 - Sanic Motorengine

I am trying to setup the new Sanic web framework (which is promised to be extremely fast) with motorengine in order to achieve 100% async.
My setup so far:
app = Sanic(__name__)
#app.listener('after_server_start')
async def setup_dbconn(app, loop):
connect("database_name", username="user", password="pass", host="192.168.1.200", port=27017, io_loop=asyncio.get_event_loop())
Unfortunately I get:
motorengine.connection.ConnectionError: Cannot connect to database default :
Unknown option username
Why does this crash?
The specific problem you encounter is not about Sanic but has to do with motorengine.
Use the database URI to connect:
motorengine.connect(
db=name,
alias=alias,
host="mongodb://username:password#localhost:port",
io_loop=tornado.ioloop.IOLoop.instance()
)
The solution came from this ticket: https://github.com/heynemann/motorengine/issues/82.
PS: For Sanic >= 0.4.0 you should consider using sanic-motor extension!

Categories

Resources