Port to httpx2, refs #2879

This commit is contained in:
Simon Willison 2026-08-13 16:22:30 -07:00
commit f712559886
10 changed files with 62 additions and 64 deletions

View file

@ -8,7 +8,7 @@ import tempfile
import time
from dataclasses import dataclass
import httpx
import httpx2
import pytest
import pytest_asyncio
@ -32,13 +32,13 @@ UNDOCUMENTED_PERMISSIONS = {
}
def wait_until_responds(url, timeout=5.0, client=httpx, **kwargs):
def wait_until_responds(url, timeout=5.0, client=httpx2, **kwargs):
start = time.time()
while time.time() - start < timeout:
try:
client.get(url, **kwargs)
return
except httpx.ConnectError:
except httpx2.ConnectError:
time.sleep(0.1)
raise AssertionError(f"Timed out waiting for {url} to respond")
@ -277,8 +277,8 @@ def ds_unix_domain_socket_server(tmp_path_factory):
cwd=tempfile.gettempdir(),
)
# Poll until available
transport = httpx.HTTPTransport(uds=uds)
client = httpx.Client(transport=transport)
transport = httpx2.HTTPTransport(uds=uds)
client = httpx2.Client(transport=transport)
try:
wait_until_responds(
"http://localhost/_memory.json", timeout=30.0, client=client

View file

@ -1,12 +1,12 @@
import socket
import httpx
import httpx2
import pytest
@pytest.mark.serial
def test_serve_localhost_http(ds_localhost_http_server):
response = httpx.get("http://localhost:8041/_memory.json")
response = httpx2.get("http://localhost:8041/_memory.json")
assert {
"database": "_memory",
"path": "/_memory",
@ -20,8 +20,8 @@ def test_serve_localhost_http(ds_localhost_http_server):
)
def test_serve_unix_domain_socket(ds_unix_domain_socket_server):
_, uds = ds_unix_domain_socket_server
transport = httpx.HTTPTransport(uds=uds)
client = httpx.Client(transport=transport)
transport = httpx2.HTTPTransport(uds=uds)
client = httpx2.Client(transport=transport)
response = client.get("http://localhost/_memory.json")
assert {
"database": "_memory",

View file

@ -1,4 +1,4 @@
import httpx
import httpx2
import pytest
import pytest_asyncio
@ -43,7 +43,7 @@ async def datasette_with_permissions():
async def test_client_methods(datasette, method, path, expected_status):
client_method = getattr(datasette.client, method)
response = await client_method(path)
assert isinstance(response, httpx.Response)
assert isinstance(response, httpx2.Response)
assert response.status_code == expected_status
# Try that again using datasette.client.request
response2 = await datasette.client.request(method, path)
@ -63,7 +63,7 @@ async def test_client_post(datasette, prefix):
"message": "A message",
},
)
assert isinstance(response, httpx.Response)
assert isinstance(response, httpx2.Response)
assert response.status_code == 302
assert "ds_messages" in response.cookies
finally:
@ -135,7 +135,7 @@ async def test_skip_permission_checks_all_methods(datasette_with_permissions, me
response = await client_method("/test_db.json", skip_permission_checks=True)
# We don't check status code since some methods might not be allowed,
# but we verify the request doesn't fail due to permissions
assert isinstance(response, httpx.Response)
assert isinstance(response, httpx2.Response)
@pytest.mark.asyncio
@ -340,7 +340,7 @@ async def test_actor_parameter_all_http_methods(datasette, method):
client_method = getattr(datasette.client, method)
# Just verify no TypeError about unexpected 'actor' kwarg
response = await client_method("/", actor={"id": "root"})
assert isinstance(response, httpx.Response)
assert isinstance(response, httpx2.Response)
@pytest.mark.asyncio

View file

@ -5,7 +5,7 @@ import subprocess
import sys
import time
import httpx
import httpx2
import pytest
from datasette.fixtures import write_fixture_database
@ -34,11 +34,11 @@ def wait_for_server(process, url, timeout=30):
f"stderr:\n{stderr}"
)
try:
response = httpx.get(url, timeout=1.0)
response = httpx2.get(url, timeout=1.0)
if response.status_code < 500:
return
last_error = f"HTTP {response.status_code}: {response.text[:200]}"
except httpx.HTTPError as ex:
except httpx2.HTTPError as ex:
last_error = repr(ex)
time.sleep(0.1)
if process.poll() is None:
@ -336,7 +336,7 @@ def project_rows(datasette_server, **filters):
"_shape": "objects",
**{key: str(value) for key, value in filters.items()},
}
response = httpx.get(f"{datasette_server}data/projects.json", params=params)
response = httpx2.get(f"{datasette_server}data/projects.json", params=params)
response.raise_for_status()
return response.json()["rows"]
@ -348,7 +348,7 @@ def project_row(datasette_server, pk):
def binary_file_blob(datasette_server, pk):
response = httpx.get(
response = httpx2.get(
f"{datasette_server}data/binary_files/{pk}.blob",
params={"_blob_column": "data"},
)
@ -369,7 +369,7 @@ def bulk_default_rows(datasette_server, **filters):
"_shape": "objects",
**{key: str(value) for key, value in filters.items()},
}
response = httpx.get(f"{datasette_server}data/bulk_defaults.json", params=params)
response = httpx2.get(f"{datasette_server}data/bulk_defaults.json", params=params)
response.raise_for_status()
return response.json()["rows"]
@ -379,7 +379,7 @@ def upsert_item_rows(datasette_server, **filters):
"_shape": "objects",
**{key: str(value) for key, value in filters.items()},
}
response = httpx.get(f"{datasette_server}data/upsert_items.json", params=params)
response = httpx2.get(f"{datasette_server}data/upsert_items.json", params=params)
response.raise_for_status()
return response.json()["rows"]
@ -473,7 +473,7 @@ def test_create_table_flow(page, datasette_server):
page.wait_for_url("**/data/playwright_created")
assert "playwright_created" in page.locator("h1").inner_text()
response = httpx.get(
response = httpx2.get(
f"{datasette_server}data/playwright_created.json?_extra=columns,column_types"
)
response.raise_for_status()
@ -487,7 +487,7 @@ def test_create_table_flow(page, datasette_server):
assert data["column_types"] == {
"metadata": {"type": "json", "config": None},
}
schema_response = httpx.get(
schema_response = httpx2.get(
f"{datasette_server}data/-/query.json",
params={
"sql": (
@ -603,7 +603,7 @@ def test_create_table_from_data_flow(page, datasette_server):
dialog.locator(".table-create-save").click()
page.wait_for_url("**/data/playwright_from_data")
response = httpx.get(
response = httpx2.get(
f"{datasette_server}data/playwright_from_data.json?_shape=objects"
)
response.raise_for_status()
@ -639,7 +639,7 @@ def test_create_table_from_csv_keeps_numeric_type_when_values_are_blank(
dialog.locator(".table-create-save").click()
page.wait_for_url("**/data/playwright_numeric_blanks")
response = httpx.get(
response = httpx2.get(
f"{datasette_server}data/playwright_numeric_blanks.json?_shape=objects"
)
response.raise_for_status()
@ -648,7 +648,7 @@ def test_create_table_from_csv_keeps_numeric_type_when_values_are_blank(
{"name": "B", "score": None},
]
schema_response = httpx.get(
schema_response = httpx2.get(
f"{datasette_server}data/-/query.json",
params={
"sql": (
@ -856,7 +856,7 @@ def test_alter_table_flow(page, datasette_server):
columns = []
for _ in range(20):
response = httpx.get(f"{datasette_server}data/projects.json?_extra=columns")
response = httpx2.get(f"{datasette_server}data/projects.json?_extra=columns")
response.raise_for_status()
columns = response.json()["columns"]
if "status" in columns: