@@ -108,19 +108,26 @@ class InstaparserClient:
108108
109109 BASE_URL = "https://instaparser.com"
110110
111- def __init__ (self , api_key : str , base_url : str | None = None ):
111+ def __init__ (
112+ self ,
113+ api_key : str ,
114+ base_url : str | None = None ,
115+ timeout : float | None = 60 ,
116+ ):
112117 """
113118 Initialize the Instaparser client.
114119
115120 Args:
116121 api_key: Your Instaparser API key
117122 base_url: Optional base URL for the API (defaults to production)
123+ timeout: Default timeout in seconds for blocking operations
118124 """
119125 self .api_key = api_key
120126 self .base_url = base_url or self .BASE_URL
121127 self .headers = {
122128 "Authorization" : f"Bearer { api_key } " ,
123129 }
130+ self .timeout = timeout
124131
125132 def __repr__ (self ) -> str :
126133 return f"<InstaparserClient base_url={ self .base_url !r} >"
@@ -134,6 +141,7 @@ def _request(
134141 params : dict | None = None ,
135142 multipart_fields : dict [str , str ] | None = None ,
136143 multipart_files : dict [str , BinaryIO | bytes ] | None = None ,
144+ timeout : float | None = None ,
137145 ) -> HTTPResponse :
138146 """
139147 Make an HTTP request using urllib.
@@ -145,6 +153,7 @@ def _request(
145153 params: Query parameters
146154 multipart_fields: Form fields for multipart upload
147155 multipart_files: Files for multipart upload
156+ timeout: Timeout in seconds for blocking operations
148157
149158 Returns:
150159 HTTPResponse on success
@@ -166,8 +175,11 @@ def _request(
166175 data = json .dumps (json_data ).encode ("utf-8" )
167176 headers ["Content-Type" ] = "application/json"
168177
178+ if timeout is None :
179+ timeout = self .timeout
180+
169181 req = Request (url , data = data , headers = headers , method = method )
170- response : HTTPResponse = urlopen (req )
182+ response : HTTPResponse = urlopen (req , timeout = timeout )
171183 return response
172184
173185 def _read_json (self , response : HTTPResponse ) -> dict [str , Any ]:
@@ -186,7 +198,14 @@ def _read_json(self, response: HTTPResponse) -> dict[str, Any]:
186198 pass
187199 return {"raw" : body }
188200
189- def article (self , url : str , content : str | None = None , output : str = "html" , use_cache : bool = True ) -> Article :
201+ def article (
202+ self ,
203+ url : str ,
204+ content : str | None = None ,
205+ output : str = "html" ,
206+ use_cache : bool = True ,
207+ timeout : float | None = None ,
208+ ) -> Article :
190209 """
191210 Parse an article from a URL or HTML content.
192211
@@ -195,6 +214,7 @@ def article(self, url: str, content: str | None = None, output: str = "html", us
195214 content: Optional raw HTML content to parse instead of fetching from URL
196215 output: Output format - 'html' (default), 'text', or 'markdown'
197216 use_cache: Whether to use cache (default: True)
217+ timeout: Timeout in seconds (default: use default client timeout)
198218
199219 Returns:
200220 Article object with parsed content
@@ -217,7 +237,12 @@ def article(self, url: str, content: str | None = None, output: str = "html", us
217237 payload ["content" ] = content
218238
219239 try :
220- response = self ._request ("POST" , "/api/1/article" , json_data = payload )
240+ response = self ._request (
241+ "POST" ,
242+ "/api/1/article" ,
243+ json_data = payload ,
244+ timeout = timeout ,
245+ )
221246 except HTTPError as e :
222247 _map_http_error (e )
223248
@@ -245,6 +270,7 @@ def summary(
245270 content : str | None = None ,
246271 use_cache : bool = True ,
247272 stream_callback : Callable [[str ], None ] | None = None ,
273+ timeout : float | None = None ,
248274 ) -> Summary :
249275 """
250276 Generate a summary of an article.
@@ -255,6 +281,7 @@ def summary(
255281 use_cache: Whether to use cache (default: True)
256282 stream_callback: Optional callback function called for each line of streaming response.
257283 If provided, enables streaming mode. The callback receives each line as a string.
284+ timeout: Timeout in seconds (default: use default client timeout)
258285
259286 Returns:
260287 Summary object with key_sentences and overview attributes
@@ -279,7 +306,12 @@ def summary(
279306 payload ["content" ] = content
280307
281308 try :
282- response = self ._request ("POST" , "/api/1/summary" , json_data = payload )
309+ response = self ._request (
310+ "POST" ,
311+ "/api/1/summary" ,
312+ json_data = payload ,
313+ timeout = timeout ,
314+ )
283315 except HTTPError as e :
284316 _map_http_error (e )
285317
@@ -312,6 +344,7 @@ def pdf(
312344 file : BinaryIO | bytes | None = None ,
313345 output : str = "html" ,
314346 use_cache : bool = True ,
347+ timeout : float | None = None ,
315348 ) -> PDF :
316349 """
317350 Parse a PDF from a URL or file.
@@ -321,6 +354,7 @@ def pdf(
321354 file: PDF file to upload (required for POST request, can be file-like object or bytes)
322355 output: Output format - 'html' (default), 'text', or 'markdown'
323356 use_cache: Whether to use cache (default: True)
357+ timeout: Timeout in seconds (default: use default client timeout)
324358
325359 Returns:
326360 PDF object with parsed PDF content (inherits from Article)
@@ -349,6 +383,7 @@ def pdf(
349383 "/api/1/pdf" ,
350384 multipart_fields = fields ,
351385 multipart_files = {"file" : file },
386+ timeout = timeout ,
352387 )
353388 except HTTPError as e :
354389 _map_http_error (e )
@@ -361,7 +396,12 @@ def pdf(
361396 params ["use_cache" ] = "false"
362397
363398 try :
364- response = self ._request ("GET" , "/api/1/pdf" , params = params )
399+ response = self ._request (
400+ "GET" ,
401+ "/api/1/pdf" ,
402+ params = params ,
403+ timeout = timeout ,
404+ )
365405 except HTTPError as e :
366406 _map_http_error (e )
367407 else :
0 commit comments