Skip to content

Commit 9afd48e

Browse files
Add HTTPX2 in-process mock support (#3543)
* Add HTTPX2 in-process mock support ``MockVWS`` now intercepts ``httpx2`` requests, synchronous and asynchronous, alongside ``requests`` and ``httpx``. ``respx`` speaks ``httpx``, whose request, response and exception classes are distinct from the ``httpx2`` ones, so ``httpx2`` gets a mock path of its own. That path patches the method which ``httpx2`` clients use to choose a transport for a request, so requests and responses on it are native ``httpx2`` objects from end to end, every client is intercepted whether it was made before or after the mock started, and no process-wide ``httpx2.alias_httpx()`` call is needed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Bring the HTTPX2 paths to full coverage CI requires 100% coverage, and the asynchronous refuse and pass-through branches of the HTTPX2 transport were not exercised, nor were the ``(connect, read)`` timeout tuple and the close methods of the test transports. Add asynchronous blocking and ``real_http`` tests, close tests for both test transports, and give the synchronous timeout test a timeout tuple. Drop the context manager methods of the test transports, which the ``vws-python`` transport protocols do not ask for. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Point the stand-in transports at their follow-up issue Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent c3665c5 commit 9afd48e

21 files changed

Lines changed: 1369 additions & 26 deletions

.github/workflows/test.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ jobs:
130130
- tests/mock_vws/test_target_validators.py
131131
- tests/mock_vws/test_requests_mock_usage.py
132132
- tests/mock_vws/test_respx_mock_usage.py
133+
- tests/mock_vws/test_httpx2_mock_usage.py
133134
- tests/mock_vws/test_flask_app_usage.py
134135
- tests/mock_vws/test_healthcheck.py
135136
- tests/mock_vws/test_docker.py

README.rst

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ Mock for the Vuforia Web Services (VWS) API, the Vuforia Web Query API, and the
1111
Mocking calls made to Vuforia
1212
------------------------------
1313

14-
``MockVWS`` intercepts requests made with `requests`_ or `httpx`_.
14+
``MockVWS`` intercepts requests made with `requests`_, `httpx`_ or `HTTPX2`_.
1515

1616
.. code-block:: shell
1717
@@ -51,10 +51,30 @@ This requires Python |minimum-python-version|\+.
5151
# This will use the Vuforia mock.
5252
httpx.get(url="https://vws.vuforia.com/summary", timeout=30)
5353
54+
``MockVWS`` also intercepts `HTTPX2`_ requests, with no need for ``httpx2.alias_httpx()``:
55+
56+
.. code-block:: python
57+
58+
"""Make a request to the Vuforia Web Services API mock using httpx2."""
59+
60+
import httpx2
61+
62+
from mock_vws import MockVWS
63+
from mock_vws.database import CloudDatabase
64+
65+
with MockVWS() as mock:
66+
database = CloudDatabase()
67+
mock.add_cloud_database(cloud_database=database)
68+
# This will use the Vuforia mock.
69+
httpx2.get(url="https://vws.vuforia.com/summary", timeout=30)
70+
71+
Asynchronous ``httpx`` and `HTTPX2`_ clients are intercepted as well.
72+
5473
By default, an exception will be raised if any requests to unmocked addresses are made.
5574

5675
.. _requests: https://pypi.org/project/requests/
5776
.. _httpx: https://pypi.org/project/httpx/
77+
.. _HTTPX2: https://httpx2.pydantic.dev/
5878

5979
Using Docker to mock calls to Vuforia from any language
6080
-------------------------------------------------------

docs/source/basic-example.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
``MockVWS`` intercepts requests to Vuforia made with `requests`_ or `httpx`_.
1+
``MockVWS`` intercepts requests to Vuforia made with `requests`_, `httpx`_ or `HTTPX2`_.
22

33
.. code-block:: python
44
@@ -47,3 +47,4 @@ See :ref:`mock-api-reference` for details of what can be changed and how.
4747

4848
.. _requests: https://pypi.org/project/requests/
4949
.. _httpx: https://pypi.org/project/httpx/
50+
.. _HTTPX2: https://httpx2.pydantic.dev/

docs/source/differences-to-vws.rst

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ The Vuforia Cloud Query API documents failure responses with JSON, arbitrary
193193
content, or no body. Use
194194
:paramref:`mock_vws.MockVWS.cloud_query_failure_response` to make every Cloud
195195
Query request return a particular documented failure shape through the
196-
in-process ``requests`` and ``httpx`` backends::
196+
in-process ``requests``, ``httpx`` and ``httpx2`` backends::
197197

198198
from mock_vws import CloudQueryFailureResponse, MockVWS
199199

@@ -238,8 +238,8 @@ behavior after successful token acquisition::
238238

239239
Omit ``requests`` to affect create, status, download, and delete requests.
240240
Other phases retain their normal behavior. This configuration works with
241-
the in-process ``requests`` and ``httpx`` backends and is not supported by the
242-
Flask/Docker backend.
241+
the in-process ``requests``, ``httpx`` and ``httpx2`` backends and is not
242+
supported by the Flask/Docker backend.
243243

244244
Other configurable result codes
245245
-------------------------------
@@ -446,9 +446,9 @@ For any other request which it does not serve, such as ``DELETE /summary`` or
446446
and the path of the request.
447447
The Flask and Docker mock reproduces both response shapes.
448448

449-
The ``requests`` and ``httpx`` backends mock only the paths which the mock
450-
serves, so a request to any other path raises a connection error rather than
451-
giving the 404 response which real Vuforia gives.
449+
The ``requests``, ``httpx`` and ``httpx2`` backends mock only the paths which
450+
the mock serves, so a request to any other path raises a connection error
451+
rather than giving the 404 response which real Vuforia gives.
452452

453453
Header cases
454454
------------

docs/source/getting-started.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,5 @@ Mocking calls made to Vuforia
77
.. include:: basic-example.rst
88

99
.. include:: httpx-example.rst
10+
11+
.. include:: httpx2-example.rst

docs/source/httpx2-example.rst

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
``MockVWS`` also intercepts requests made with `HTTPX2`_, with no need for ``httpx2.alias_httpx()``.
2+
3+
.. code-block:: python
4+
5+
"""Make a request to the Vuforia Web Services API mock using httpx2."""
6+
7+
import httpx2
8+
9+
from mock_vws import MockVWS
10+
from mock_vws.database import CloudDatabase
11+
12+
with MockVWS() as mock:
13+
database = CloudDatabase()
14+
mock.add_cloud_database(cloud_database=database)
15+
# This will use the Vuforia mock.
16+
httpx2.get(url="https://vws.vuforia.com/summary", timeout=30)
17+
18+
Asynchronous ``httpx`` and `HTTPX2`_ clients are intercepted as well.
19+
20+
.. _HTTPX2: https://httpx2.pydantic.dev/

docs/source/index.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ This requires Python |minimum-python-version|\+.
1414

1515
.. include:: httpx-example.rst
1616

17+
.. include:: httpx2-example.rst
18+
1719
Using Docker to mock calls to Vuforia from any language
1820
-------------------------------------------------------
1921

newsfragments/3507.change

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
``MockVWS`` now intercepts ``httpx2`` requests, synchronous and asynchronous, alongside ``requests`` and ``httpx``. The ``httpx2`` path uses native ``httpx2`` requests and responses, and does not need ``httpx2.alias_httpx()``.

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ dependencies = [
3737
"beartype>=0.22.9",
3838
"flask>=3.0.3",
3939
"httpx>=0.27.0",
40+
"httpx2>=2.12",
4041
"numpy>=2.4.4",
4142
"opencv-contrib-python-headless>=5.0.0.93",
4243
"pillow>=12.2.0",

spelling_private_dict.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ chunked
2929
cmyk
3030
config
3131
connectionerror
32+
coroutine
3233
customizable
3334
dataclass
3435
dataclasses
@@ -56,6 +57,7 @@ html
5657
http
5758
https
5859
httpx
60+
httpx2
5961
iff
6062
io
6163
issuecomment
@@ -106,6 +108,7 @@ reportAttributeAccessIssue
106108
reportGeneralTypeIssues
107109
reportMissingTypeStubs
108110
reportPrivateImportUsage
111+
reportPrivateUsage
109112
reportUnknownArgumentType
110113
reportUnknownMemberType
111114
reportUnknownVariableType

0 commit comments

Comments
 (0)