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