Skip to content

Commit abd73b9

Browse files
committed
Django Channels v2
1 parent 660a0e0 commit abd73b9

14 files changed

Lines changed: 963 additions & 3 deletions

File tree

README.md

Lines changed: 79 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,6 @@ You can see a full example here: https://github.com/graphql-python/graphql-ws/tr
132132

133133
### Django Channels
134134

135-
136135
First `pip install channels` and it to your django apps
137136

138137
Then add the following to your settings.py
@@ -202,4 +201,82 @@ from graphql_ws.django_channels import GraphQLSubscriptionConsumer
202201
channel_routing = [
203202
route_class(GraphQLSubscriptionConsumer, path=r"^/subscriptions"),
204203
]
205-
```
204+
```
205+
206+
### Django Channels 2
207+
208+
Set up with Django Channels just takes three steps:
209+
210+
1. Install the apps
211+
2. Set up schema
212+
3. Set up channels Router
213+
214+
215+
First `pip install channels` and it to your `INSTALLED_APPS`. If you want
216+
graphiQL, install `graphql_ws.django` app before `graphene_django` to serve a
217+
graphiql template that will work with websockets:
218+
219+
```python
220+
INSTALLED_APPS = [
221+
"channels",
222+
"graphql_ws.django",
223+
"graphene_django",
224+
# ...
225+
]
226+
```
227+
228+
229+
Next, set up your graphql schema:
230+
231+
```python
232+
import graphene
233+
from rx import Observable
234+
235+
236+
class Query(graphene.ObjectType):
237+
hello = graphene.String()
238+
239+
def resolve_hello(self, info, **kwargs):
240+
return "world"
241+
242+
243+
class Subscription(graphene.ObjectType):
244+
245+
count_seconds = graphene.Int(up_to=graphene.Int())
246+
247+
def resolve_count_seconds(root, info, up_to=5):
248+
return (
249+
Observable.interval(1000)
250+
.map(lambda i: "{0}".format(i))
251+
.take_while(lambda i: int(i) <= up_to)
252+
)
253+
254+
255+
schema = graphene.Schema(query=Query, subscription=Subscription)
256+
```
257+
258+
...and point to your schema in Django settings
259+
```python
260+
GRAPHENE = {
261+
'SCHEMA': 'yourproject.schema'
262+
}
263+
```
264+
265+
266+
Finally, configure channels routing (it'll be served from `/subscriptions`):
267+
268+
```python
269+
from channels.routing import ProtocolTypeRouter, URLRouter
270+
from graphql_ws.django.graphql_channels import (
271+
websocket_urlpatterns as graphql_urlpatterns
272+
)
273+
274+
application = ProtocolTypeRouter({"websocket": URLRouter(graphql_urlpatterns)})
275+
```
276+
277+
...and point to the application in Django settings
278+
```python
279+
ASGI_APPLICATION = 'yourproject.schema'
280+
```
281+
282+
Run `./manage.py runserver` and go to `http://localhost:8000/graphql` to test!

README.rst

Lines changed: 179 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ Websocket server for GraphQL subscriptions.
55

66
Currently supports: \*
77
`aiohttp <https://github.com/graphql-python/graphql-ws#aiohttp>`__ \*
8-
`Gevent <https://github.com/graphql-python/graphql-ws#gevent>`__
8+
`Gevent <https://github.com/graphql-python/graphql-ws#gevent>`__ \*
9+
Sanic (uses `websockets <https://github.com/aaugustin/websockets/>`__
10+
library)
911

1012
Installation instructions
1113
=========================
@@ -44,6 +46,29 @@ For setting up, just plug into your aiohttp server.
4446
4547
web.run_app(app, port=8000)
4648
49+
Sanic
50+
~~~~~
51+
52+
Works with any framework that uses the websockets library for it's
53+
websocket implementation. For this example, plug in your Sanic server.
54+
55+
.. code:: python
56+
57+
from graphql_ws.websockets_lib import WsLibSubscriptionServer
58+
59+
60+
app = Sanic(__name__)
61+
62+
subscription_server = WsLibSubscriptionServer(schema)
63+
64+
@app.websocket('/subscriptions', subprotocols=['graphql-ws'])
65+
async def subscriptions(request, ws):
66+
await subscription_server.handle(ws)
67+
return ws
68+
69+
70+
app.run(host="0.0.0.0", port=8000)
71+
4772
And then, plug into a subscribable schema:
4873

4974
.. code:: python
@@ -111,3 +136,156 @@ And then, plug into a subscribable schema:
111136
112137
You can see a full example here:
113138
https://github.com/graphql-python/graphql-ws/tree/master/examples/flask\_gevent
139+
140+
Django Channels
141+
~~~~~~~~~~~~~~~
142+
143+
First ``pip install channels`` and it to your django apps
144+
145+
Then add the following to your settings.py
146+
147+
.. code:: python
148+
149+
CHANNELS_WS_PROTOCOLS = ["graphql-ws", ]
150+
CHANNEL_LAYERS = {
151+
"default": {
152+
"BACKEND": "asgiref.inmemory.ChannelLayer",
153+
"ROUTING": "django_subscriptions.urls.channel_routing",
154+
},
155+
156+
}
157+
158+
Setup your graphql schema
159+
160+
.. code:: python
161+
162+
import graphene
163+
from rx import Observable
164+
165+
166+
class Query(graphene.ObjectType):
167+
hello = graphene.String()
168+
169+
def resolve_hello(self, info, **kwargs):
170+
return 'world'
171+
172+
class Subscription(graphene.ObjectType):
173+
174+
count_seconds = graphene.Int(up_to=graphene.Int())
175+
176+
177+
def resolve_count_seconds(
178+
root,
179+
info,
180+
up_to=5
181+
):
182+
return Observable.interval(1000)\
183+
.map(lambda i: "{0}".format(i))\
184+
.take_while(lambda i: int(i) <= up_to)
185+
186+
187+
188+
schema = graphene.Schema(
189+
query=Query,
190+
subscription=Subscription
191+
)
192+
193+
Setup your schema in settings.py
194+
195+
.. code:: python
196+
197+
GRAPHENE = {
198+
'SCHEMA': 'path.to.schema'
199+
}
200+
201+
and finally add the channel routes
202+
203+
.. code:: python
204+
205+
from channels.routing import route_class
206+
from graphql_ws.django_channels import GraphQLSubscriptionConsumer
207+
208+
channel_routing = [
209+
route_class(GraphQLSubscriptionConsumer, path=r"^/subscriptions"),
210+
]
211+
212+
Django Channels 2
213+
~~~~~~~~~~~~~~~~~
214+
215+
Set up with Django Channels just takes three steps:
216+
217+
1. Install the apps
218+
2. Set up schema
219+
3. Set up channels Router
220+
221+
First ``pip install channels`` and it to your ``INSTALLED_APPS``. If you
222+
want graphiQL, install ``graphql_ws.django`` app before
223+
``graphene_django`` to serve a graphiql template that will work with
224+
websockets:
225+
226+
.. code:: python
227+
228+
INSTALLED_APPS = [
229+
"channels",
230+
"graphql_ws.django",
231+
"graphene_django",
232+
# ...
233+
]
234+
235+
Next, set up your graphql schema:
236+
237+
.. code:: python
238+
239+
import graphene
240+
from rx import Observable
241+
242+
243+
class Query(graphene.ObjectType):
244+
hello = graphene.String()
245+
246+
def resolve_hello(self, info, **kwargs):
247+
return "world"
248+
249+
250+
class Subscription(graphene.ObjectType):
251+
252+
count_seconds = graphene.Int(up_to=graphene.Int())
253+
254+
def resolve_count_seconds(root, info, up_to=5):
255+
return (
256+
Observable.interval(1000)
257+
.map(lambda i: "{0}".format(i))
258+
.take_while(lambda i: int(i) <= up_to)
259+
)
260+
261+
262+
schema = graphene.Schema(query=Query, subscription=Subscription)
263+
264+
...and point to your schema in Django settings
265+
266+
.. code:: python
267+
268+
GRAPHENE = {
269+
'SCHEMA': 'yourproject.schema'
270+
}
271+
272+
Finally, configure channels routing (it'll be served from
273+
``/subscriptions``):
274+
275+
.. code:: python
276+
277+
from channels.routing import ProtocolTypeRouter, URLRouter
278+
from graphql_ws.django.graphql_channels import (
279+
websocket_urlpatterns as graphql_urlpatterns
280+
)
281+
282+
application = ProtocolTypeRouter({"websocket": URLRouter(graphql_urlpatterns)})
283+
284+
...and point to the application in Django settings
285+
286+
.. code:: python
287+
288+
ASGI_APPLICATION = 'yourproject.schema'
289+
290+
Run ``./manage.py runserver`` and go to
291+
``http://localhost:8000/graphql`` to test!

examples/django_channels2/Pipfile

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
[[source]]
2+
url = "https://pypi.org/simple"
3+
verify_ssl = true
4+
name = "pypi"
5+
6+
[dev-packages]
7+
8+
[packages]
9+
graphql-ws = {path = "./../..", editable = true}
10+
channels = "*"
11+
graphene-django = "*"
12+
13+
[requires]
14+
python_version = "3.6"

0 commit comments

Comments
 (0)