Skip to content

Commit

Permalink
Add HTTPX transport (#370)
Browse files Browse the repository at this point in the history
  • Loading branch information
helderco authored Nov 26, 2022
1 parent f0150a8 commit 0819418
Show file tree
Hide file tree
Showing 18 changed files with 2,836 additions and 6 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ jobs:
strategy:
fail-fast: false
matrix:
dependency: ["aiohttp", "requests", "websockets"]
dependency: ["aiohttp", "requests", "httpx", "websockets"]

steps:
- uses: actions/checkout@v3
Expand Down
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
SRC_PYTHON := gql tests docs/code_examples

dev-setup:
python pip install -e ".[test]"
python -m pip install -e ".[test]"

tests:
pytest tests --cov=gql --cov-report=term-missing -vv
Expand All @@ -17,6 +17,9 @@ tests_aiohttp:
tests_requests:
pytest tests --requests-only

tests_httpx:
pytest tests --httpx-only

tests_websockets:
pytest tests --websockets-only

Expand Down
34 changes: 34 additions & 0 deletions docs/code_examples/httpx_async.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import asyncio

from gql import Client, gql
from gql.transport.httpx import HTTPXAsyncTransport


async def main():

transport = HTTPXAsyncTransport(url="https://countries.trevorblades.com/graphql")

# Using `async with` on the client will start a connection on the transport
# and provide a `session` variable to execute queries on this connection
async with Client(
transport=transport,
fetch_schema_from_transport=True,
) as session:

# Execute single query
query = gql(
"""
query getContinents {
continents {
code
name
}
}
"""
)

result = await session.execute(query)
print(result)


asyncio.run(main())
20 changes: 20 additions & 0 deletions docs/code_examples/httpx_sync.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from gql import Client, gql
from gql.transport.httpx import HTTPXTransport

transport = HTTPXTransport(url="https://countries.trevorblades.com/")

client = Client(transport=transport, fetch_schema_from_transport=True)

query = gql(
"""
query getContinents {
continents {
code
name
}
}
"""
)

result = client.execute(query)
print(result)
4 changes: 4 additions & 0 deletions docs/intro.rst
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ The corresponding between extra dependencies required and the GQL classes is:
+---------------------+----------------------------------------------------------------+
| requests | :ref:`RequestsHTTPTransport <requests_transport>` |
+---------------------+----------------------------------------------------------------+
| httpx | :ref:`HTTPTXTransport <httpx_transport>` |
| | |
| | :ref:`HTTPXAsyncTransport <httpx_async_transport>` |
+---------------------+----------------------------------------------------------------+
| botocore | :ref:`AppSyncIAMAuthentication <appsync_iam_auth>` |
+---------------------+----------------------------------------------------------------+

Expand Down
1 change: 1 addition & 0 deletions docs/modules/gql.rst
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ Sub-Packages
transport_exceptions
transport_phoenix_channel_websockets
transport_requests
transport_httpx
transport_websockets
transport_websockets_base
dsl
Expand Down
7 changes: 7 additions & 0 deletions docs/modules/transport_httpx.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
gql.transport.httpx
===================

.. currentmodule:: gql.transport.httpx

.. automodule:: gql.transport.httpx
:member-order: bysource
1 change: 1 addition & 0 deletions docs/transports/async_transports.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Async transports are transports which are using an underlying async library. The
:maxdepth: 1

aiohttp
httpx_async
websockets
phoenix
appsync
13 changes: 13 additions & 0 deletions docs/transports/httpx.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
.. _httpx_transport:

HTTPXTransport
==============

The HTTPXTransport is a sync transport using the `httpx`_ library
and allows you to send GraphQL queries using the HTTP protocol.

Reference: :class:`gql.transport.httpx.HTTPXTransport`

.. literalinclude:: ../code_examples/httpx_sync.py

.. _httpx: https://www.python-httpx.org
39 changes: 39 additions & 0 deletions docs/transports/httpx_async.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
.. _httpx_async_transport:

HTTPXAsyncTransport
===================

This transport uses the `httpx`_ library and allows you to send GraphQL queries using the HTTP protocol.

Reference: :class:`gql.transport.httpx.HTTPXAsyncTransport`

.. note::

GraphQL subscriptions are not supported on the HTTP transport.
For subscriptions you should use the :ref:`websockets transport <websockets_transport>`.

.. literalinclude:: ../code_examples/httpx_async.py

Authentication
--------------

There are multiple ways to authenticate depending on the server configuration.

1. Using HTTP Headers

.. code-block:: python
transport = HTTPXAsyncTransport(
url='https://SERVER_URL:SERVER_PORT/graphql',
headers={'Authorization': 'token'}
)
2. Using HTTP Cookies

You can manually set the cookies which will be sent with each connection:

.. code-block:: python
transport = HTTPXAsyncTransport(url=url, cookies={"cookie1": "val1"})
.. _httpx: https://www.python-httpx.org
1 change: 1 addition & 0 deletions docs/transports/sync_transports.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ They cannot be used asynchronously.
:maxdepth: 1

requests
httpx
9 changes: 7 additions & 2 deletions docs/usage/file_upload.rst
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
File uploads
============

GQL supports file uploads with the :ref:`aiohttp transport <aiohttp_transport>`
and the :ref:`requests transport <requests_transport>`
GQL supports file uploads with the :ref:`aiohttp transport <aiohttp_transport>`, the
:ref:`requests transport <requests_transport>`, the :ref:`httpx transport <httpx_transport>`,
and the :ref:`httpx async transport <httpx_async_transport>`,
using the `GraphQL multipart request spec`_.

.. _GraphQL multipart request spec: https://github.com/jaydenseric/graphql-multipart-request-spec
Expand All @@ -20,6 +21,8 @@ In order to upload a single file, you need to:
transport = AIOHTTPTransport(url='YOUR_URL')
# Or transport = RequestsHTTPTransport(url='YOUR_URL')
# Or transport = HTTPXTransport(url='YOUR_URL')
# Or transport = HTTPXAsyncTransport(url='YOUR_URL')
client = Client(transport=transport)
Expand Down Expand Up @@ -48,6 +51,8 @@ It is also possible to upload multiple files using a list.
transport = AIOHTTPTransport(url='YOUR_URL')
# Or transport = RequestsHTTPTransport(url='YOUR_URL')
# Or transport = HTTPXTransport(url='YOUR_URL')
# Or transport = HTTPXAsyncTransport(url='YOUR_URL')
client = Client(transport=transport)
Expand Down
Loading

0 comments on commit 0819418

Please sign in to comment.