Coverage for mindsdb / integrations / handlers / youtube_handler / youtube_handler.py: 0%

61 statements  

« prev     ^ index     » next       coverage.py v7.13.1, created at 2026-01-21 00:36 +0000

1from mindsdb.integrations.handlers.youtube_handler.youtube_tables import ( 

2 YoutubeCommentsTable, 

3 YoutubeChannelsTable, 

4 YoutubeVideosTable, 

5) 

6from mindsdb.integrations.libs.api_handler import APIHandler 

7from mindsdb.integrations.libs.response import ( 

8 HandlerStatusResponse as StatusResponse, 

9) 

10from mindsdb.utilities import log 

11from mindsdb_sql_parser import parse_sql 

12 

13from mindsdb.utilities.config import Config 

14 

15from googleapiclient.discovery import build 

16 

17from mindsdb.integrations.utilities.handlers.auth_utilities.google import GoogleUserOAuth2Manager 

18 

19DEFAULT_SCOPES = [ 

20 'https://www.googleapis.com/auth/youtube', 

21 'https://www.googleapis.com/auth/youtube.force-ssl', 

22 'https://www.googleapis.com/auth/youtubepartner' 

23] 

24 

25logger = log.getLogger(__name__) 

26 

27 

28class YoutubeHandler(APIHandler): 

29 """Youtube handler implementation""" 

30 

31 def __init__(self, name=None, **kwargs): 

32 """Initialize the Youtube handler. 

33 Parameters 

34 ---------- 

35 name : str 

36 name of a handler instance 

37 """ 

38 super().__init__(name) 

39 self.connection_data = kwargs.get("connection_data", {}) 

40 self.kwargs = kwargs 

41 

42 self.parser = parse_sql 

43 self.connection = None 

44 self.is_connected = False 

45 

46 self.handler_storage = kwargs['handler_storage'] 

47 

48 self.credentials_url = self.connection_data.get('credentials_url', None) 

49 self.credentials_file = self.connection_data.get('credentials_file', None) 

50 if self.connection_data.get('credentials'): 

51 self.credentials_file = self.connection_data.pop('credentials') 

52 if not self.credentials_file and not self.credentials_url: 

53 # try to get from config 

54 yt_config = Config().get('handlers', {}).get('youtube', {}) 

55 secret_file = yt_config.get('credentials_file') 

56 secret_url = yt_config.get('credentials_url') 

57 if secret_file: 

58 self.credentials_file = secret_file 

59 elif secret_url: 

60 self.credentials_url = secret_url 

61 

62 self.youtube_api_token = self.connection_data.get('youtube_api_token', None) 

63 

64 self.scopes = self.connection_data.get('scopes', DEFAULT_SCOPES) 

65 

66 youtube_video_comments_data = YoutubeCommentsTable(self) 

67 self._register_table("comments", youtube_video_comments_data) 

68 

69 youtube_channel_data = YoutubeChannelsTable(self) 

70 self._register_table("channels", youtube_channel_data) 

71 

72 youtube_video_data = YoutubeVideosTable(self) 

73 self._register_table("videos", youtube_video_data) 

74 

75 def connect(self) -> StatusResponse: 

76 """Set up the connection required by the handler. 

77 Returns 

78 ------- 

79 StatusResponse 

80 connection object 

81 """ 

82 if self.is_connected is True: 

83 return self.connection 

84 

85 google_oauth2_manager = GoogleUserOAuth2Manager(self.handler_storage, self.scopes, self.credentials_file, self.credentials_url, self.connection_data.get('code')) 

86 creds = google_oauth2_manager.get_oauth2_credentials() 

87 

88 youtube = build( 

89 "youtube", "v3", developerKey=self.youtube_api_token, credentials=creds 

90 ) 

91 self.connection = youtube 

92 

93 return self.connection 

94 

95 def check_connection(self) -> StatusResponse: 

96 """Check connection to the handler. 

97 Returns 

98 ------- 

99 StatusResponse 

100 Status confirmation 

101 """ 

102 response = StatusResponse(False) 

103 

104 try: 

105 self.connect() 

106 response.success = True 

107 response.copy_storage = True 

108 except Exception as e: 

109 logger.error(f"Error connecting to Youtube API: {e}!") 

110 response.error_message = e 

111 

112 self.is_connected = response.success 

113 

114 return response 

115 

116 def native_query(self, query: str) -> StatusResponse: 

117 """Receive and process a raw query. 

118 Parameters 

119 ---------- 

120 query : str 

121 query in a native format 

122 Returns 

123 ------- 

124 StatusResponse 

125 Request status 

126 """ 

127 ast = parse_sql(query) 

128 return self.query(ast)