Skip to content

Commit 61d319f

Browse files
committed
DjangoChannelsGraphqlWs initially published.
0 parents  commit 61d319f

File tree

13 files changed

+1639
-0
lines changed

13 files changed

+1639
-0
lines changed

LICENSE

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
MIT License
2+
3+
Copyright (c) 2018 DATADVANCE
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a
6+
copy of this software and associated documentation files (the
7+
"Software"), to deal in the Software without restriction, including
8+
without limitation the rights to use, copy, modify, merge, publish,
9+
distribute, sublicense, and/or sell copies of the Software, and to
10+
permit persons to whom the Software is furnished to do so, subject to
11+
the following conditions:
12+
13+
The above copyright notice and this permission notice shall be included
14+
in all copies or substantial portions of the Software.
15+
16+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17+
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

MANIFEST.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
include LICENSE
2+
include README.md

README.md

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
2+
# Django Channels based WebSocket GraphQL server with Graphene-like subscriptions
3+
4+
## Features
5+
6+
- WebSocket-based GraphQL server implemented on the Django Channels.
7+
- Graphene-like subscriptions support.
8+
- Operation order is guaranteed due to WebSocket usage.
9+
- Subscription groups support based on the Django Channels groups.
10+
11+
## Quick start
12+
13+
The `channels_graphql_ws` module provides two classes: `Subscription`
14+
and `GraphqlWsConsumer`. The `Subscription` class itself is a "creative"
15+
copy of `Mutation` class from the Graphene
16+
(`graphene/types/mutation.py`). The `GraphqlWsConsumer` is a Channels
17+
WebSocket consumer which maintains WebSocket connection with the client.
18+
19+
Create GraphQL schema, e.g. using Graphene (note that subscription
20+
definition syntax is close to the Graphene mutation definition):
21+
22+
```python
23+
import channels_graphql_ws
24+
import graphene
25+
26+
class MySubscription(channels_graphql_ws.Subscription):
27+
"""Sample GraphQL subscription."""
28+
29+
# Subscription payload.
30+
event = graphene.String()
31+
32+
class Arguments:
33+
"""That is how subscription arguments are defined."""
34+
arg1 = graphene.String()
35+
arg2 = graphene.String()
36+
37+
def subscribe(self, info, arg1, arg2):
38+
"""Called when user subscribes."""
39+
40+
# Return the list of subscription group names.
41+
return ['group42']
42+
43+
def publish(self, info, arg1, arg2):
44+
"""Called to notify the client."""
45+
46+
# Here `self` contains the `payload` from the `broadcast()`
47+
# invocation (see below).
48+
49+
return MySubscription(event='Something has happened!')
50+
51+
class Query(graphene.ObjectType):
52+
"""Root GraphQL query."""
53+
# Check Graphene docs to see how to define queries.
54+
pass
55+
56+
class Mutation(graphene.ObjectType):
57+
"""Root GraphQL mutation."""
58+
# Check Graphene docs to see how to define mutations.
59+
pass
60+
61+
class Subscription(graphene.ObjectType):
62+
"""Root GraphQL subscription."""
63+
my_subscription = MySubscription.Field()
64+
65+
my_schema = graphene.Schema(
66+
query=Query,
67+
mutation=Mutation,
68+
subscription=Subscription,
69+
)
70+
```
71+
72+
Make your own WebSocket consumer subclass and set the schema it serves:
73+
74+
```python
75+
class MyGraphqlWsConsumer(channels_graphql_ws.GraphqlWsConsumer):
76+
"""Channels WebSocket consumer which provides GraphQL API."""
77+
schema = my_schema
78+
```
79+
80+
Setup Django Channels routing:
81+
82+
```python
83+
application = channels.routing.ProtocolTypeRouter({
84+
'websocket': channels.routing.URLRouter([
85+
django.urls.path('graphql/', MyGraphqlWsConsumer),
86+
])
87+
})
88+
```
89+
90+
Notify clients when some event happens:
91+
92+
```python
93+
MySubscription.broadcast(
94+
# Subscription group to notify clients in.
95+
group='group42',
96+
# Dict delivered to the `publish` method as the `self` argument.
97+
payload={},
98+
)
99+
```
100+
101+
## Details
102+
103+
For details check the [source code](channels_graphql_ws/graphql_ws.py)
104+
which is thoroughly commented. (The docstrings of the `Subscription`
105+
class in especially useful.)
106+
107+
Since the WebSocket handling is based on the Django Channels and
108+
subscriptions are implemented in the Graphene-like style it is
109+
recommended to have a look the documentation of these great projects:
110+
111+
- [Django Channels](http://channels.readthedocs.io)
112+
- [Graphene](http://graphene-python.org/)
113+
114+
The implemented WebSocket-based protocol was taken from the library
115+
[subscription-transport-ws](https://github.com/apollographql/subscriptions-transport-ws)
116+
which is used by the [Apollo GraphQL](https://github.com/apollographql).
117+
Check the [protocol description](https://github.com/apollographql/subscriptions-transport-ws/blob/master/PROTOCOL.md)
118+
for details.
119+
120+
## Alternatives
121+
122+
There is a [Tomáš Ehrlich](https://gist.github.com/tricoder42)
123+
GitHubGist [GraphQL Subscription with django-channels](https://gist.github.com/tricoder42/af3d0337c1b33d82c1b32d12bd0265ec)
124+
which this implementation was initially based on.
125+
126+
There is a promising [GraphQL WS](https://github.com/graphql-python/graphql-ws)
127+
library by the Graphene authors. In particular
128+
[this pull request](https://github.com/graphql-python/graphql-ws/pull/9)
129+
gives a hope that there will be native Graphene implementation of the
130+
WebSocket transport with subscriptions one day.
131+
132+
## Contributing
133+
134+
This project is developed and maintained by DATADVANCE LLC. Please
135+
submit an issue if you have any questions or want to suggest an
136+
improvement.
137+
138+
## Acknowledgements
139+
140+
This work is supported by the Russian Foundation for Basic Research
141+
(project No. 15-29-07043).

channels_graphql_ws/__init__.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#
2+
# coding: utf-8
3+
# Copyright (c) 2018 DATADVANCE
4+
#
5+
# Permission is hereby granted, free of charge, to any person obtaining
6+
# a copy of this software and associated documentation files (the
7+
# "Software"), to deal in the Software without restriction, including
8+
# without limitation the rights to use, copy, modify, merge, publish,
9+
# distribute, sublicense, and/or sell copies of the Software, and to
10+
# permit persons to whom the Software is furnished to do so, subject to
11+
# the following conditions:
12+
#
13+
# The above copyright notice and this permission notice shall be
14+
# included in all copies or substantial portions of the Software.
15+
#
16+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19+
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20+
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21+
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22+
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23+
24+
25+
"""Websocket GraphQL server with subscriptions.
26+
27+
Django Channels based WebSocket GraphQL server with Graphene-like
28+
subscriptions.
29+
"""
30+
31+
from .graphql_ws import Subscription
32+
from .graphql_ws import GraphqlWsConsumer

0 commit comments

Comments
 (0)