1111from json import JSONDecodeError
1212from typing import IO , TYPE_CHECKING , Any
1313
14+ import httpx
1415from deprecated import deprecated
15- from requests import Response , Session
16- from requests .adapters import HTTPAdapter , Retry
1716
1817from dune_client .util import get_package_version
1918
@@ -53,17 +52,14 @@ def __init__(
5352 self .performance = performance
5453 self .logger = logging .getLogger (__name__ )
5554 logging .basicConfig (format = "%(asctime)s %(levelname)s %(name)s %(message)s" )
56- retry_strategy = Retry (
57- total = 5 ,
58- backoff_factor = 0.5 ,
59- status_forcelist = {429 , 502 , 503 , 504 },
60- allowed_methods = {"GET" , "POST" , "PATCH" },
61- raise_on_status = True ,
55+
56+ # Configure retry transport for httpx
57+ transport = httpx .HTTPTransport (retries = 5 )
58+ self .http = httpx .Client (
59+ base_url = base_url ,
60+ timeout = request_timeout ,
61+ transport = transport ,
6262 )
63- adapter = HTTPAdapter (max_retries = retry_strategy )
64- self .http = Session ()
65- self .http .mount ("https://" , adapter )
66- self .http .mount ("http://" , adapter )
6763
6864 @classmethod
6965 @deprecated (
@@ -140,7 +136,7 @@ def _build_parameters(
140136class BaseRouter (BaseDuneClient ):
141137 """Extending the Base Client with elementary api routing"""
142138
143- def _handle_response (self , response : Response ) -> Any :
139+ def _handle_response (self , response : httpx . Response ) -> Any :
144140 """Generic response handler utilized by all Dune API routes"""
145141 try :
146142 # Some responses can be decoded and converted to DuneErrors
@@ -158,13 +154,12 @@ def _handle_response(self, response: Response) -> Any:
158154
159155 def _route_url (self , route : str | None = None , url : str | None = None ) -> str :
160156 if route is not None :
161- final_url = f"{ self .base_url } { self .api_version } { route } "
162- elif url is not None :
163- final_url = url
164- else :
165- assert route is not None or url is not None
166-
167- return final_url
157+ # Return relative path - httpx.Client will prepend base_url
158+ return f"{ self .api_version } { route } "
159+ if url is not None :
160+ # Absolute URL provided (e.g., for pagination next_uri)
161+ return url
162+ raise ValueError ("Either route or url must be provided" )
168163
169164 def _get (
170165 self ,
@@ -197,12 +192,12 @@ def _post(
197192 """Generic interface for the POST method of a Dune API request"""
198193 url = self ._route_url (route )
199194 self .logger .debug (f"POST received input url={ url } , params={ params } " )
195+ merged_headers = dict (self .default_headers (), ** headers if headers else {})
200196 response = self .http .post (
201197 url = url ,
202198 json = params ,
203- headers = dict (self .default_headers (), ** headers if headers else {}),
204- timeout = self .request_timeout ,
205- data = data ,
199+ headers = merged_headers ,
200+ content = data ,
206201 )
207202 return self ._handle_response (response )
208203
@@ -214,7 +209,6 @@ def _patch(self, route: str, params: Any) -> Any:
214209 url = url ,
215210 json = params ,
216211 headers = self .default_headers (),
217- timeout = self .request_timeout ,
218212 )
219213 return self ._handle_response (response )
220214
@@ -225,6 +219,5 @@ def _delete(self, route: str) -> Any:
225219 response = self .http .delete (
226220 url = url ,
227221 headers = self .default_headers (),
228- timeout = self .request_timeout ,
229222 )
230223 return self ._handle_response (response )
0 commit comments