I am trying to connect to Lightstremer to use the IG API streaming, and I would like to use the websockets library.
I am wondering if it is possible.
What I am struggling with is how to get the URI to use to create the connection with the server.
I can get the lightstreamer endpoint from IG and it looks like 'http://demo-apd.marketdatasystem.com'.
If I run
import websockets
import asyncio
ws_url = 'http://demo-apd.marketdatasystem.com/lighstreamer'
connection = await websockets.connect(ws_url)
I get the error https://demo-apd.marketdatasystems.com/lighstreamer isn't a valid URI
If I change the code below
ws_url = 'wss://demo-apd.marketdatasystem.com/lighstreamer'
connection = await websockets.connect(ws_url)
I have a message of failed connection
thanks for your time
Think you need to use a Lightstreamer client instead of WebSockets. As I understand it, they are two different protocols.
Official Python client from Lightstreamer - https://sdk.lightstreamer.com/ls-python-client/1.0.1/api/intro.html
Related
We have a FastApi app and using httpx AsyncClient for testing purposes. We are experiencing a problem where the unit tests run locally fine but fail on the CI server (Github Actions).
After further research we have come across this proposed solution by setting raise_server_exceptions=False to False.
client = TestClient(app, raise_server_exceptions=False)
However this is for the sync client. We are using the async client.
#pytest.fixture
async def client(test_app):
async with AsyncClient(app=test_app, base_url="http://testserver") as client:
yield client
The AsyncClient does not support the raise_app_exceptions=False option.
Does anyone have experience with this?
Thanks
The problem is caused by FastApi version. You can use fastapi==0.65.0 and even without the ASGITransport object and the raise_app_exceptions=False flag you will be able to run the tests which are checking for custom exception raising.
Also the fastapi version should be frozen in the requirements file.
You can read more here
For httpx v0.14.0+ you need to use httpx.ASGITransport.
Excerpt from the official documentation:
For some more complex cases you might need to customise the ASGI transport. This allows you to:
Inspect 500 error responses rather than raise exceptions by setting raise_app_exceptions=False.
Mount the ASGI application at a subpath by setting root_path.
Use a given client address for requests by setting client.
For example:
# Instantiate a client that makes ASGI requests with a client IP of "1.2.3.4",
# on port 123.
transport = httpx.ASGITransport(app=app, raise_app_exceptions=False,
client=("1.2.3.4", 123))
async with httpx.AsyncClient(transport=transport, base_url="http://testserver") as client:
...
I am trying to connect to binance websocket API using python. But it fails with this error: [Errno 8] nodename nor servname provided, or not known
import websocket
import sys
import pkg_resources
SOCKET = 'wss://stream.binance.com:9443/ws/ethusdt#kline_1m'
def on_open(ws):
print('opened connection')
def on_close(ws):
print('close connection')
def on_message(ws, message):
print('received message')
def on_error(ws, error):
print(error)
websocket.enableTrace(True)
ws = websocket.WebSocketApp(SOCKET, on_open=on_open, on_close=on_close, on_message=on_message, on_error=on_error)
ws.run_forever()
Anyone has an idea how should I resolve the issue. Are their APIs reliable?
Thanks in advance
Binanic api change consistently with each upgrade to the API. There a few ways of approaching the problem .
firstly check that the WSS socket is live ...
SOCKET = 'wss://stream.binance.com:9443/ws/ethusdt#kline_1m'
Then
A: check that you can log on manually through their documentation site as there live testing facility on there
If that is not successful.
B: Check that you API keys are still valid for account interaction
C: check the api version they currently using
E: on the API documentation there is live examples you can test the
get requests
D: Their service sometimes has limits on how often you can call their
API Make sure you within range
Over an above that if you have tested their api live examples for get requests there no reason that is should not work . As a rule of thumb I always use postman or insomnia to check the requests before I implement it in my own code as sometimes your header in the post requests do not match their header requirements
Insomnia
or
Postman
I personally always use the insomnia first to make sure the requests work then implement it in my code to match the format .
I am trying to connect to the Binance websocket stream.
Following their documentation I use the below code to establish the connection:
from websocket import create_connection
ws = create_connection('wss://fstream.binance.com/')
When running it though, I get the following error:
WebSocketBadStatusException: Handshake status 400 Bad Request
I could not find any info on the web about this error.
Does anyone know how to fix this?
This Point is somewhat unclear in the Binance API-Docs.
The base urls for the futures are:
wss://fstream.binance.com
wss://fstream3.binance.com
But if you just connect to these base urls you get the mentioned exception.
You should complement the url-strings to
wss://fstream.binance.com/ws
wss://fstream3.binance.com/ws
This is the same for spot markets and all the other websockets. Always put a "/ws" at the end.
You could also start subscribing with the connection-url then it looks like this spot-market example:
wss://stream.binance.com:9443/ws/btcusdt#aggTrade
(But i think connecting just with "/ws" and then live subscribing/unsubscribing as explained in the docs to streams is the better way.)
I gotta say it took me a long time to figure the solution out but here it goes.
Binance API documentation should be edited because it is missing the port for the fstream.binance.com
The port is 443.
So you should use
"fstream.binance.com:443" instead of
"fstream.binance.com".
Hope it helps. (Hell yeah it does!)
You could install python-binance and use the BinanceSocketManager
python -m pip install python-binance
Use the following code I found here
import time
from binance.client import Client # Import the Binance Client
from binance.websockets import BinanceSocketManager # Import the Binance Socket Manager
# Although fine for tutorial purposes, your API Keys should never be placed directly in the script like below.
# You should use a config file (cfg or yaml) to store them and reference when needed.
PUBLIC = '<YOUR-PUBLIC-KEY>'
SECRET = '<YOUR-SECRET-KEY>'
# Instantiate a Client
client = Client(api_key=PUBLIC, api_secret=SECRET)
# Instantiate a BinanceSocketManager, passing in the client that you instantiated
bm = BinanceSocketManager(client)
# This is our callback function. For now, it just prints messages as they come.
def handle_message(msg):
print(msg)
# Start trade socket with 'ETHBTC' and use handle_message to.. handle the message.
conn_key = bm.start_trade_socket('ETHBTC', handle_message)
# then start the socket manager
bm.start()
# let some data flow..
time.sleep(10)
# stop the socket manager
bm.stop_socket(conn_key)
You are missing the path on websocket connect!
Take a look to the binance api docs:
https://binance-docs.github.io/apidocs/futures/en/#websocket-market-streams
python-binance does not support websocket to binance futures endpoints, so you can use unicorn-binance-websocket-api instead, here is an example for future endpoints:
https://github.com/oliver-zehentleitner/unicorn-binance-websocket-api/blob/master/example_binance_futures.py
I built an web application using Python Bottle framework.
I used bottle-websocket plugin for WebSocket communication with clients.
Here is a part of my code.
from bottle import Bottle, request, run
from bottle.ext.websocket import GeventWebSocketServer, websocket
class MyHandler():
...
class MyServer(Bottle):
...
def _serve_websocket(self, ws):
handler = MyHandler()
some_data = request.cookies.get('some_key') # READ SOME DATA FROM HTTP REQUEST
while True:
msg = ws.receive()
handler.do_sth_on(msg, some_data) # USE THE DATA FROM HTTP REQUEST
ws.send(msg)
del(handler)
if __name__ == '__main__':
run(app=MyServer(), server=GeventWebSocketServer, host=HOST, port=PORT)
As the code shows, I need to read some data from the browser (cookies or anything in the HTTP request headers) and use it for WebSocket message processing.
How can I ensure the request is from the same browser session as the one where WebSocket connection comes?
NOTE
As I do not have much knowledge of HTTP and WebSocket, I'd love to here detailed answere as much as possible.
How can I ensure the request is from the same browser session as the one where WebSocket connection comes?
Browser session is a bit abstract since HTTP does not have a concept of sessions. HTTP and RESTful APIs is designed to be stateless, but there is options.
Usually, what you usually want to know is what user the request comes from. This is usually solved by authentication e.g. by using OpenID Connect and let the user send his JWT-token in the Authorization: header, this works for all HTTP requests, including when setting up a Websocket connection.
bottle-oauthlib seem to be a library for authenticating end-users using OAuth2 / OpenID Connect.
Another option is to identify the "browser session" using cookies but this depends on a state somewhere on the server side and is harder to implement on cloud native platforms like e.g. Kubernetes that prefer stateless workloads.
I want to connect to Socket.IO server using python. Is there a way to do it?
I have tried websocket-client as suggested in this answer.
ws = create_connection("ws://example.com:1000/socket.io/")
That code throws this exception
websocket._exceptions.WebSocketConnectionClosedException: Connection is already closed.
I feel like I am missing parameters because the JS client connection URL looks like this:
ws://example.com:1000/socket.io/?EIO=3&transport=websocket&sid=CHARSANDNUMBERS
You just need to use the url from the JS client, possibly without the sid:
ws = create_connection("ws://example.com:1000/socket.io/?EIO=3&transport=websocket")
From my personal experience I didn't have that sid param, but just try to add it if it doesn't work without.
You can look at this: socketIO-client
As an example,
from socketIO_client import SocketIO
socketIO = SocketIO('localhost', 8000)