File tree Expand file tree Collapse file tree 4 files changed +26
-2
lines changed Expand file tree Collapse file tree 4 files changed +26
-2
lines changed Original file line number Diff line number Diff line change 22from  typing  import  Optional , Iterable 
33
44from  requests  import  Session 
5+ from  requests .adapters  import  HTTPAdapter 
6+ from  urllib3  import  Retry 
57
68from  .proxies  import  ProxyConfig , GenericProxyConfig 
79
@@ -38,6 +40,13 @@ def __init__(
3840            http_client .proxies  =  proxy_config .to_requests_dict ()
3941            if  proxy_config .prevent_keeping_connections_alive :
4042                http_client .headers .update ({"Connection" : "close" })
43+             if  proxy_config .retries_when_blocked  >  0 :
44+                 retry_config  =  Retry (
45+                     total = proxy_config .retries_when_blocked ,
46+                     status_forcelist = [429 ],
47+                 )
48+                 http_client .mount ("http://" , HTTPAdapter (max_retries = retry_config ))
49+                 http_client .mount ("https://" , HTTPAdapter (max_retries = retry_config ))
4150        self ._fetcher  =  TranscriptListFetcher (http_client , proxy_config = proxy_config )
4251
4352    def  fetch (
Original file line number Diff line number Diff line change @@ -152,8 +152,9 @@ class RequestBlocked(CouldNotRetrieveTranscript):
152152    )
153153    WITH_GENERIC_PROXY_CAUSE_MESSAGE  =  (
154154        "YouTube is blocking your requests, despite you using proxies. Keep in mind " 
155-         "a proxy is just a way to hide your real IP behind the IP of that proxy, but " 
156-         "there is no guarantee that the IP of that proxy won't be blocked as well.\n \n " 
155+         "that a proxy is just a way to hide your real IP behind the IP of that proxy, " 
156+         "but there is no guarantee that the IP of that proxy won't be blocked as " 
157+         "well.\n \n " 
157158        "The only truly reliable way to prevent IP blocks is rotating through a large " 
158159        "pool of residential IPs, by using a provider like Webshare " 
159160        "(https://www.webshare.io/?referral_code=w0xno53eb50g), which provides you " 
Original file line number Diff line number Diff line change @@ -92,6 +92,8 @@ class _PlayabilityFailedReason(str, Enum):
9292
9393def  _raise_http_errors (response : Response , video_id : str ) ->  Response :
9494    try :
95+         if  response .status_code  ==  429 :
96+             raise  IpBlocked (video_id )
9597        response .raise_for_status ()
9698        return  response 
9799    except  HTTPError  as  error :
Original file line number Diff line number Diff line change @@ -272,6 +272,18 @@ def test_get_transcript__exception_if_youtube_request_limit_reached(
272272        with  self .assertRaises (IpBlocked ):
273273            YouTubeTranscriptApi ().fetch ("abc" )
274274
275+     def  test_get_transcript__exception_if_timedtext_request_limit_reached (
276+         self ,
277+     ):
278+         httpretty .register_uri (
279+             httpretty .GET ,
280+             "https://www.youtube.com/api/timedtext" ,
281+             status = 429 ,
282+         )
283+ 
284+         with  self .assertRaises (IpBlocked ):
285+             YouTubeTranscriptApi ().fetch ("abc" )
286+ 
275287    def  test_fetch__exception_if_age_restricted (self ):
276288        httpretty .register_uri (
277289            httpretty .POST ,
 
 
   
 
     
   
   
          
    
    
     
    
      
     
     
    You can’t perform that action at this time.
  
 
    
  
    
      
        
     
       
      
     
   
 
    
    
  
 
  
 
     
    
0 commit comments