Reputation: 2394
I'm connecting to a websocket in an async function, to update a local mysql db
[edit: although only the coinbase websocket is shown here, it was later identified to be the gemini websocket that had the issue, by hitting the v1 instead of v2 websocket]
async def write_websocket_to_sql(exchange, symbol):
# handle different inputs to get the correct url and subscription message, and error check
url = wss://ws-feed.exchange.coinbase.com
subscription_message = {
"type": "subscribe",
"product_ids": ["BTCUSD"],
"channels": ["level2_batch", "heartbeat"]
}
async with websockets.connect(url) as ws:
# Subscribe to the websocket feed
await ws.send(json.dumps(subscription_message))
# Receive and process messages from the websocket
while True:
print("receiving message for ", ticker_symbol, " on ", exchange, " at ", datetime.datetime.now())
try:
message = await ws.recv()
except websockets.exceptions.ConnectionClosed:
print("Connection closed, reconnecting...")
await ws.send(json.dumps(subscription_message))
continue
print("message received success!")
data = json.loads(message)
I'm looking for an explanation as to why the async with websockets.connect(url) as ws:
line needs async
. await ws.send
is going to wait for the response either way
copilot originally added it in, and indeed, when I remove it I get the error
line 453, in write_websocket_to_sql
with websockets.connect(url) as ws:
AttributeError: __enter__
no idea why its trying to use a function that doesn't exist?
After changing it back to async
, I've started to get this error after a lot of successful pulls... but always within 5 seconds of starting the script.
File "/home/path/main.py", line 573, in main
await asyncio.gather(task1, task2)
File "/home/path/main.py", line 463, in write_websocket_to_sql
await ws.send(json.dumps(subscription_message))
File "/home/anaconda3/envs/py39/lib/python3.9/site-packages/websockets/legacy/protocol.py", line 619, in send
await self.ensure_open()
File "/home/anaconda3/envs/py39/lib/python3.9/site-packages/websockets/legacy/protocol.py", line 920, in ensure_open
raise self.connection_closed_exc()
websockets.exceptions.ConnectionClosedError: no close frame received or sent
so my questions are:
Upvotes: 0
Views: 756
Reputation: 2394
The websocket is closing the connection remotely. The error was occurring from using the Gemini websocket v1 instead of v2 for market data.
Upvotes: 0
Reputation: 7158
async
, it's about protocol that implements context managers in python.In case of with
keyword python calls __enter__
method when entering and __exit__
.
with 1: # AttributeError: __enter__
pass
int
nor websockets.connect(url)
class has implemented __enter__
, so you get such error.
async_with
assumes __aenter__
and __aexit__
are implemented, which is the case here.
Upvotes: 1