slazarov / python-signalr-client Goto Github PK
View Code? Open in Web Editor NEWSignalR client for python based on asyncio.
License: MIT License
SignalR client for python based on asyncio.
License: MIT License
pip install signalr-client-aio
Collecting signalr-client-aio
Using cached https://files.pythonhosted.org/packages/83/90/82d1e2feffb173ad9d9c9e25f395eabec11c3426b5cb134a689227222d5d/signalr_client_aio-0.0.1.6.2-py2.py3-none-any.whl
Requirement already satisfied: requests>=2.18.4 in c:\users\terminal-3\anaconda3\lib\site-packages (from signalr-client-aio) (2.21.0)
Collecting websockets>=4.0.1 (from signalr-client-aio)
Using cached https://files.pythonhosted.org/packages/9c/60/f96f535f3354cb6ba5e5c7ab128b1c4802a2d040ee7225e3fe51242816c1/websockets-8.0.2-cp37-cp37m-win_amd64.whl
Requirement already satisfied: certifi>=2017.4.17 in c:\users\terminal-3\anaconda3\lib\site-packages (from requests>=2.18.4->signalr-client-aio) (2018.11.29)
Requirement already satisfied: idna<2.9,>=2.5 in c:\users\terminal-3\anaconda3\lib\site-packages (from requests>=2.18.4->signalr-client-aio) (2.8)
Requirement already satisfied: urllib3<1.25,>=1.21.1 in c:\users\terminal-3\anaconda3\lib\site-packages (from requests>=2.18.4->signalr-client-aio) (1.24.1)
Requirement already satisfied: chardet<3.1.0,>=3.0.2 in c:\users\terminal-3\anaconda3\lib\site-packages (from requests>=2.18.4->signalr-client-aio) (3.0.4)
Could not install packages due to an EnvironmentError: [Errno 2] No such file or directory: 'c:\users\terminal-3\anaconda3\lib\site-packages\pandas-0.24.2.dist-info\METADATA'
Hi Stanislav,
I'm trying your signalr-client-aio and it is working perfectly for the given methods:
Though when I'm trying to invoke two other requests, i.e.:
hub.server.invoke('querySummaryState', 'BTC-ETH')
hub.server.invoke('SubscribeToSummaryLiteDeltas', 'BTC-ETH')
i get the following error messages:
A bit of googling around showed that this could sign something going wrong at Bittrex server side. Therefore: Does this occur to others as well?
Or does the client not feature these methods?
I'm running Python 3.7 in a Jupyter Notebook environment.
I am trying your library with python 3.6.5
However, when I try to connect to my vendor signalr endpoint, I got the following error:
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/signalr_aio/_connection.py", line 36, in start
self.__transport.start()
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/signalr_aio/transports/_transport.py", line 47, in start
self.ws_loop.run_until_complete(self.socket(self.ws_loop))
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/asyncio/base_events.py", line 468, in run_until_complete
return future.result()
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/signalr_aio/transports/_transport.py", line 59, in socket
loop=loop) as self.ws:
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/websockets/py35/client.py", line 2, in aenter
return await self
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/websockets/py35/client.py", line 19, in await_impl
extra_headers=protocol.extra_headers,
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/websockets/client.py", line 263, in handshake
raise InvalidStatusCode(status_code)
websockets.exceptions.InvalidStatusCode: Status code not 101: 400
Can you help me with this issue?
I have tried with this library https://github.com/TargetProcess/signalr-client-py and it is able to connect sucessfully. However, the project doesn't seem active recently, so i wanna try different available packages.
I'm trying to run the sample code from bittrex, which uses your library:
https://bittrex.github.io/api/v3#topic-Example-Socket-Clients
But I get this error:
TypeError: As of 3.10, the loop parameter was removed from Queue() since it is no longer necessary
traceback:
Traceback (most recent call last):
File "...\V3WebsocketExample.py", line 127, in
asyncio.run(main())
File "...\Python310\lib\asyncio\runners.py", line 44, in run
return loop.run_until_complete(main)
File "...\Python310\lib\asyncio\base_events.py", line 646, in run_until_complete
return future.result()
File "...\V3WebsocketExample.py", line 32, in main
await connect()
File "...\V3WebsocketExample.py", line 43, in connect
connection = Connection(URL)
File "...\Python310\lib\site-packages\signalr_aio_connection.py", line 24, in init
self.__transport = Transport(self)
File "...\Python310\lib\site-packages\signalr_aio\transports_transport.py", line 34, in init
self._set_loop()
File "...\Python310\lib\site-packages\signalr_aio\transports_transport.py", line 42, in _set_loop
self.invoke_queue = asyncio.Queue(loop=self.ws_loop)
File "...\Python310\lib\asyncio\queues.py", line 34, in init
super().init(loop=loop)
File "...\Python310\lib\asyncio\mixins.py", line 17, in init
raise TypeError(
TypeError: As of 3.10, the loop parameter was removed from Queue() since it is no longer necessary
_transport.py uses
except ModuleNotFoundError
which I think is new in 3.6.
16:15:23 24-02-2019, CRITICAL [bittrex.py:bittrex:run_blocking:135] Traceback (most recent call last):
File "/usr/local/lib/python3.7/site-packages/websockets/protocol.py", line 674, in transfer_data
message = yield from self.read_message()
File "/usr/local/lib/python3.7/site-packages/websockets/protocol.py", line 742, in read_message
frame = yield from self.read_data_frame(max_size=self.max_size)
File "/usr/local/lib/python3.7/site-packages/websockets/protocol.py", line 815, in read_data_frame
frame = yield from self.read_frame(max_size)
File "/usr/local/lib/python3.7/site-packages/websockets/protocol.py", line 884, in read_frame
extensions=self.extensions,
File "/usr/local/lib/python3.7/site-packages/websockets/framing.py", line 99, in read
data = yield from reader(2)
File "/usr/local/lib/python3.7/asyncio/streams.py", line 679, in readexactly
await self._wait_for_data('readexactly')
File "/usr/local/lib/python3.7/asyncio/streams.py", line 473, in _wait_for_data
await self._waiter
concurrent.futures._base.CancelledError
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/code/data_api/bittrex.py", line 133, in run_blocking
self.run()
File "/code/data_api/bittrex.py", line 128, in run
connection.start()
File "/usr/local/lib/python3.7/site-packages/signalr_aio/_connection.py", line 36, in start
self.__transport.start()
File "/usr/local/lib/python3.7/site-packages/signalr_aio/transports/_transport.py", line 47, in start
self.ws_loop.run_until_complete(self.socket(self.ws_loop))
File "/usr/local/lib/python3.7/asyncio/base_events.py", line 584, in run_until_complete
return future.result()
File "/usr/local/lib/python3.7/site-packages/signalr_aio/transports/_transport.py", line 61, in socket
await self.handler(self.ws)
File "/usr/local/lib/python3.7/site-packages/signalr_aio/transports/_transport.py", line 70, in handler
loop=self.ws_loop, return_exceptions=False)
File "/usr/local/lib/python3.7/site-packages/signalr_aio/transports/_transport.py", line 77, in consumer_handler
message = await ws.recv()
File "/usr/local/lib/python3.7/site-packages/websockets/protocol.py", line 434, in recv
yield from self.ensure_open()
File "/usr/local/lib/python3.7/site-packages/websockets/protocol.py", line 658, in ensure_open
) from self.transfer_data_exc
websockets.exceptions.ConnectionClosed: WebSocket connection is closed: code = 1006 (connection closed abnormally [internal]), no reason
Hi, thank you very much for this. I don't like the "wait" thing with the other signalR module, so I think async is a nice solution.
Unfortunately I still use python 3.4 and don't want to update.
So can I simply replace:
"async def..." with
"@asyncio.coroutine
def ..."
"await" with "yield from"
"async with session.get(url) as r:" with "r = yield from session.get(url)"
and everything is fine? Or is it more complex?
edit:
Just saw you also use "async for".. I found no short alternative for this, just a big block of code in last example of response here: https://stackoverflow.com/questions/34338518/async-for-in-python-3-4
I just want to invoke an event on server and then receive some message, like the local method call.
e.g.
msg = hub.server.invoke('SubscribeToExchangeDeltas', 'BTC-ETH')
Thanks,
Hi @slazarov!
First of thank you for this great library. It's really helpful.
I've experimented a little to get the project ready for Python 3.10 in order to use it for (Fast-F1)[https://github.com/theOehrly/Fast-F1]. It seems like it could be pretty straight forward: oscr@45edbc4
How would you feel about making a new release with Python 3.10 support?
EDIT: I can make a pr for it just to be clear.
Should asyncio.ensure_future
be considered for this call? Currently, I've been wrapping the start
invocation on the connection
module in a coroutine anyway. Any reason why it should not natively be a coroutine?
My websocket connection towards the signalr endpoint seems to drop every now and then, is there any way to capture this exception and reconnect? My lack of Python-fu is sever.
message = await ws.recv()
File "/srv/code/lib/python3.6/site-packages/websockets/protocol.py", line 350, in recv
yield from self.ensure_open()
File "/srv/code/lib/python3.6/site-packages/websockets/protocol.py", line 501, in ensure_open
self.close_code, self.close_reason) from self.transfer_data_exc
websockets.exceptions.ConnectionClosed: WebSocket connection is closed: code = 1006 (connection closed abnormally [internal]), no reason
I'm using the following code:
try:
connection = Connection(self._stream, session=session)
hub = connection.register_hub('myHub')
connection.received += self.on_signalr_debug
connection.error += self.on_signalr_error
hub.client.on('NewStuff', self.on_signalr_stuff)
connection.start()
hub.server.invoke('authenticate', login, token)
hub.server.invoke('coolStuff', mystuff)
except Exception as err:
_LOGGER.exception("Exception (%s) from SignalR", str(err))
But the Exception is never triggered? Because everything runs in asyncio in eventloop?
My connection sometime stops receiving messages and would be nice to be able to raise an exception when there hasn't been a message so that you can do something about it. Or is there another way of doing this?
My problem is that I'm unable to use the library with Cryptopia's websocket.
Cryptopia's websocket is a totally undocumented, non-public websocket.
It also uses signalR. The endpoint url is www.cryptopia.co.nz/signalr and the hub is called 'notificationHub'.
I just tried to modify the example code:
from base64 import b64decode
from zlib import decompress, MAX_WBITS
import json
async def process_message(message):
deflated_msg = decompress(b64decode(message), -MAX_WBITS)
return json.loads(deflated_msg.decode())
# Create debug message handler.
async def on_debug(**msg):
# In case of 'queryExchangeState'
if 'R' in msg and type(msg['R']) is not bool:
decoded_msg = await process_message(msg['R'])
print(decoded_msg)
# Create error handler
async def on_error(msg):
print(msg)
# Create hub message handler
async def on_message(msg):
decoded_msg = await process_message(msg[0])
print(decoded_msg)
if __name__ == "__main__":
# Create connection
# Users can optionally pass a session object to the client, e.g a cfscrape session to bypass cloudflare.
connection = Connection('https://www.cryptopia.co.nz/signalr', session=None)
# Register hub
hub = connection.register_hub('notificationHub')
# Assign debug message handler. It streams unfiltered data, uncomment it to test.
connection.received += on_debug
# Assign error handler
connection.error += on_error
# Assign hub message handler
hub.client.on('uE', on_message)
hub.client.on('uS', on_message)
# Send a message
hub.server.invoke('setTradePairSubscription', 1, 2)
# Start the client
connection.start()
But I always get the following error:
File "some_path\signalr_aio\hubs_hub.py", line 43, in handle
await self.__handlers[method](message)
KeyError: 'SendTradeDataUpdate'
What's the problem?
Hi!
As far as I understand this does NOT support SignalR Core. Could anyone confirm it?
Hi,
I wanted to try out the library, but it's not working for me. I copy pasted your example code under sample usage. I'm using the 0.0.1.5 version from PyPi.
Traceback (most recent call last):
File "/home/meister245/virtualenv/py3_virtual/lib/python3.5/site-packages/signalr_aio/transports/_transport.py", line 67, in consumer_handler
async for message in ws:
TypeError: 'async for' requires an object with __aiter__ method, got WebSocketClientProtocol
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "bittrex.py", line 51, in <module>
connection.start()
File "/home/meister245/virtualenv/py3_virtual/lib/python3.5/site-packages/signalr_aio/_connection.py", line 36, in start
self.__transport.start()
File "/home/meister245/virtualenv/py3_virtual/lib/python3.5/site-packages/signalr_aio/transports/_transport.py", line 39, in start
self.ws_loop.run_until_complete(self.socket(self.ws_loop))
File "uvloop/loop.pyx", line 1364, in uvloop.loop.Loop.run_until_complete
File "/usr/lib/python3.5/asyncio/futures.py", line 274, in result
raise self._exception
File "/usr/lib/python3.5/asyncio/tasks.py", line 239, in _step
result = coro.send(None)
File "/home/meister245/virtualenv/py3_virtual/lib/python3.5/site-packages/signalr_aio/transports/_transport.py", line 53, in socket
await self.handler(ws)
File "/home/meister245/virtualenv/py3_virtual/lib/python3.5/site-packages/signalr_aio/transports/_transport.py", line 60, in handler
loop=self.ws_loop, return_exceptions=False)
File "/usr/lib/python3.5/asyncio/futures.py", line 361, in __iter__
yield self # This tells Task to wait for completion.
File "/usr/lib/python3.5/asyncio/tasks.py", line 296, in _wakeup
future.result()
File "/usr/lib/python3.5/asyncio/futures.py", line 274, in result
raise self._exception
File "/usr/lib/python3.5/asyncio/tasks.py", line 239, in _step
result = coro.send(None)
File "/home/meister245/virtualenv/py3_virtual/lib/python3.5/site-packages/signalr_aio/transports/_transport.py", line 72, in consumer_handler
raise Exception
Exception
Task was destroyed but it is pending!
task: <Task pending coro=<Transport.producer_handler() running at /home/meister245/virtualenv/py3_virtual/lib/python3.5/site-packages/signalr_aio/transports/_transport.py:77> wait_for=<Future pending cb=[Task._wakeup()]> cb=[gather.<locals>._done_callback(1)() at /usr/lib/python3.5/asyncio/tasks.py:637]>
Hi
I want to send token as query string to authenticate?
How Do I do???
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.