Skip to content

Commit c8155ad

Browse files
committed
httpx instead of aiohttp
1 parent 51bf9dc commit c8155ad

File tree

6 files changed

+75
-78
lines changed

6 files changed

+75
-78
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
## 3.5
22
### Added
3-
- Asynchronous API support using `aiohttp`
3+
- Asynchronous API support using `httpx`
44
- New class `Metabase_API_Async` for async operations
55
- Async versions of core API methods
66

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ mb = Metabase_API('https://...', api_key='YOUR_API_KEY')
2121
```
2222

2323
## Asynchronous Usage
24-
The library now supports asynchronous operations using `aiohttp`:
24+
The library now supports asynchronous operations using `httpx`:
2525

2626
```python
2727
import asyncio
Lines changed: 45 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,72 +1,69 @@
1-
import aiohttp
1+
import httpx
22

33
async def get(self, endpoint, *args, **kwargs):
44
"""Async version of GET request"""
55
await self.validate_session_async()
6-
auth = aiohttp.BasicAuth(self.email, self.password) if self.auth else None
7-
8-
async with aiohttp.ClientSession() as session:
9-
async with session.get(
10-
self.domain + endpoint,
11-
headers=self.header,
6+
auth = (self.email, self.password) if self.auth else None
7+
8+
async with httpx.AsyncClient() as client:
9+
res = await client.get(
10+
self.domain + endpoint,
11+
headers=self.header,
1212
auth=auth,
1313
**kwargs
14-
) as res:
15-
if 'raw' in args:
16-
return res
17-
else:
18-
return await res.json() if res.status == 200 else False
19-
14+
)
15+
if 'raw' in args:
16+
return res
17+
else:
18+
return res.json() if res.status_code == 200 else False
2019

2120
async def post(self, endpoint, *args, **kwargs):
2221
"""Async version of POST request"""
2322
await self.validate_session_async()
24-
auth = aiohttp.BasicAuth(self.email, self.password) if self.auth else None
25-
26-
async with aiohttp.ClientSession() as session:
27-
async with session.post(
28-
self.domain + endpoint,
29-
headers=self.header,
23+
auth = (self.email, self.password) if self.auth else None
24+
25+
async with httpx.AsyncClient() as client:
26+
res = await client.post(
27+
self.domain + endpoint,
28+
headers=self.header,
3029
auth=auth,
3130
**kwargs
32-
) as res:
33-
if 'raw' in args:
34-
return res
35-
else:
36-
return await res.json() if res.status == 200 else False
37-
31+
)
32+
if 'raw' in args:
33+
return res
34+
else:
35+
return res.json() if res.status_code == 200 else False
3836

3937
async def put(self, endpoint, *args, **kwargs):
4038
"""Async version of PUT request for updating objects"""
4139
await self.validate_session_async()
42-
auth = aiohttp.BasicAuth(self.email, self.password) if self.auth else None
43-
44-
async with aiohttp.ClientSession() as session:
45-
async with session.put(
46-
self.domain + endpoint,
47-
headers=self.header,
40+
auth = (self.email, self.password) if self.auth else None
41+
42+
async with httpx.AsyncClient() as client:
43+
res = await client.put(
44+
self.domain + endpoint,
45+
headers=self.header,
4846
auth=auth,
4947
**kwargs
50-
) as res:
51-
if 'raw' in args:
52-
return res
53-
else:
54-
return res.status
55-
48+
)
49+
if 'raw' in args:
50+
return res
51+
else:
52+
return res.status_code
5653

5754
async def delete(self, endpoint, *args, **kwargs):
5855
"""Async version of DELETE request"""
5956
await self.validate_session_async()
60-
auth = aiohttp.BasicAuth(self.email, self.password) if self.auth else None
61-
62-
async with aiohttp.ClientSession() as session:
63-
async with session.delete(
64-
self.domain + endpoint,
65-
headers=self.header,
57+
auth = (self.email, self.password) if self.auth else None
58+
59+
async with httpx.AsyncClient() as client:
60+
res = await client.delete(
61+
self.domain + endpoint,
62+
headers=self.header,
6663
auth=auth,
6764
**kwargs
68-
) as res:
69-
if 'raw' in args:
70-
return res
71-
else:
72-
return res.status
65+
)
66+
if 'raw' in args:
67+
return res
68+
else:
69+
return res.status_code

metabase_api/metabase_api_async.py

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import aiohttp
1+
import httpx
22
import getpass
33
from .metabase_api import Metabase_API
44

@@ -40,19 +40,19 @@ async def authenticate_async(self):
4040
'password': self.password
4141
}
4242

43-
async with aiohttp.ClientSession() as session:
44-
auth = aiohttp.BasicAuth(self.email, self.password) if self.auth else None
45-
async with session.post(
46-
self.domain + '/api/session',
47-
json=conn_header,
43+
auth = (self.email, self.password) if self.auth else None
44+
async with httpx.AsyncClient() as client:
45+
res = await client.post(
46+
self.domain + '/api/session',
47+
json=conn_header,
4848
auth=auth
49-
) as res:
50-
if res.status != 200:
51-
raise Exception(f"Authentication failed with status {res.status}")
52-
53-
data = await res.json()
54-
self.session_id = data['id']
55-
self.header = {'X-Metabase-Session': self.session_id}
49+
)
50+
if res.status_code != 200:
51+
raise Exception(f"Authentication failed with status {res.status_code}")
52+
53+
data = res.json()
54+
self.session_id = data['id']
55+
self.header = {'X-Metabase-Session': self.session_id}
5656

5757
async def validate_session_async(self):
5858
"""Asynchronously get a new session ID if the previous one has expired"""
@@ -62,19 +62,19 @@ async def validate_session_async(self):
6262
if not self.session_id: # First request
6363
return await self.authenticate_async()
6464

65-
async with aiohttp.ClientSession() as session:
66-
auth = aiohttp.BasicAuth(self.email, self.password) if self.auth else None
67-
async with session.get(
68-
self.domain + '/api/user/current',
65+
auth = (self.email, self.password) if self.auth else None
66+
async with httpx.AsyncClient() as client:
67+
res = await client.get(
68+
self.domain + '/api/user/current',
6969
headers=self.header,
7070
auth=auth
71-
) as res:
72-
if res.status == 200:
73-
return True
74-
elif res.status == 401: # unauthorized
75-
return await self.authenticate_async()
76-
else:
77-
raise Exception(f"Session validation failed with status {res.status}")
71+
)
72+
if res.status_code == 200:
73+
return True
74+
elif res.status_code == 401: # unauthorized
75+
return await self.authenticate_async()
76+
else:
77+
raise Exception(f"Session validation failed with status {res.status_code}")
7878

7979

8080

@@ -152,8 +152,8 @@ async def get_card_data(self, card_name=None, card_id=None, collection_name=None
152152

153153
# return the results in the requested format
154154
if data_format == 'json':
155-
text = await res.text()
155+
text = res.text if hasattr(res, 'text') else await res.text()
156156
return json.loads(text)
157157
if data_format == 'csv':
158-
text = await res.text()
158+
text = res.text if hasattr(res, 'text') else await res.text()
159159
return text.replace('null', '')

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
requests>=2.25.0
2-
aiohttp>=3.8.0
2+
httpx>=0.23.0

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
packages=setuptools.find_packages(),
1616
install_requires=[
1717
"requests",
18-
"aiohttp", # Added aiohttp dependency
18+
"httpx",
1919
],
2020
classifiers=[
2121
"Programming Language :: Python :: 3",

0 commit comments

Comments
 (0)