Skip to content

Commit b60ef24

Browse files
felipao-mxclaude
andcommitted
Replace requests with httpx
- Updated HTTP client to use httpx instead of requests - Modified response handling to match httpx API - Updated dependencies in requirements.txt and setup.py - Updated tests to use pytest-httpx 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 21690e1 commit b60ef24

File tree

6 files changed

+34
-32
lines changed

6 files changed

+34
-32
lines changed

cuenca/http/client.py

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,14 @@
33
from typing import Optional, Tuple
44
from urllib.parse import urljoin
55

6-
import requests
6+
import httpx
77
from cuenca_validations.errors import ERROR_CODES
88
from cuenca_validations.types import JSONEncoder
99
from cuenca_validations.typing import (
1010
ClientRequestParams,
1111
DictStrAny,
1212
OptionalDict,
1313
)
14-
from requests import Response
1514

1615
from ..exc import CuencaResponseException
1716
from ..jwt import Jwt
@@ -103,27 +102,32 @@ def request(
103102
**kwargs,
104103
) -> bytes:
105104
resp = None
106-
with requests.Session() as session:
107-
session.headers = self.headers # type: ignore
105+
with httpx.Client() as client:
106+
# Set headers
107+
headers = self.headers.copy()
108+
109+
# Update JWT token if needed
108110
if self.jwt_token:
109111
if self.jwt_token.is_expired:
110112
self.jwt_token = Jwt.create(self)
111-
self.headers['X-Cuenca-Token'] = self.jwt_token.token
112-
session.headers = self.headers # type: ignore
113-
resp = session.request( # type: ignore
113+
headers['X-Cuenca-Token'] = self.jwt_token.token
114+
115+
# Make request
116+
resp = client.request(
114117
method=method,
115118
url='https://' + self.host + urljoin('/', endpoint),
116119
auth=self.auth,
117120
json=json.loads(JSONEncoder().encode(data)),
118121
params=params,
122+
headers=headers,
119123
**kwargs,
120124
)
121125
self._check_response(resp)
122126
return resp.content
123127

124128
@staticmethod
125-
def _check_response(response: Response):
126-
if response.ok:
129+
def _check_response(response: httpx.Response):
130+
if 200 <= response.status_code < 300:
127131
return
128132
json = response.json()
129133
if 'code' in json:

cuenca/resources/transfers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
TransferRequest,
88
)
99
from cuenca_validations.typing import DictStrAny
10-
from requests import HTTPError
10+
from httpx import HTTPError
1111

1212
from ..exc import CuencaException
1313
from .accounts import Account

requirements-test.txt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ mypy==1.14.1
66
pytest==8.3.4
77
pytest-cov==6.0.0
88
pytest-vcr==1.0.2
9-
requests-mock==1.12.1
9+
pytest-httpx==0.30.0
1010
types-freezegun==1.1.10
11-
types-requests==2.31.0.6
1211
vcrpy==7.0.0

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
requests==2.32.3
1+
httpx==0.27.0
22
cuenca-validations==2.1.13
33
pydantic-extra-types==2.10.2

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
package_data=dict(cuenca=['py.typed']),
2424
python_requires='>=3.9',
2525
install_requires=[
26-
'requests>=2.32.0',
26+
'httpx>=0.27.0',
2727
'cuenca-validations>=2.1.5',
2828
'pydantic-extra-types>=2.10.0',
2929
],

tests/test_cuenca.py

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
import requests_mock # type: ignore
1+
import pytest
2+
from pytest_httpx import HTTPXMock
23

34
import cuenca
45

56

6-
def test_get_balance():
7+
def test_get_balance(httpx_mock: HTTPXMock):
78
# It is the case when the user has transactions in the account
89
response_json = {
910
'items': [
@@ -23,29 +24,27 @@ def test_get_balance():
2324
],
2425
'next_page_uri': None,
2526
}
26-
with requests_mock.mock() as m:
27-
m.get(
28-
'https://sandbox.cuenca.com/balance_entries?limit=1',
29-
status_code=200,
30-
json=response_json,
31-
)
32-
33-
balance = cuenca.get_balance()
27+
httpx_mock.add_response(
28+
url='https://sandbox.cuenca.com/balance_entries?limit=1',
29+
status_code=200,
30+
json=response_json,
31+
)
32+
33+
balance = cuenca.get_balance()
3434
assert balance == response_json['items'][0]['rolling_balance']
3535

3636

37-
def test_get_balance_before_first_transaction():
37+
def test_get_balance_before_first_transaction(httpx_mock: HTTPXMock):
3838
# When the user have no transactions at all
3939
# balance_entries endpoint returns `items` as empty list.
4040
# It means that its balance is Mx$0.00
4141
response_json = {'items': [], 'next_page_uri': None}
4242

43-
with requests_mock.mock() as m:
44-
m.get(
45-
'https://sandbox.cuenca.com/balance_entries?limit=1',
46-
status_code=200,
47-
json=response_json,
48-
)
43+
httpx_mock.add_response(
44+
url='https://sandbox.cuenca.com/balance_entries?limit=1',
45+
status_code=200,
46+
json=response_json,
47+
)
4948

50-
balance = cuenca.get_balance()
49+
balance = cuenca.get_balance()
5150
assert balance == 0

0 commit comments

Comments
 (0)