Update dependencies to use httpx2 and refactor tests for compatibility

This commit is contained in:
k1nq
2026-09-16 13:49:46 +05:00
parent 7d0762ef17
commit 01028f440e
4 changed files with 79 additions and 61 deletions
+2 -2
View File
@@ -4,7 +4,7 @@ import random
from collections.abc import Awaitable, Callable from collections.abc import Awaitable, Callable
from datetime import UTC, datetime from datetime import UTC, datetime
import httpx import httpx2
from sqlalchemy import select from sqlalchemy import select
from sqlalchemy.ext.asyncio import async_sessionmaker from sqlalchemy.ext.asyncio import async_sessionmaker
@@ -37,7 +37,7 @@ class WebhookClient:
self._timeout = timeout self._timeout = timeout
async def send(self, url: str, payload: PaymentWebhook) -> None: async def send(self, url: str, payload: PaymentWebhook) -> None:
async with httpx.AsyncClient(timeout=self._timeout) as client: async with httpx2.AsyncClient(timeout=self._timeout) as client:
response = await client.post(url, json=payload.model_dump(mode="json")) response = await client.post(url, json=payload.model_dump(mode="json"))
response.raise_for_status() response.raise_for_status()
+1 -1
View File
@@ -12,7 +12,7 @@ dependencies = [
"asyncpg>=0.30,<1", "asyncpg>=0.30,<1",
"fastapi>=0.115,<1", "fastapi>=0.115,<1",
"faststream[cli,rabbit]>=0.5.48,<1", "faststream[cli,rabbit]>=0.5.48,<1",
"httpx>=0.28,<1", "httpx2>=2.13,<3",
"pydantic>=2.10,<3", "pydantic>=2.10,<3",
"pydantic-settings>=2.7,<3", "pydantic-settings>=2.7,<3",
"sqlalchemy[asyncio]>=2.0.36,<3", "sqlalchemy[asyncio]>=2.0.36,<3",
+42 -35
View File
@@ -1,58 +1,65 @@
import uuid import uuid
from collections.abc import AsyncIterator
import httpx2
import pytest
from fastapi import FastAPI from fastapi import FastAPI
from fastapi.testclient import TestClient
from app.api import router from app.api import router
def make_client() -> TestClient: @pytest.fixture
async def client() -> AsyncIterator[httpx2.AsyncClient]:
app = FastAPI() app = FastAPI()
app.include_router(router) app.include_router(router)
return TestClient(app) transport = httpx2.ASGITransport(app=app)
async with httpx2.AsyncClient(
transport=transport,
base_url="http://testserver",
) as test_client:
yield test_client
def test_get_payment_requires_api_key() -> None: async def test_get_payment_requires_api_key(client: httpx2.AsyncClient) -> None:
with make_client() as client: response = await client.get(f"/api/v1/payments/{uuid.uuid4()}")
response = client.get(f"/api/v1/payments/{uuid.uuid4()}")
assert response.status_code == 401 assert response.status_code == 401
assert response.json() == {"detail": "Invalid or missing API key"} assert response.json() == {"detail": "Invalid or missing API key"}
def test_create_payment_requires_idempotency_key() -> None: async def test_create_payment_requires_idempotency_key(client: httpx2.AsyncClient) -> None:
with make_client() as client: response = await client.post(
response = client.post( "/api/v1/payments",
"/api/v1/payments", headers={"X-API-Key": "change-me"},
headers={"X-API-Key": "change-me"}, json={
json={ "amount": "100.00",
"amount": "100.00", "currency": "RUB",
"currency": "RUB", "description": "Test payment",
"description": "Test payment", "metadata": {},
"metadata": {}, "webhook_url": "https://example.com/webhook",
"webhook_url": "https://example.com/webhook", },
}, )
)
assert response.status_code == 422 assert response.status_code == 422
assert response.json()["detail"][0]["loc"] == ["header", "Idempotency-Key"] assert response.json()["detail"][0]["loc"] == ["header", "Idempotency-Key"]
def test_create_payment_rejects_unsupported_currency() -> None: async def test_create_payment_rejects_unsupported_currency(
with make_client() as client: client: httpx2.AsyncClient,
response = client.post( ) -> None:
"/api/v1/payments", response = await client.post(
headers={ "/api/v1/payments",
"X-API-Key": "change-me", headers={
"Idempotency-Key": "test-key", "X-API-Key": "change-me",
}, "Idempotency-Key": "test-key",
json={ },
"amount": "100.00", json={
"currency": "GBP", "amount": "100.00",
"description": "Test payment", "currency": "GBP",
"metadata": {}, "description": "Test payment",
"webhook_url": "https://example.com/webhook", "metadata": {},
}, "webhook_url": "https://example.com/webhook",
) },
)
assert response.status_code == 422 assert response.status_code == 422
Generated
+34 -23
View File
@@ -117,15 +117,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/3c/d7/8fb3044eaef08a310acfe23dae9a8e2e07d305edc29a53497e52bc76eca7/asyncpg-0.31.0-cp314-cp314t-win_amd64.whl", hash = "sha256:bd4107bb7cdd0e9e65fae66a62afd3a249663b844fa34d479f6d5b3bef9c04c3", size = 706062, upload-time = "2025-11-24T23:26:44.086Z" }, { url = "https://files.pythonhosted.org/packages/3c/d7/8fb3044eaef08a310acfe23dae9a8e2e07d305edc29a53497e52bc76eca7/asyncpg-0.31.0-cp314-cp314t-win_amd64.whl", hash = "sha256:bd4107bb7cdd0e9e65fae66a62afd3a249663b844fa34d479f6d5b3bef9c04c3", size = 706062, upload-time = "2025-11-24T23:26:44.086Z" },
] ]
[[package]]
name = "certifi"
version = "2026.7.22"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/a3/c2/24167ea9858356b47a87a50d39908bfdb72ceeefe0041586e704e5376b3a/certifi-2026.7.22.tar.gz", hash = "sha256:741e2c3b351ddf169a738da9f2c048608ff7f2c5cc02f1ebc6b118bb090d5d55", size = 138112, upload-time = "2026-07-22T03:35:12.644Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/0b/a7/71ac2cff56fec219ed242bb11b8efb69fcc4bec75db06fb7bfe35de520e6/certifi-2026.7.22-py3-none-any.whl", hash = "sha256:62f22742b58a1a33014a2b6b706588a8d7e2a88ae7bd1a6ebe8c992928483775", size = 136983, upload-time = "2026-07-22T03:35:11.276Z" },
]
[[package]] [[package]]
name = "click" name = "click"
version = "8.5.0" version = "8.5.0"
@@ -278,16 +269,16 @@ wheels = [
] ]
[[package]] [[package]]
name = "httpcore" name = "httpcore2"
version = "1.0.9" version = "2.13.0"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
dependencies = [ dependencies = [
{ name = "certifi" },
{ name = "h11" }, { name = "h11" },
{ name = "truststore" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/06/94/82699a10bca87a5556c9c59b5963f2d039dbd239f25bc2a63907a05a14cb/httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8", size = 85484, upload-time = "2025-04-24T22:06:22.219Z" } sdist = { url = "https://files.pythonhosted.org/packages/15/8c/e925b1c92018abb3a1863ce1549d76d2381e334d21d65d4ac8f65dabd78a/httpcore2-2.13.0.tar.gz", hash = "sha256:2adc8be4fb285fbcd6d894298db3b52c177e74b6674eda3a76bd36be3292a3db", size = 67740, upload-time = "2026-09-14T14:18:04.717Z" }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55", size = 78784, upload-time = "2025-04-24T22:06:20.566Z" }, { url = "https://files.pythonhosted.org/packages/7e/0d/117a771a2bb91df334b66bf4da14cd02f21aefbcfe53180f336ce55e8f90/httpcore2-2.13.0-py3-none-any.whl", hash = "sha256:35ae5be347aa40467b4a5dc032ac67ebb6d27189fc97e8cebcf99616f6a1bb9e", size = 83162, upload-time = "2026-09-14T14:18:02.529Z" },
] ]
[[package]] [[package]]
@@ -327,18 +318,29 @@ wheels = [
] ]
[[package]] [[package]]
name = "httpx" name = "httpx2"
version = "0.28.1" version = "2.13.0"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
dependencies = [ dependencies = [
{ name = "anyio" }, { name = "anyio", marker = "sys_platform != 'emscripten'" },
{ name = "certifi" }, { name = "httpcore2", marker = "sys_platform != 'emscripten'" },
{ name = "httpcore" }, { name = "httpx2-jsfetch", marker = "sys_platform == 'emscripten'" },
{ name = "idna" }, { name = "idna" },
{ name = "truststore", marker = "sys_platform != 'emscripten'" },
{ name = "typing-extensions", marker = "python_full_version < '3.13'" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406, upload-time = "2024-12-06T15:37:23.222Z" } sdist = { url = "https://files.pythonhosted.org/packages/b9/a0/e9deef4654132857b5a5dbe4eddd0ac59c2814500e11f2f5044cd81103ee/httpx2-2.13.0.tar.gz", hash = "sha256:81bd07dc67a3701729ef1f777a3c00c915d4539604fdb5afd327f8682f6b7b44", size = 100290, upload-time = "2026-09-14T14:18:05.486Z" }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517, upload-time = "2024-12-06T15:37:21.509Z" }, { url = "https://files.pythonhosted.org/packages/fe/d1/a0c72b0e006df654709fbc366cc5bcb53e5aee13e1e3395152c6dd293376/httpx2-2.13.0-py3-none-any.whl", hash = "sha256:fc12720cedf72faa26cca6b4ca394e05c894e7d7933fc45cafe767960804e49a", size = 95565, upload-time = "2026-09-14T14:18:03.553Z" },
]
[[package]]
name = "httpx2-jsfetch"
version = "1.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/cd/c4/0e5636363151a2a1795e0a77617168b9ca438e1748ec05fc9b5687f93d64/httpx2_jsfetch-1.0.tar.gz", hash = "sha256:70a0e3eabfef7cce5ad9c629f7d01ca05e418f586646f4ddf14782e4c1454c60", size = 6872, upload-time = "2026-08-07T00:13:07.492Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/9b/43/832f631d32e4f1211caa2ba368317739fe71f0b8530e4c9d15dc454bac2a/httpx2_jsfetch-1.0-py3-none-any.whl", hash = "sha256:cb916b707601e69a07721aabc8f3f6659be3a6893bc1ff5c6f9e02241df2da32", size = 6382, upload-time = "2026-08-07T00:13:06.567Z" },
] ]
[[package]] [[package]]
@@ -620,7 +622,7 @@ dependencies = [
{ name = "asyncpg" }, { name = "asyncpg" },
{ name = "fastapi" }, { name = "fastapi" },
{ name = "faststream", extra = ["cli", "rabbit"] }, { name = "faststream", extra = ["cli", "rabbit"] },
{ name = "httpx" }, { name = "httpx2" },
{ name = "pydantic" }, { name = "pydantic" },
{ name = "pydantic-settings" }, { name = "pydantic-settings" },
{ name = "sqlalchemy", extra = ["asyncio"] }, { name = "sqlalchemy", extra = ["asyncio"] },
@@ -641,7 +643,7 @@ requires-dist = [
{ name = "asyncpg", specifier = ">=0.30,<1" }, { name = "asyncpg", specifier = ">=0.30,<1" },
{ name = "fastapi", specifier = ">=0.115,<1" }, { name = "fastapi", specifier = ">=0.115,<1" },
{ name = "faststream", extras = ["cli", "rabbit"], specifier = ">=0.5.48,<1" }, { name = "faststream", extras = ["cli", "rabbit"], specifier = ">=0.5.48,<1" },
{ name = "httpx", specifier = ">=0.28,<1" }, { name = "httpx2", specifier = ">=2.13,<3" },
{ name = "pydantic", specifier = ">=2.10,<3" }, { name = "pydantic", specifier = ">=2.10,<3" },
{ name = "pydantic-settings", specifier = ">=2.7,<3" }, { name = "pydantic-settings", specifier = ">=2.7,<3" },
{ name = "pytest", marker = "extra == 'dev'", specifier = ">=8.3,<9" }, { name = "pytest", marker = "extra == 'dev'", specifier = ">=8.3,<9" },
@@ -1075,6 +1077,15 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/c8/cb/6a6a47d5b464bd08695d254f3da6e7986cc70c9fa5d778eda57538edfe56/starlette-1.6.0-py3-none-any.whl", hash = "sha256:a86dd39d14bb45f85a3d18525215a9ef0cfd1f192ac793220e72598c90335f0c", size = 75969, upload-time = "2026-08-08T18:27:56.196Z" }, { url = "https://files.pythonhosted.org/packages/c8/cb/6a6a47d5b464bd08695d254f3da6e7986cc70c9fa5d778eda57538edfe56/starlette-1.6.0-py3-none-any.whl", hash = "sha256:a86dd39d14bb45f85a3d18525215a9ef0cfd1f192ac793220e72598c90335f0c", size = 75969, upload-time = "2026-08-08T18:27:56.196Z" },
] ]
[[package]]
name = "truststore"
version = "0.10.4"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/53/a3/1585216310e344e8102c22482f6060c7a6ea0322b63e026372e6dcefcfd6/truststore-0.10.4.tar.gz", hash = "sha256:9d91bd436463ad5e4ee4aba766628dd6cd7010cf3e2461756b3303710eebc301", size = 26169, upload-time = "2025-08-12T18:49:02.73Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/19/97/56608b2249fe206a67cd573bc93cd9896e1efb9e98bce9c163bcdc704b88/truststore-0.10.4-py3-none-any.whl", hash = "sha256:adaeaecf1cbb5f4de3b1959b42d41f6fab57b2b1666adb59e89cb0b53361d981", size = 18660, upload-time = "2025-08-12T18:49:01.46Z" },
]
[[package]] [[package]]
name = "ty" name = "ty"
version = "0.0.81" version = "0.0.81"