- Supported the most recent WebSocket sub-protocol
graphql-transport-wsused by Apollo. See the specification: https://github.com/enisdenjo/graphql-ws/blob/master/PROTOCOL.md.
- GraphQL parsing and message serialization now perform concurrently
by
sync_to_async(...,thread_sensitive=False).
WARNING: Release contains backward incompatible changes!
- To suppress/drop subscription notification just return
Nonefrom the subscription resolver. Previously it was necessary to return specialSKIPobject which is no longer the case.. - Python 3.8 compatibility brought back. Tests pass OK.
GraphqlWsConsumer.warn_resolver_timeoutremoved to avoid mess with user specified middlewares. This functionality can easily be implemented on the library user level by creating a designated middleware.GraphqlWsConsumer.middlewareaccepts an instance ofgraphql.MiddlewareManageror the list of functions. Same as the argumentmiddlewareofgraphql.executemethod.- Fixed broken example.
- Invoke synchronous resolvers in the main thread with eventloop. So
there is no difference in this aspect with async resolvers. This
corresponds to the behavior of the
graphql-corelibrary. - Added example of middleware which offloads synchronous resolvers to the threadpool.
- Fixed bug with GraphQL WrappingTypes like GraphQLNonNull causing exceptions when used as subscription field.
- Fixed broken example.
Broken support of previous Python version brought back.
- DjangoChannelsGraphqlWs has migrated to the recent versions of Django, Channels, and Graphene. All other Python dependencies updated.
- Server outputs a warning to the log when operation/resolver takes
longer than specified timeout, which is one second by default. The
settings
GraphqlWsConsumer.warn_operation_timeoutandGraphqlWsConsumer.warn_resolver_timeoutallow to tune the timeout or even disable the warning at all. - If exception raises from the resolver a response now contains a field "extensions.code" with a class name of the exception.
- Added support for async resolvers and middlewares.
- WARNING: This release is not backward compatible with previous ones!
The main cause is a major update of Django, Channels, and Graphene,
but there are some introduced by the library itself. In particular:
- Context lifetime and content have changed. See README.md for details.
- Minor fix in logging.
- Ability to configure server notification queue limit per subscription.
- Switched to Channels 3.
- Python dependencies updated.
- Django channel name added to the context as the
channel_namerecord. - Python dependencies updated.
- Client method 'execute' consumes 'complete' message in case of error.
- Logging slightly improved. Thanks to @edouardtheron.
- Quadratic growth of threads number has stopped. The problem was
observer on Python 3.6 and 3.7 and was not on 3.8, because starting
with 3.8
ThreadPoolExecutordoes not spawn new thread if there are idle threads in the pool already. The issue was in the fact that for each of worker thread we run an event loop which default executor is theThreadPoolExecutorwith default (by Python) number of threads. All this eventually ended up in hundreds of thread created for eachGraphqlWsConsumersubclass.
- Python 3.6 compatibility brought back.
- Subscription
payloadnow properly serializes the following Pythondatetimetypes:datetime.datetimedatetime.datedatetime.time
- Allow
msgpack v1.*in the dependencies requirements. - Windows support improved: tests fixed, example fixed.
- Development instructions updated in the
README.md. - Removed
graphql-coreversion lock, it is hold bygrapheneanyway. - Many CI-related fixes.
- Added support for Python 3.6.
- Dependencies updated and relaxed, now Django 3 is allowed.
- Testing framework improved to run on 3.6, 3.7, 3.8 with Tox.
- Client setup documentation (Python, GraphiQL) improved. Thanks to Rigel Kent.
- Error logging added to simplify debugging, error messages improved.
- Fixed wrong year in this changelog (facepalm).
- Configuration management made slightly simple.
- Bandit linter removed as useless.
- More instructions for the package developers in the
README.mdadded.
- Example improved to show how to handle HTTP auth (#23).
- Better error message when Channels channel layer is not available.
- Context (
info.contextin resolvers) lifetime has changed. It is now an object-like wrapper around Channels scope typically available asself.scopein the Channels consumers. So you can access Channels scope asinfo.context. Modifications made ininfo.contextare stored in the Channels scope, so they are persisted as long as WebSocket connection lives. You can work withinfo.contextboth as withdictor as withSimpleNamespace.
- Added support for GraphQL middleware, look at the
GraphqlWsConsumer.middlewaresetting. - Example reworked to illustrate how to authenticate clients.
- Channels
scopeis now stored ininfo.context.scopeasdict. (Previouslyinfo.contextwas a copy ofscopewrapped into thetypes.SimpleNamespace). The thing is the GraphQLinfo.contextand Channelsscopeare different things. Theinfo.contextis a storage for a single GraphQL operation, whilescopeis a storage for the whole WebSocket connection. For example now useinfo.context.scope["user"]to get access to the Django user model.
- Changelog eventually added.
GraphqlWsClienttransport timeout increased 5->60 seconds.- Dependency problem fixed, version numbers frozen in
poetry.lockfile for non-development dependencies. - Tests which failed occasionally due to wrong DB misconfiguration.