Skip to content

Fix bugs with transport-ws-protocol #111

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 16, 2023
Merged

Fix bugs with transport-ws-protocol #111

merged 1 commit into from
May 16, 2023

Conversation

ayys
Copy link
Collaborator

@ayys ayys commented May 16, 2023

I am guessing the v3 branch was only used with GraphQLWSHandler, and not with GraphQLTransportWSHandler. That's probably why there were a bunch of bugs. This PR fixes the errors I got when trying to use subscriptions with the graphql-transport-ws protocol.

The first error I got was

Can't instantiate abstract class GraphQLTransportWSHandler with abstract method send_xjson

I implemented this function and the error went away.

Second error was with message types - they were TypedDicts, but typeddicts are essentially dicts.
This means additional fields specified are not properly used. I fixed it by converting them to dataclasses and adding a to_dict field to it.

I am guessing this branch was only used with GraphQLWSHandler, and not with
GraphQLTransportWSHandler. That's probably why there were a bunch of bugs. This PR fixes those.
@ayys ayys requested a review from syrusakbary May 16, 2023 11:22
Comment on lines -27 to +30
return await self._get_context(request=self._ws)
return await self._get_context(self._ws)

async def get_root_value(self) -> Any:
return await self._get_root_value(request=self._ws)
return await self._get_root_value(self._ws)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed this because channels/graphql_ws.py doesn't specify the argument name either.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Side note: graphql_ws.py and graphql_transport_ws.py have alot of duplicate code that could be merged. I will not do that in this PR though.

await self._ws.accept(
subprotocol=BaseGraphQLTransportWSHandler.GRAPHQL_TRANSPORT_WS_PROTOCOL
)
await self._ws.accept(subprotocol=BaseGraphQLTransportWSHandler.PROTOCOL)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wrong variable name was being used :/

Comment on lines +215 to +220
async def send_message(self, data: Message) -> None:
data = data.asdict()
assert (
data.get("type") is not None
), "expected dict with `type` field. Got {} instead".format(data)
await self.send_json(data)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use dataclasses instead of TypedDicts. TypeDict is just a dict at runtime, and is only used for typehinting. That means data.type would not have worked.
sidenote: we should do the same for graphql_ws.py too.

@@ -5,6 +5,8 @@
except ImportError:
from typing_extensions import TypedDict

from dataclasses import dataclass, asdict

from .contstants import (
GQL_CONNECTION_INIT,
GQL_CONNECTION_ACK,
Copy link
Collaborator Author

@ayys ayys May 16, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These constants should probably be an enum, but fixing that shouldn't be part of this PR

@syrusakbary syrusakbary merged commit 792777e into graphql-python:v3 May 16, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants