Skip to content

Commit a8630e5

Browse files
committed
Merge HTTPMultipartTransport into AIOHTTPTransport
1 parent 851ca37 commit a8630e5

10 files changed

Lines changed: 326 additions & 643 deletions

File tree

docs/code_examples/http_multipart_async.py renamed to docs/code_examples/aiohttp_multipart_subscription.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@
22
import logging
33

44
from gql import Client, gql
5-
from gql.transport.http_multipart_transport import HTTPMultipartTransport
5+
from gql.transport.aiohttp import AIOHTTPTransport
66

77
logging.basicConfig(level=logging.INFO)
88

99

1010
async def main():
1111

12-
transport = HTTPMultipartTransport(url="https://gql-book-server.fly.dev/graphql")
12+
transport = AIOHTTPTransport(url="https://gql-book-server.fly.dev/graphql")
1313

1414
# Using `async with` on the client will start a connection on the transport
1515
# and provide a `session` variable to execute queries on this connection

docs/modules/gql.rst

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ Sub-Packages
2929
transport_common_adapters_aiohttp
3030
transport_common_adapters_websockets
3131
transport_exceptions
32-
transport_http_multipart
3332
transport_phoenix_channel_websockets
3433
transport_requests
3534
transport_httpx

docs/modules/transport_http_multipart.rst

Lines changed: 0 additions & 7 deletions
This file was deleted.

docs/transports/aiohttp.rst

Lines changed: 71 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,79 @@ This transport uses the `aiohttp`_ library and allows you to send GraphQL querie
77

88
Reference: :class:`gql.transport.aiohttp.AIOHTTPTransport`
99

10-
.. note::
10+
This transport supports both standard GraphQL operations (queries, mutations) and subscriptions.
11+
Subscriptions are implemented using the `multipart subscription protocol`_
12+
as implemented by Apollo GraphOS Router and other compatible servers.
1113

12-
GraphQL subscriptions are not supported on the HTTP transport.
13-
For subscriptions you should use a websockets transport:
14-
:ref:`WebsocketsTransport <websockets_transport>` or
15-
:ref:`AIOHTTPWebsocketsTransport <aiohttp_websockets_transport>`.
14+
This provides an HTTP-based alternative to WebSocket transports for receiving streaming
15+
subscription updates. It's particularly useful when:
16+
17+
- WebSocket connections are not available or blocked by infrastructure
18+
- You want to use standard HTTP with existing load balancers and proxies
19+
- The backend implements the multipart subscription protocol
20+
21+
Queries
22+
-------
1623

1724
.. literalinclude:: ../code_examples/aiohttp_async.py
1825

26+
Subscriptions
27+
-------------
28+
29+
The transport sends a standard HTTP POST request with an ``Accept`` header indicating
30+
support for multipart responses:
31+
32+
.. code-block:: text
33+
34+
Accept: multipart/mixed;subscriptionSpec="1.0", application/json
35+
36+
The server responds with a ``multipart/mixed`` content type and streams subscription
37+
updates as separate parts in the response body. Each part contains a JSON payload
38+
with GraphQL execution results.
39+
40+
.. literalinclude:: ../code_examples/aiohttp_multipart_subscription.py
41+
42+
How It Works
43+
^^^^^^^^^^^^
44+
45+
**Message Format**
46+
47+
Each message part follows this structure:
48+
49+
.. code-block:: text
50+
51+
--graphql
52+
Content-Type: application/json
53+
54+
{"payload": {"data": {...}, "errors": [...]}}
55+
56+
**Heartbeats**
57+
58+
Servers may send empty JSON objects (``{}``) as heartbeat messages to keep the
59+
connection alive. These are automatically filtered out by the transport.
60+
61+
**Error Handling**
62+
63+
The protocol distinguishes between two types of errors:
64+
65+
- **GraphQL errors**: Returned within the ``payload`` property alongside data
66+
- **Transport errors**: Returned with a top-level ``errors`` field and ``null`` payload
67+
68+
**End of Stream**
69+
70+
The subscription ends when the server sends the final boundary marker:
71+
72+
.. code-block:: text
73+
74+
--graphql--
75+
76+
Limitations
77+
^^^^^^^^^^^
78+
79+
- Subscriptions require the server to implement the multipart subscription protocol
80+
- Long-lived connections may be terminated by intermediate proxies or load balancers
81+
- Some server configurations may not support HTTP/1.1 chunked transfer encoding required for streaming
82+
1983
Authentication
2084
--------------
2185

@@ -52,3 +116,5 @@ and you can save these cookies in a cookie jar to reuse them in a following conn
52116
53117
.. _aiohttp: https://docs.aiohttp.org
54118
.. _issue 197: https://github.com/graphql-python/gql/issues/197
119+
.. _multipart subscription protocol: https://www.apollographql.com/docs/graphos/routing/operations/subscriptions/multipart-protocol
120+

docs/transports/async_transports.rst

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ Async transports are transports which are using an underlying async library. The
1111

1212
aiohttp
1313
httpx_async
14-
http_multipart
1514
websockets
1615
aiohttp_websockets
1716
phoenix

docs/transports/http_multipart.rst

Lines changed: 0 additions & 159 deletions
This file was deleted.

0 commit comments

Comments
 (0)