You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+45-63Lines changed: 45 additions & 63 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,12 +2,11 @@
2
2
#### (Work in Progress!)
3
3
A port of apollographql subscriptions for python, using gevent websockets and redis
4
4
5
-
This is a implementation of apollographql [subscriptions-transport-ws](https://github.com/apollographql/subscriptions-transport-ws) and [graphql-subscriptions](https://github.com/apollographql/graphql-subscriptions) in Python. It currently implements a pubsub using [redis-py](https://github.com/andymccurdy/redis-py) and uses [gevent-websockets](https://bitbucket.org/noppo/gevent-websocket) for concurrency. It also makes heavy use of
6
-
[syrusakbary/promise](https://github.com/syrusakbary/promise) python implementation to mirror the logic in the apollo-graphql libraries.
5
+
This is a implementation of apollographql [subscriptions-transport-ws](https://github.com/apollographql/subscriptions-transport-ws) and [graphql-subscriptions](https://github.com/apollographql/graphql-subscriptions) in Python. It currently implements a pubsub using [redis-py](https://github.com/andymccurdy/redis-py) and uses [gevent-websockets](https://bitbucket.org/noppo/gevent-websocket) for concurrency. It also makes heavy use of [syrusakbary/promise](https://github.com/syrusakbary/promise) python implementation to mirror the logic in the apollo-graphql libraries.
7
6
8
-
Meant to be used in conjunction with [graphql-python](https://github.com/graphql-python) / [graphene](http://graphene-python.org/) server and [apollo-client](http://dev.apollodata.com/) for graphql.
7
+
Meant to be used in conjunction with [graphql-python](https://github.com/graphql-python) / [graphene](http://graphene-python.org/) server and [apollo-client](http://dev.apollodata.com/) for graphql. The api is below, but if you want more information, consult the apollo graphql libraries referenced above.
9
8
10
-
Very initial implementation. Currently only works with Python 2. No tests yet.
9
+
Initial implementation. Currently only works with Python 2. No tests yet.
-`args, kwargs`: additional position and keyword args will be passed
23
-
to Redis-py constructor
19
+
-`host`: Redis server instance url or IP (optional)
20
+
-`port`: Redis server port (optional)
21
+
-`args, kwargs`: Any additional position and keyword args will be passed to Redis-py constructor (optional)
24
22
25
23
#### Methods
26
-
-`publish(trigger_name, message)`: Trigger name is a subscription
27
-
or pubsub channel; message is the mutation object or message that will end
28
-
up being passed to the subscription root_value; this method will be called inside of
29
-
mutation resolve function
30
-
-`subscribe(trigger_name, on_message_handler, options)`: Trigger name
31
-
is a subscription or pubsub channel; on_message_handler is the callback
32
-
that will be triggered on each mutation; this method is called by the subscription
33
-
manager
34
-
-`unsubscribe(sub_id)`: Sub_id is the subscription ID that is being
35
-
tracked by the pubsub instance -- it is returned from the `subscribe` method
36
-
and called by the subscription manager
37
-
-`wait_and_get_message()`: Called by the subscribe method during the first
38
-
subscription for server; run in a separate greenlet and calls Redis `get_message()`
39
-
method to constantly poll for new messages on pubsub channels
40
-
-`handle_message(message)`: Called by pubsub when a message is
41
-
received on a subscribed channel; will check all existing pubsub subscriptons and
42
-
then calls `on_message_handler()` for all matches
24
+
-`publish(trigger_name, message)`: Trigger name is a subscription or pubsub channel; message is the mutation object or message that will end up being passed to the subscription as the root_value; this method should be called inside of mutation resolve function
25
+
-`subscribe(trigger_name, on_message_handler, options)`: Trigger name is a subscription or pubsub channel; on_message_handler is the callback that will be triggered on each mutation; this method is called by the subscription manager
26
+
-`unsubscribe(sub_id)`: Sub_id is the subscription ID that is being tracked by the pubsub instance -- it is returned from the `subscribe` method and called by the subscription manager
27
+
-`wait_and_get_message()`: Called by the `subscribe` method during the first subscription for the server; run in a separate greenlet and calls Redis `get_message()` method to constantly poll for new messages on pubsub channels
28
+
-`handle_message(message)`: Called by the pubsub when a message is received on a subscribed channel; will check all existing pubsub subscriptons and then calls `on_message_handler()` for all matches
-`pubsub`: Any pubsub instance with publish, subscribe, and unsubscribe methods (in this case an instance of the RedisPubsub class) (required)
34
+
-`setup_funcs`: Dictionary of setup functions that map from subscription name to a map of pubsub channel names and their filter functions; kwargs parameters are: `query, operation_name, callback, variables, context, format_error, format_response, args, subscription_name` (optional)
format_error, format_response)`: Called by ApolloSubscriptionServer upon
75
-
receiving a new subscription from a websocket. Arguments are parsed by
76
-
ApolloSubscriptionServer from graphql subscription query
77
-
-`unsubscribe(sub_id)`: Sub_id is the subscription ID that is being
78
-
tracked by the subscription manager instance -- returned from the
79
-
`subscribe()` method and called by the ApolloSubscriptionServer
50
+
-`publish(trigger_name, payload)`: Trigger name is the subscription or pubsub channel; payload is the mutation object or message that will end up being passed to the subscription root_value; method called inside of mutation resolve function
51
+
-`subscribe(query, operation_name, callback, variables, context, format_error, format_response)`: Called by ApolloSubscriptionServer upon receiving a new subscription from a websocket. Arguments are parsed by ApolloSubscriptionServer from the graphql subscription query
52
+
-`unsubscribe(sub_id)`: Sub_id is the subscription ID that is being tracked by the subscription manager instance -- returned from the `subscribe()` method and called by the ApolloSubscriptionServer
-`on_subscribe, on_unsubscribe, on_connect, on_disconnet`: TODO
56
+
-`subscription_manager`: A subscripton manager instance (required).
57
+
-`websocket`: The websocket object passed in from your route handler (required).
58
+
-`keep_alive`: The time period, in seconds, that the server will send keep alive messages to the client. (optional)
59
+
-`on_subscribe(message, subscription_parameters, websocket)`: Optional function to create custom params that will be used when resolving this subscription (optional)
60
+
-`on_unsubscribe(websocket)`: Optional function that is called when a client unsubscribes (optional)
61
+
-`on_connect(message_payload, websocket)`: Optional function that will be called when a client connects to the socket, called with the message_payload from the client, if the return value is an object, its elements will be added to the context. Return false or throw an exception to reject the connection. May return a Promise. (optional)
62
+
-`on_disconnect(websocket)`: Optional function that called when a client disconnects (optional)
87
63
88
64
#### Methods
89
-
- TODO
65
+
-`on_open()`: Called when the socket first opens; checks for correct subscription protocol and initializes keep alive messages
66
+
-`on_close(reason)`: Called when socket is closed; unsubscribes from subscriptions and deletes subscription objects
67
+
-`on_message(message)`: provides main control flow for all messaging exchanged between on socket between server and client; parses initial message, checks for exceptions, responds to client and subscribes / unsubscribes socket to mutation channels, via pubsub
68
+
-`unsubscribe(sub_id)`: Unsubscribes socket from subscriptions specified by client
69
+
-`timer()`: Timer for sending keep alive messages to client; run in separate greenlet per socket
70
+
-`send_init_result(result), send_keep_alive(), send_subscription_data(sub_id, payload), send_subscription_fail(sub_id, payload), send_subscription_success(sub_id)`: convenience methods for sending different messages and payloads to client
90
71
91
72
## Example Usage
92
73
#### Server (using Flask and Flask-Sockets):
93
74
94
75
```python
95
76
from flask import Flask
96
-
from flask_sqlalchemy import SQLAlchemy
97
77
from flask_sockets import Sockets
98
78
from graphql_subscriptions import (
99
79
SubscriptionManager,
@@ -104,10 +84,11 @@ from graphql_subscriptions import (
104
84
app = Flask(__name__)
105
85
106
86
# using Flask Sockets here, but could use gevent-websocket directly
107
-
# to create a websocket app
87
+
# to create a websocket app and attach it to flask app object
108
88
sockets = Sockets(app)
109
89
110
-
# instantiate pubsub
90
+
# instantiate pubsub -- this will be used to "publish" mutations
91
+
# and also to pass it into your subscription manager
111
92
pubsub = RedisPubsub()
112
93
113
94
# create schema using graphene or another python graphql library
@@ -118,11 +99,11 @@ schema = graphene.Schema(
118
99
subscription=Subscription
119
100
)
120
101
121
-
# instantiate subscription manager object--passing in schema and pubsub
102
+
# instantiate subscription manager object -- passing in schema and pubsub
0 commit comments