I have a problem with asyncio, in this program I use asyncua that is for OPC protocol and asyncio_mqtt, my program should wait for connection to broker even if any problem occurred in broker side, it should wait until get connected again but this error happened:
Closing Loop
Reconnect to Server in 3 ...
Reconnect to Server in 2 ...
Traceback (most recent call last):
File "C:\Users\O.Fathi\PycharmProjects\OpcProject\final_main.py", line 310, in <module>
main(server_state)
File "C:\Users\O.Fathi\PycharmProjects\OpcProject\final_main.py", line 300, in main
clientMqtt = asyncio.SelectorEventLoop().run_until_complete(asyncio.wait([test()]))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\O.Fathi\AppData\Local\Programs\Python\Python311\Lib\asyncio\base_events.py", line 650, in run_until_complete
return future.result()
^^^^^^^^^^^^^^^
File "C:\Users\O.Fathi\AppData\Local\Programs\Python\Python311\Lib\asyncio\tasks.py", line 415, in wait
raise TypeError("Passing coroutines is forbidden, use tasks explicitly.")
TypeError: Passing coroutines is forbidden, use tasks explicitly.
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\O.Fathi\PycharmProjects\OpcProject\final_main.py", line 324, in <module>
asyncio.run(main(server_state))
^^^^^^^^^^^^^^^^^^
File "C:\Users\O.Fathi\PycharmProjects\OpcProject\final_main.py", line 300, in main
clientMqtt = asyncio.SelectorEventLoop().run_until_complete(asyncio.wait([test()]))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\O.Fathi\AppData\Local\Programs\Python\Python311\Lib\asyncio\base_events.py", line 650, in run_until_complete
return future.result()
^^^^^^^^^^^^^^^
File "C:\Users\O.Fathi\AppData\Local\Programs\Python\Python311\Lib\asyncio\tasks.py", line 415, in wait
raise TypeError("Passing coroutines is forbidden, use tasks explicitly.")
TypeError: Passing coroutines is forbidden, use tasks explicitly.
Reconnect to Server in 1 ...
sys:1: RuntimeWarning: coroutine 'test' was never awaited
Process finished with exit code 1
Here is some part of program, in main function, test function called and run async-mqtt:
import asyncio
import json
import logging
import time
from dataStructure import *
from opcConnection import *
from asyncua.ua import ObjectIds
from asyncua.ua.uatypes import NodeId
from asyncua import Client, Node, ua
from asyncio_mqtt import Client as ClientM
from asyncio_mqtt import MqttError
from asyncer import asyncify
async def test() -> None:
structPad = set_structure('>8sh')
structData = set_structure('<hffbb')
firstTime = True
timeSync = None
dataDict = {}
try:
logger.info("Connecting to MQTT")
async with ClientM(hostname="192.168.1.51", port=1883, client_id="OPC_client") as clientMqtt:
logger.info("Connection to MQTT open")
async with clientMqtt.unfiltered_messages() as messages:
await clientMqtt.subscribe(mqttTopic)
async for message in messages:
if message.topic == "TimeSync":
timeSync = message.payload
print(timeSync)
if firstTime:
await clientMqtt.publish("ready_to_Receive_opc_topic", payload="")
firstTime = False
if message.topic == "send_opc_tag":
print(message.payload.decode("UTF-8"))
dataBase, opcServers = await create_database(message)
dataDict, client = await create_dataDict(dataBase)
print(dataDict)
logger.info(
"Message %s %s", message.topic, message.payload
)
if message.topic == "Receive_OPC_Server":
bMessage = message.payload.decode('UTF-8')
# dataBase = json.loads(bMessage["send_opc_tag"])
client_rec = await opcConnection(bMessage)
if client_rec != 0:
nodesTree = await catchNodes(client_rec)
await clientMqtt.publish('OPC_Server_Tree', nodesTree)
print("Tree Cached")
else:
clientMqtt.publish('OPC_Server_Tree', "")
print("Not Tree")
if dataDict != {}:
dataDict = await get_values(dataDict, client)
value = []
percentt = []
id = []
for i in dataDict:
id.append(i)
if dataDict[i]["nodeList"] != []:
if dataDict[i]["values"][0] is None:
value.append(00.00)
dataDict[i]["percent"] = 00.00
percentt.append(0.0)
else:
value.append(dataDict[i]["values"][0])
dataDict[i]["percent"] = percentage(dataDict[i]["VMX"], dataDict[i]["VMN"],
dataDict[i]["values"])
percentt.append(dataDict[i]["percent"][0])
dataDict[i]["timeStamp"] = timeSync
dataDict[i]['bufferSize'] = buffer_data_get_padding(structPad, dataDict[i]["bufferSize"], 0,
timeSync, 1)
values = {
"id": id,
"values": value,
"percent": percentt,
"buffer": estimate_buffer_size(len(value))
}
buffer = values["buffer"]
buffer_data_get_padding(structPad, buffer, 0, timeSync, len(value))
buffer_data_get(structData, buffer, values)
print(values["values"])
await clientMqtt.publish("live_OPC_tags_value", payload=buffer)
except MqttError as e:
logger.error("Connection to MQTT closed: " + str(e))
except Exception:
logger.exception("Connection to MQTT closed")
await asyncio.sleep(3)
clientMqtt = None
server_state = True
def main(server_state):
mqttTopic = [("send_opc_tag", QOS_1), ("TimeSync", QOS_1), ("Receive_OPC_Server", QOS_1)]
clientMqtt = asyncio.SelectorEventLoop().run_until_complete(asyncio.wait([test()]))
if __name__ == "__main__":
try:
set_connection = True
main(server_state)
except KeyboardInterrupt:
pass
finally:
print("Closing Loop")
for i in range(3):
time.sleep(1)
print(f"Reconnect to Server in {3 - i} ...")
asyncio.run(main(server_state))
I wish I could have about 3k connections at once, but when running the server I'm having a bad crash (on about 500 connections in Win 10 x64 and on about 1019 connections on Ubuntu) with both of websockets libraries:
Here is the stresstestscript.py which cause the issue (even if I run this one in different machines over the lan):
import websocket,time
serveraddr="ws://localhost:12345"
ws = websocket.WebSocket()
ws.connect(serveraddr)
list = []
for b in range(3000):
list.append(websocket.WebSocket())
count=1
for x in list:
count+=1
x.connect(serveraddr)
time.sleep(0.01)
time.sleep(5000)
Here is the server.py (the exact sample on websockets official documentation):
#!/usr/bin/env python
# WS server example that synchronizes state across clients
import asyncio
import json
import logging
import websockets
logging.basicConfig()
STATE = {"value": 0}
USERS = set()
def state_event():
return json.dumps({"type": "state", **STATE})
def users_event():
return json.dumps({"type": "users", "count": len(USERS)})
async def notify_state():
if USERS: # asyncio.wait doesn't accept an empty list
message = state_event()
await asyncio.wait([user.send(message) for user in USERS])
async def notify_users():
if USERS: # asyncio.wait doesn't accept an empty list
message = users_event()
await asyncio.wait([user.send(message) for user in USERS])
async def register(websocket):
USERS.add(websocket)
print("add")
await notify_users()
async def unregister(websocket):
USERS.remove(websocket)
await notify_users()
async def counter(websocket, path):
# register(websocket) sends user_event() to websocket
await register(websocket)
try:
await websocket.send(state_event())
async for message in websocket:
data = json.loads(message)
if data["action"] == "minus":
STATE["value"] -= 1
await notify_state()
elif data["action"] == "plus":
STATE["value"] += 1
await notify_state()
else:
logging.error("unsupported event: %s", data)
finally:
await unregister(websocket)
start_server = websockets.serve(counter, "localhost", 12345)
asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()
Here is the server error (on windows, when exceed the 500 connections opened at once):
Traceback (most recent call last):
File "websockettestserver.py", line 70, in <module>
asyncio.get_event_loop().run_forever()
File "C:\Python37-32\lib\asyncio\base_events.py", line 539, in run_forever
self._run_once()
File "C:\Python37-32\lib\asyncio\base_events.py", line 1739, in _run_once
event_list = self._selector.select(timeout)
File "C:\Python37-32\lib\selectors.py", line 323, in select
r, w, _ = self._select(self._readers, self._writers, [], timeout)
File "C:\Python37-32\lib\selectors.py", line 314, in _select
r, w, x = select.select(r, w, w, timeout)
ValueError: too many file descriptors in select()
Like I said, I wish I could have more simultaneous connections, increasing the about 1000 connections on Linux to 3000-4000 (!?).
How to fix this?
1.run more diff server.py on diff port
2.use nginx to Distribute the requests
I want to connect WS API of Bitmex exchange(testnet.bitmex.com) and continuously fetch data.
I am using following code, it connects sucsessfully, but dont keep the connection, closing after recieving subscription data:
import time
import json
import hmac
import hashlib
secret ='7sol85dTkfWprpa03TbRFfgbnQDxpwiYP5PLspgYx_nNDSrn'
key='YPR0oojxqAR-2dp1J76BgNhT'
websocket_url = 'wss://testnet.bitmex.com/realtime?'
async def main():
expires = str(int(round(time.time())) + 5)
path = 'GET/realtime' + expires
signature = hmac.new(secret.encode(),path.encode(),hashlib.sha256).hexdigest()
async with websockets.connect(websocket_url + 'api-expires=' + expires + '&api-signature=' + signature + '&api-key=' + key) as ws:
request = {"op": "subscribe", "args": ['trade:XBTUSD', 'instrument:XBTUSD', 'quote:XBTUSD', 'position:XBTUSD']}
await ws.send(json.dumps(request))
while True:
result = await ws.recv()
print(result)
asyncio.run(main())
Here is result, you can see responses from API, but it closes after getting of subscription list.
In synchronous execution all goes fine
{"info":"Welcome to the BitMEX Realtime API.","version":"2019-07-18T21:20:16.000Z","timestamp":"2019-07-20T22:19:51.071Z","docs":"https://testnet.bitmex.com/app/wsAPI","limit":{"remaining":39}}
{"table":"trade","action":"partial","keys":[],"types":{"timestamp":"timestamp","symbol":"symbol","side":"symbol","size":"long","price":"float","tickDirection":"symbol","trdMatchID":"guid","grossValue":"long","homeNotional":"float","foreignNotional":"float"},"foreignKeys":{"symbol":"instrument","side":"side"},"attributes":{"timestamp":"sorted","symbol":"grouped"},"filter":{"symbol":"XBTUSD"},"data":[{"timestamp":"2019-07-20T22:19:43.770Z","symbol":"XBTUSD","side":"Buy","size":3,"price":10954,"tickDirection":"PlusTick","trdMatchID":"bff64535-4c5d-2a0a-8533-47e93091daa3","grossValue":27387,"homeNotional":0.00027387,"foreignNotional":3}]}
{"table":"quote","action":"partial","keys":[],"types":{"timestamp":"timestamp","symbol":"symbol","bidSize":"long","bidPrice":"float","askPrice":"float","askSize":"long"},"foreignKeys":{"symbol":"instrument"},"attributes":{"timestamp":"sorted","symbol":"grouped"},"filter":{"symbol":"XBTUSD"},"data":[{"timestamp":"2019-07-20T22:19:43.770Z","symbol":"XBTUSD","bidSize":1863,"bidPrice":10951,"askPrice":10954,"askSize":1403}]}
{"success":true,"subscribe":"trade:XBTUSD","request":{"op":"subscribe","args":["trade:XBTUSD","instrument:XBTUSD","quote:XBTUSD","position:XBTUSD"]}}
{"success":true,"subscribe":"instrument:XBTUSD","request":{"op":"subscribe","args":["trade:XBTUSD","instrument:XBTUSD","quote:XBTUSD","position:XBTUSD"]}}
{"success":true,"subscribe":"quote:XBTUSD","request":{"op":"subscribe","args":["trade:XBTUSD","instrument:XBTUSD","quote:XBTUSD","position:XBTUSD"]}}
{"success":true,"subscribe":"position:XBTUSD","request":{"op":"subscribe","args":["trade:XBTUSD","instrument:XBTUSD","quote:XBTUSD","position:XBTUSD"]}}
{"table":"position","action":"partial","keys":["account","symbol","currency"],"types":{"account":"long","symbol":"symbol","currency":"symbol","underlying":"symbol","quoteCurrency":"symbol","commission":"float","initMarginReq":"float","maintMarginReq":"float","riskLimit":"long","leverage":"float","crossMargin":"boolean","deleveragePercentile":"float","rebalancedPnl":"long","prevRealisedPnl":"long","prevUnrealisedPnl":"long","prevClosePrice":"float","openingTimestamp":"timestamp","openingQty":"long","openingCost":"long","openingComm":"long","openOrderBuyQty":"long","openOrderBuyCost":"long","openOrderBuyPremium":"long","openOrderSellQty":"long","openOrderSellCost":"long","openOrderSellPremium":"long","execBuyQty":"long","execBuyCost":"long","execSellQty":"long","execSellCost":"long","execQty":"long","execCost":"long","execComm":"long","currentTimestamp":"timestamp","currentQty":"long","currentCost":"long","currentComm":"long","realisedCost":"long","unrealisedCost":"long","grossOpenCost":"long","grossOpenPremium":"long","grossExecCost":"long","isOpen":"boolean","markPrice":"float","markValue":"long","riskValue":"long","homeNotional":"float","foreignNotional":"float","posState":"symbol","posCost":"long","posCost2":"long","posCross":"long","posInit":"long","posComm":"long","posLoss":"long","posMargin":"long","posMaint":"long","posAllowance":"long","taxableMargin":"long","initMargin":"long","maintMargin":"long","sessionMargin":"long","targetExcessMargin":"long","varMargin":"long","realisedGrossPnl":"long","realisedTax":"long","realisedPnl":"long","unrealisedGrossPnl":"long","longBankrupt":"long","shortBankrupt":"long","taxBase":"long","indicativeTaxRate":"float","indicativeTax":"long","unrealisedTax":"long","unrealisedPnl":"long","unrealisedPnlPcnt":"float","unrealisedRoePcnt":"float","simpleQty":"float","simpleCost":"float","simpleValue":"float","simplePnl":"float","simplePnlPcnt":"float","avgCostPrice":"float","avgEntryPrice":"float","breakEvenPrice":"float","marginCallPrice":"float","liquidationPrice":"float","bankruptPrice":"float","timestamp":"timestamp","lastPrice":"float","lastValue":"long"},"foreignKeys":{"symbol":"instrument"},"attributes":{"account":"sorted","symbol":"grouped","currency":"grouped","underlying":"grouped","quoteCurrency":"grouped"},"filter":{"account":92043,"symbol":"XBTUSD"},"data":[{"account":92043,"symbol":"XBTUSD","currency":"XBt","underlying":"XBT","quoteCurrency":"USD","commission":0.00075,"initMarginReq":0.25,"maintMarginReq":0.005,"riskLimit":20000000000,"leverage":4,"crossMargin":false,"deleveragePercentile":1,"rebalancedPnl":38942,"prevRealisedPnl":255686,"prevUnrealisedPnl":0,"prevClosePrice":10978.78,"openingTimestamp":"2019-07-20T22:00:00.000Z","openingQty":-100,"openingCost":991600,"openingComm":-4854,"openOrderBuyQty":0,"openOrderBuyCost":0,"openOrderBuyPremium":0,"openOrderSellQty":0,"openOrderSellCost":0,"openOrderSellPremium":0,"execBuyQty":0,"execBuyCost":0,"execSellQty":0,"execSellCost":0,"execQty":0,"execCost":0,"execComm":0,"currentTimestamp":"2019-07-20T22:19:50.061Z","currentQty":-100,"currentCost":991600,"currentComm":-4854,"realisedCost":0,"unrealisedCost":991600,"grossOpenCost":0,"grossOpenPremium":0,"grossExecCost":0,"isOpen":true,"markPrice":10966.17,"markValue":911900,"riskValue":911900,"homeNotional":-0.009119,"foreignNotional":100,"posState":"","posCost":991600,"posCost2":991600,"posCross":44500,"posInit":247900,"posComm":963,"posLoss":0,"posMargin":293363,"posMaint":5921,"posAllowance":0,"taxableMargin":0,"initMargin":0,"maintMargin":213663,"sessionMargin":0,"targetExcessMargin":0,"varMargin":0,"realisedGrossPnl":0,"realisedTax":0,"realisedPnl":4854,"unrealisedGrossPnl":-79700,"longBankrupt":0,"shortBankrupt":0,"taxBase":0,"indicativeTaxRate":0,"indicativeTax":0,"unrealisedTax":0,"unrealisedPnl":-79700,"unrealisedPnlPcnt":-0.0804,"unrealisedRoePcnt":-0.3215,"simpleQty":null,"simpleCost":null,"simpleValue":null,"simplePnl":null,"simplePnlPcnt":null,"avgCostPrice":10084.5,"avgEntryPrice":10084.5,"breakEvenPrice":10549.5,"marginCallPrice":14200.5,"liquidationPrice":14200.5,"bankruptPrice":14302,"timestamp":"2019-07-20T22:19:50.061Z","lastPrice":10966.17,"lastValue":911900}]}
Traceback (most recent call last):
File "E:/python/TRADE2/venv/2.py", line 37, in <module>
asyncio.run(main())
File "C:\Users\Padalecki\AppData\Local\Programs\Python\Python37-32\lib\asyncio\runners.py", line 43, in run
return loop.run_until_complete(main)
File "C:\Users\Padalecki\AppData\Local\Programs\Python\Python37-32\lib\asyncio\base_events.py", line 584, in run_until_complete
return future.result()
File "E:/python/TRADE2/venv/2.py", line 27, in main
result = await ws.recv()
File "E:\python\TRADE2\venv\lib\site-packages\websockets\protocol.py", line 485, in recv
await self.ensure_open()
File "E:\python\TRADE2\venv\lib\site-packages\websockets\protocol.py", line 772, in ensure_open
raise self.connection_closed_exc()
websockets.exceptions.ConnectionClosedOK: code = 1000 (OK), no reason
I tried to use run_forever():
loop = asyncio.get_event_loop()
loop.create_task(main())
loop.run_forever()
Same result
it did not helped
Your while loop is outside of the connect() context manager block, after the block is exited the connection is closed. You just need to indent some of your code
async with websockets.connect(websocket_url + 'api-expires=' + expires + '&api-signature=' + signature + '&api-key=' + key) as ws:
request = {"op": "subscribe", "args": ['trade:XBTUSD', 'instrument:XBTUSD', 'quote:XBTUSD', 'position:XBTUSD']}
await ws.send(json.dumps(request))
>>>>while True:
>>>> result = await ws.recv()
>>>> print(result)
I am new to Python and have some issues with my Discord Bot which I do not get fixed. The bot should automatically assign roles to users who join the server for the first time. I can set up autorole successfully. But when a user joins the server, the following error message appears in the console.
Ignoring exception in on_member_join
Traceback (most recent call last):
File "C:\Program Files\Python36\lib\site-packages\discord\client.py", line 307, in _run_event
yield from getattr(self, event)(*args, **kwargs)
File "E:/dev/DiscordBot/main.py", line 35, in on_member_join
await client.add_role(member, role)
File "C:\Program Files\Python36\lib\site-packages\discord\client.py", line 296, in __getattr__
raise AttributeError(msg.format(self.__class__, name))
AttributeError: '<class 'discord.client.Client'>' object has no attribute 'add_role'
C:\Program Files\Python36\lib\site-packages\discord\client.py:314: RuntimeWarning: coroutine 'get' was never awaited
pass
main.py
import discord
from discord.ext import commands
import SECRETS
import STATICS
from commands import cmd_autorole
client = discord.Client()
commands = dict(autorole=cmd_autorole)
#client.event
async def on_ready():
print("Bot is ready!")
await client.change_presence(game=discord.Game(name="with humans"))
#client.event
async def on_message(message):
if message.content.startswith(STATICS.PREFIX):
invoke = message.content[len(STATICS.PREFIX):].split(" ")[0]
args = message.content.split(" ")[1:]
if commands.__contains__(invoke):
await commands.get(invoke).ex(args, message, client, invoke)
else:
await client.send_message(message.channel, embed=discord.Embed(color=discord.Color.red(), description=("The command `%s` is not valid!" % invoke)))
#client.event
async def on_member_join(member):
# await client.send_message(member, "**Hello %s,**\n\nwelcome on Discord-Server __**%s**__!\nPlease look first at the main channel %s .\n\nHave Fun!" % (member.name, member.server.name, discord.utils.get(member.server.channels, id="532425431526277135").mention))
role = cmd_autorole.get(member.server)
if not role is None:
await client.add_role(member, role)
client.run(SECRETS.TOKEN)
cmd_autorole.py
import os
from os import path
import discord
async def error(content, channel, client):
await client.send_message(channel, embed=discord.Embed(color=discord.Color.red(), description=content))
async def get(server):
f = "SETTINGS/" + server.id + "/autorole"
if path.isfile(f):
with open(f) as f:
return discord.utils.get(server.roles, id=f.read())
else:
return None
async def savefile(id, server):
if not path.isdir("SETTINGS/" + server.id):
os.makedirs("SETTINGS/" + server.id)
with open("SETTINGS/" + server.id + "/autorole", "w") as f:
f.write(id)
f.close()
async def ex(args, message, client, invoke):
print(args)
if len(args) > 0:
rolename = args.__str__()[1:-1].replace(",", "").replace("'", "")
role = discord.utils.get(message.server.roles, name=rolename)
if role is None:
await error("Please enter a valid role existing on this server!", message.channel, client)
else:
try:
await savefile(role.id, message.server)
await client.send_message(message.channel, embed=discord.Embed(color=discord.Color.green(), description=("Autorole has been successfully set up for the Role `% s`." % role.name)))
except Exception:
await error("Something went wrong while saving autorole!", message.channel, client)
raise Exception
In your cmd_autorole.py file, the get() function is asynchronous, but you haven't awaited it in your main file.
You must to write role = await cmd_autorole.get(member.server) instead of role = cmd_autorole.get(member.server).
Instead of using #client.event for the second events try using #client.listenlike this:
#client.listen
async def on_message(message):
if message.content.startswith(STATICS.PREFIX):
invoke = message.content[len(STATICS.PREFIX):].split(" ")[0]
args = message.content.split(" ")[1:]
if commands.__contains__(invoke):
await commands.get(invoke).ex(args, message, client, invoke)
else:
await client.send_message(message.channel, embed=discord.Embed(color=discord.Color.red(), description=("The command `%s` is not valid!" % invoke)))
#client.listen
async def on_member_join(member):
# await client.send_message(member, "**Hello %s,**\n\nwelcome on Discord-Server __**%s**__!\nPlease look first at the main channel %s .\n\nHave Fun!" % (member.name, member.server.name, discord.utils.get(member.server.channels, id="532425431526277135").mention))
role = cmd_autorole.get(member.server)
if not role is None:
await client.add_role(member, role)