- 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
None
from the subscription resolver. Previously it was necessary to return specialSKIP
object which is no longer the case.. - Python 3.8 compatibility brought back. Tests pass OK.
GraphqlWsConsumer.warn_resolver_timeout
removed to avoid mess with user specified middlewares. This functionality can easily be implemented on the library user level by creating a designated middleware.GraphqlWsConsumer.middleware
accepts an instance ofgraphql.MiddlewareManager
or the list of functions. Same as the argumentmiddleware
ofgraphql.execute
method.- 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-core
library. - 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_timeout
andGraphqlWsConsumer.warn_resolver_timeout
allow 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_name
record. - 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
ThreadPoolExecutor
does 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 theThreadPoolExecutor
with default (by Python) number of threads. All this eventually ended up in hundreds of thread created for eachGraphqlWsConsumer
subclass.
- Python 3.6 compatibility brought back.
- Subscription
payload
now properly serializes the following Pythondatetime
types:datetime.datetime
datetime.date
datetime.time
- Allow
msgpack v1.*
in the dependencies requirements. - Windows support improved: tests fixed, example fixed.
- Development instructions updated in the
README.md
. - Removed
graphql-core
version lock, it is hold bygraphene
anyway. - 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.md
added.
- Example improved to show how to handle HTTP auth (#23).
- Better error message when Channels channel layer is not available.
- Context (
info.context
in resolvers) lifetime has changed. It is now an object-like wrapper around Channels scope typically available asself.scope
in the Channels consumers. So you can access Channels scope asinfo.context
. Modifications made ininfo.context
are stored in the Channels scope, so they are persisted as long as WebSocket connection lives. You can work withinfo.context
both as withdict
or as withSimpleNamespace
.
- Added support for GraphQL middleware, look at the
GraphqlWsConsumer.middleware
setting. - Example reworked to illustrate how to authenticate clients.
- Channels
scope
is now stored ininfo.context.scope
asdict
. (Previouslyinfo.context
was a copy ofscope
wrapped into thetypes.SimpleNamespace
). The thing is the GraphQLinfo.context
and Channelsscope
are different things. Theinfo.context
is a storage for a single GraphQL operation, whilescope
is 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.
GraphqlWsClient
transport timeout increased 5->60 seconds.- Dependency problem fixed, version numbers frozen in
poetry.lock
file for non-development dependencies. - Tests which failed occasionally due to wrong DB misconfiguration.