added error message if YouTube requests fail

This commit is contained in:
Jonas Depoix 2021-11-08 09:51:21 +01:00
parent c5bf0132ff
commit c3f8dc0772
4 changed files with 41 additions and 2 deletions

View File

@ -12,4 +12,5 @@ from ._errors import (
CookiePathInvalid, CookiePathInvalid,
CookiesInvalid, CookiesInvalid,
FailedToCreateConsentCookie, FailedToCreateConsentCookie,
YouTubeRequestFailed,
) )

View File

@ -35,6 +35,20 @@ class CouldNotRetrieveTranscript(Exception):
return self.CAUSE_MESSAGE return self.CAUSE_MESSAGE
class YouTubeRequestFailed(CouldNotRetrieveTranscript):
CAUSE_MESSAGE = 'Request to YouTube failed: {reason}'
def __init__(self, video_id, http_error):
self.reason = str(http_error)
super(YouTubeRequestFailed, self).__init__(video_id)
@property
def cause(self):
return self.CAUSE_MESSAGE.format(
reason=self.reason,
)
class VideoUnavailable(CouldNotRetrieveTranscript): class VideoUnavailable(CouldNotRetrieveTranscript):
CAUSE_MESSAGE = 'The video is no longer available' CAUSE_MESSAGE = 'The video is no longer available'

View File

@ -11,10 +11,13 @@ from xml.etree import ElementTree
import re import re
from requests import HTTPError
from ._html_unescaping import unescape from ._html_unescaping import unescape
from ._errors import ( from ._errors import (
VideoUnavailable, VideoUnavailable,
TooManyRequests, TooManyRequests,
YouTubeRequestFailed,
NoTranscriptFound, NoTranscriptFound,
TranscriptsDisabled, TranscriptsDisabled,
NotTranslatable, NotTranslatable,
@ -25,6 +28,14 @@ from ._errors import (
from ._settings import WATCH_URL from ._settings import WATCH_URL
def _raise_http_errors(response, video_id):
try:
response.raise_for_status()
return response
except HTTPError as error:
raise YouTubeRequestFailed(error, video_id)
class TranscriptListFetcher(object): class TranscriptListFetcher(object):
def __init__(self, http_client): def __init__(self, http_client):
self._http_client = http_client self._http_client = http_client
@ -72,7 +83,8 @@ class TranscriptListFetcher(object):
return html return html
def _fetch_html(self, video_id): def _fetch_html(self, video_id):
return self._http_client.get(WATCH_URL.format(video_id=video_id)).text.replace( response = self._http_client.get(WATCH_URL.format(video_id=video_id))
return _raise_http_errors(response, video_id).text.replace(
'\\u0026', '&' '\\u0026', '&'
).replace( ).replace(
'\\', '' '\\', ''
@ -273,8 +285,9 @@ class Transcript(object):
:return: a list of dictionaries containing the 'text', 'start' and 'duration' keys :return: a list of dictionaries containing the 'text', 'start' and 'duration' keys
:rtype [{'text': str, 'start': float, 'end': float}]: :rtype [{'text': str, 'start': float, 'end': float}]:
""" """
response = self._http_client.get(self._url)
return _TranscriptParser().parse( return _TranscriptParser().parse(
self._http_client.get(self._url).text _raise_http_errors(response, self.video_id).text,
) )
def __str__(self): def __str__(self):

View File

@ -19,6 +19,7 @@ from youtube_transcript_api import (
CookiePathInvalid, CookiePathInvalid,
CookiesInvalid, CookiesInvalid,
FailedToCreateConsentCookie, FailedToCreateConsentCookie,
YouTubeRequestFailed,
) )
@ -174,6 +175,16 @@ class TestYouTubeTranscriptApi(TestCase):
with self.assertRaises(VideoUnavailable): with self.assertRaises(VideoUnavailable):
YouTubeTranscriptApi.get_transcript('abc') YouTubeTranscriptApi.get_transcript('abc')
def test_get_transcript__exception_if_youtube_request_fails(self):
httpretty.register_uri(
httpretty.GET,
'https://www.youtube.com/watch',
status=500
)
with self.assertRaises(YouTubeRequestFailed):
YouTubeTranscriptApi.get_transcript('abc')
def test_get_transcript__exception_if_youtube_request_limit_reached(self): def test_get_transcript__exception_if_youtube_request_limit_reached(self):
httpretty.register_uri( httpretty.register_uri(
httpretty.GET, httpretty.GET,