ecthiender / py-graphql-client Goto Github PK
View Code? Open in Web Editor NEWDead-simple GraphQL client with subscriptions over websockets
Home Page: https://pypi.org/project/py-graphql-client/
License: Other
Dead-simple GraphQL client with subscriptions over websockets
Home Page: https://pypi.org/project/py-graphql-client/
License: Other
Hello.
I only put :
from graphql_client import GraphQLClient
in a .py file and I get this :
ImportError: cannot import name 'GraphQLClient' from partially initialized module 'graphql_client' (most likely due to a circular import)
What is the problem ?
Thanks !
On Python 3.8.12 with py-graphql-client 0.1.1 and websockets-client 0.54.0 running on Ubuntu focal, I see this exception when I call close():
stopping 5990f26aabc1472bad9913d8d3cf34b9
Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/local/python/lib/python3.8/threading.py", line 932, in _bootstrap_inner
self.run()
File "/usr/local/python/lib/python3.8/threading.py", line 870, in run
self._target(*self._args, **self._kwargs)
File "/workspaces/serenity.core/venv/lib/python3.8/site-packages/graphql_client/__init__.py", line 118, in _receiver_task
user_fn(op_id, msg)
File "src/python/serenity/core/utils/rfb_check.py", line 17, in callback
client.close()
File "/workspaces/serenity.core/venv/lib/python3.8/site-packages/graphql_client/__init__.py", line 239, in close
self._recevier_thread.join()
File "/usr/local/python/lib/python3.8/threading.py", line 1008, in join
raise RuntimeError("cannot join current thread")
RuntimeError: cannot join current thread
Example that reproduces the issue:
from time import sleep
from graphql_client import GraphQLClient
client = GraphQLClient('ws://localhost:9002/graphql/subscriptions')
sub_ids = []
def callback(_id, data):
if data['type'] == 'complete':
for sub_id in sub_ids:
print(f'stopping {sub_id}')
client.stop_subscribe(sub_id)
client.close()
else:
print(f"msg id: {_id}. data: {data}")
query = """
subscription {
overallPortfolioSummaries {
weight
}
}
"""
sub_ids.append(client.subscribe(query, callback=callback))
Ignore this, stupid question fixed it my bad
HI ,
THIS MODULES HELPS US TO SUBSCRIPT TO A SERVICE , AFTER SUBSCRIPTION WE NEED TO KEEP TO CONNECTION OPEN TO RECEIVE POST REQUESTS WHEN EVER SERVER SENDS US , HOW DO WE HANDLE THAT ?
Can I get the Id of the web socket connection exposed on the GraphQlClient object? I wanted to use it for logging purposes and reconciliation with the server side records
How are things with python3.5 today?
Hi !, maybe my question is out the range of this library , but i need handle exception when the client lost connection whit the server for any reason, and don't found documentation above this.
If I connect to a URL of the form wss://...
I get an SSL error, but is SSL supported? I guess you need to provide a way to pass a native SSL context?
I'm running Python 3.5.2 on Ubuntu. Attempting to import GraphQLClient throws the following:
Traceback (most recent call last): File "this_one.py", line 1, in <module> from graphql_client import GraphQLClient File "/path/lib/python3.5/site-packages/graphql_client/__init__.py", line 102 err = f'Protocol Violation.\nExpected "id" in {msg}, but could not find.' ^ SyntaxError: invalid syntax
Looking into Python3 f-strings, it looks like they aren't supported until 3.6, but your docs state this lib just requires >= 3.4.
If there is an open subscription the client should automatically retry / reconnect, maybe with an exponential backoff. I have found the tenacity package helpful for this in the past.
Exception has occurred: WebSocketConnectionClosedException
Connection is already closed.
File "/workspaces/serenity.core/venv/lib/python3.8/site-packages/websocket/_socket.py", line 93, in recv
raise WebSocketConnectionClosedException(
File "/workspaces/serenity.core/venv/lib/python3.8/site-packages/websocket/_core.py", line 449, in _recv
return recv(self.sock, bufsize)
File "/workspaces/serenity.core/venv/lib/python3.8/site-packages/websocket/_abnf.py", line 396, in recv_strict
bytes_ = self.recv(min(16384, shortage))
File "/workspaces/serenity.core/venv/lib/python3.8/site-packages/websocket/_abnf.py", line 309, in recv_header
header = self.recv_strict(2)
File "/workspaces/serenity.core/venv/lib/python3.8/site-packages/websocket/_abnf.py", line 361, in recv_frame
self.recv_header()
File "/workspaces/serenity.core/venv/lib/python3.8/site-packages/websocket/_core.py", line 374, in recv_frame
return self.frame_buffer.recv_frame()
File "/workspaces/serenity.core/venv/lib/python3.8/site-packages/websocket/_core.py", line 340, in recv_data_frame
frame = self.recv_frame()
File "/workspaces/serenity.core/venv/lib/python3.8/site-packages/websocket/_core.py", line 327, in recv_data
opcode, frame = self.recv_data_frame(control_frame)
File "/workspaces/serenity.core/venv/lib/python3.8/site-packages/websocket/_core.py", line 310, in recv
opcode, data = self.recv_data()
File "/workspaces/serenity.core/venv/lib/python3.8/site-packages/graphql_client/__init__.py", line 85, in _receiver_task
res = self._connection.recv()
File "/usr/local/python/lib/python3.8/threading.py", line 870, in run
self._target(*self._args, **self._kwargs)
File "/usr/local/python/lib/python3.8/threading.py", line 932, in _bootstrap_inner
self.run()
File "/usr/local/python/lib/python3.8/threading.py", line 890, in _bootstrap
self._bootstrap_inner()
Adding a few checks to stop_subscribe to prevent threading issues when stop_subscribe is called explicitly.
(.venv) โ fetcher python main.py
--- request header ---
GET /graphql HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Host: localhost:8080
Origin: http://localhost:8080
Sec-WebSocket-Key: Y/T3i5rm6rUT2DcY1WBSHQ==
Sec-WebSocket-Version: 13
-----------------------
--- response header ---
HTTP/1.1 101 Switching Protocols
Server: nginx/1.17.7
Date: Sun, 12 Jan 2020 16:05:14 GMT
Connection: upgrade
Upgrade: websocket
Sec-WebSocket-Accept: YjXSZB3ABv2zrPKFRHWEQF4t4oQ=
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET, PUT, POST, DELETE, PATCH, OPTIONS
Access-Control-Allow-Headers: DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization
Strict-Transport-Security: max-age=15724800; includeSubDomains
-----------------------
send: b'\x81\xb9e\xd2\xe5\x7f\x1e\xf0\x91\x06\x15\xb7\xc7EE\xf0\x86\x10\x0b\xbc\x80\x1c\x11\xbb\x8a\x11:\xbb\x8b\x16\x11\xf0\xc9_G\xa2\x84\x06\t\xbd\x84\x1bG\xe8\xc5\x04G\xba\x80\x1e\x01\xb7\x97\x0cG\xe8\xc5\x11\x10\xbe\x89\x02\x18'
send: b'\x88\x82\x07\x08\x97\xd2\x04\xe0'
send: b'\x81\xfe\x00\x9e[\x92K\xb8 \xb0"\xdcy\xa8k\x9ak\xe2z\xe8n\xd1i\x94{\xb0?\xc1+\xf7i\x82{\xb08\xcc:\xe0?\x9aw\xb2i\xc8:\xeb\'\xd7:\xf6i\x82{\xe9i\xd0>\xf3/\xdd)\xe1i\x82{\xfc>\xd47\xbek\x9a*\xe7.\xca"\xb0q\x98y\xce%\xcb.\xf08\xdb)\xfb;\xcc2\xfd%\x98 \xce%\x98{\xf0\'\xd78\xf98\x98s\xe96\x91{\xe9\x17\xd6{\xb2k\x982\xf6k\xcb/\xf3?\xcd(\xcd%\xd96\xf7\x17\xd6{\xb26\xe45\xef\x17\xd6y\xbek\x9a-\xf39\xd1:\xf0\'\xdd(\xb0q\x985\xe7\'\xd4&\xef'
Traceback (most recent call last):
File "main.py", line 25, in <module>
id = ws.subscribe(query, callback=callback)
File "/Users/rd/Code/fetcher/.venv/lib/python3.7/site-packages/graphql_client/__init__.py", line 79, in subscribe
_id = self._start(payload)
File "/Users/rd/Code/fetcher/.venv/lib/python3.7/site-packages/graphql_client/__init__.py", line 58, in _start
self._conn.recv()
File "/Users/rd/Code/fetcher/.venv/lib/python3.7/site-packages/websocket/_core.py", line 310, in recv
opcode, data = self.recv_data()
File "/Users/rd/Code/fetcher/.venv/lib/python3.7/site-packages/websocket/_core.py", line 327, in recv_data
opcode, frame = self.recv_data_frame(control_frame)
File "/Users/rd/Code/fetcher/.venv/lib/python3.7/site-packages/websocket/_core.py", line 340, in recv_data_frame
frame = self.recv_frame()
File "/Users/rd/Code/fetcher/.venv/lib/python3.7/site-packages/websocket/_core.py", line 374, in recv_frame
return self.frame_buffer.recv_frame()
File "/Users/rd/Code/fetcher/.venv/lib/python3.7/site-packages/websocket/_abnf.py", line 361, in recv_frame
self.recv_header()
File "/Users/rd/Code/fetcher/.venv/lib/python3.7/site-packages/websocket/_abnf.py", line 309, in recv_header
header = self.recv_strict(2)
File "/Users/rd/Code/fetcher/.venv/lib/python3.7/site-packages/websocket/_abnf.py", line 396, in recv_strict
bytes_ = self.recv(min(16384, shortage))
File "/Users/rd/Code/fetcher/.venv/lib/python3.7/site-packages/websocket/_core.py", line 449, in _recv
return recv(self.sock, bufsize)
File "/Users/rd/Code/fetcher/.venv/lib/python3.7/site-packages/websocket/_socket.py", line 94, in recv
"Connection is already closed.")
websocket._exceptions.WebSocketConnectionClosedException: Connection is already closed.
Currently wss does not work. Add support for wss.
Hi @ecthiender .
Trying to implement your solution to reach the WS : wss://ws.sorare.com/cable (correct URL given by the dev team)
Wrote a basic subscription that works on Playground.
But infortunately my script returns :
subproto = headers.get("sec-websocket-protocol", None).lower()
AttributeError: 'NoneType' object has no attribute 'lower'
Any idea ?
Thanks !
Hey, obviously an issue probably isn't the best place to put this but there aren't many other feedback mechanisms on Github!
Just wanted to say thanks for your work! I mentioned before about more efficiently adding multiple callbacks to a single thread, was going to look at it today but it seems that your changes in e48ea36 have already addressed it!
From the tests I ran this morning it seems to be working well, with only one thread handling many separate subscriptions. I will test a bit further and put feedback here if that's alright?
Let me know if there are any other tasks you would like helping with for this package ๐
running the simple example on the homepage
from graphql_client import GraphQLClient
def callback(_id, data):
print("got new data..")
print(f"msg id: {_id}. data: {data}")
with GraphQLClient(endpoint) as client:
sub_id = client.subscribe(subscription,
# variables={'limit': 10},
headers=new_header,
callback=callback)
client.stop_subscribe(sub_id)
returns the following:
raceback (most recent call last):
File "dro_auth.py", line 91, in <module>
with GraphQLClient(endpoint) as client:
AttributeError: __enter__
Support GraphQLClient
to be used with a context manage a.k.a with
statement.
E.g -
with GraphQLClient('ws://localhost:8080/graphql') as client:
sub_id = client.subscribe(..)
...
client.stop_subscribe(sub_id)
referencing https://developer.github.com/v4/guides/using-the-explorer/
In the Key field, enter Authorization. In the Value field, enter Bearer , where is your generated OAuth token
How could we pass the Authorization header in this library?
When we set up a subscription the _start
method is consuming the first message sent by the subscriber which should not be happening. All the messages should be sent to the callback method passed.
The same applies to the query
method.
Hi,
I'm looking to pass some auth information in subscription parameters, but the payload for the connection initialization wraps the headers in a nested headers
attribute (here, instead of passing them as-is.
This assumes that the target server looks inside a headers
property on the incoming parameters - different servers handle these payloads differently. Some added flexibility to the client library will make it much more versatile and usable against various servers.
I will submit a quick PR to address this, but looking forward to hearing any thoughts!
Is there a way to send some flag to ignore ssl certificate check?
I have one environment which is failing to connect with below message:
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1131)
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.