Coverage for mindsdb / integrations / utilities / handlers / api_utilities / microsoft / ms_graph_api_utilities.py: 77%

56 statements  

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

1import requests 

2import time 

3from typing import Dict, Generator, List, Optional, Text, Union 

4 

5from mindsdb.utilities import log 

6 

7logger = log.getLogger(__name__) 

8 

9 

10class MSGraphAPIBaseClient: 

11 """ 

12 The base class for the Microsoft Graph API clients. 

13 This class contains common methods for accessing the Microsoft Graph API. 

14 

15 Attributes: 

16 MICROSOFT_GRAPH_BASE_API_URL (Text): The base URL of the Microsoft Graph API. 

17 MICROSOFT_GRAPH_API_VERSION (Text): The version of the Microsoft Graph API. 

18 PAGINATION_COUNT (Optional[int]): The number of items to retrieve per request. 

19 """ 

20 MICROSOFT_GRAPH_BASE_API_URL: Text = "https://graph.microsoft.com/" 

21 MICROSOFT_GRAPH_API_VERSION: Text = "v1.0" 

22 PAGINATION_COUNT: Optional[int] = 20 

23 

24 def __init__(self, access_token: Text) -> None: 

25 """ 

26 Initializes the Microsoft Graph API client. 

27 

28 Args: 

29 access_token (Text): The access token for authenticating the requests to the Microsoft Graph API. 

30 """ 

31 self.access_token = access_token 

32 self._group_ids = None 

33 

34 def _get_api_url(self, endpoint: Text) -> Text: 

35 """ 

36 Constructs the API URL for the specified endpoint. 

37 

38 Args: 

39 endpoint (Text): The endpoint of the Microsoft Graph API. 

40 

41 Returns: 

42 Text: The fully constructed API URL. 

43 """ 

44 api_url = f"{self.MICROSOFT_GRAPH_BASE_API_URL}{self.MICROSOFT_GRAPH_API_VERSION}/{endpoint}/" 

45 return api_url 

46 

47 def _make_request( 

48 self, 

49 api_url: Text, 

50 params: Optional[Dict] = None, 

51 data: Optional[Dict] = None, 

52 method: Text = "GET" 

53 ) -> Union[Dict, object]: 

54 """ 

55 Makes a request to the Microsoft Graph API. 

56 

57 Args: 

58 api_url (Text): The API URL to make the request to. 

59 params (Optional[Dict]): The parameters to include in the request. 

60 data (Optional[Dict]): The data to include in the request. 

61 method (Text): The HTTP method to use for the request. 

62 

63 Returns: 

64 Union[Dict, object]: The response content of the request. 

65 """ 

66 headers = {"Authorization": f"Bearer {self.access_token}"} 

67 

68 # Make the request to the Microsoft Graph API based on the method. 

69 if method == "GET": 69 ↛ 71line 69 didn't jump to line 71 because the condition on line 69 was always true

70 response = requests.get(api_url, headers=headers, params=params) 

71 elif method == "POST": 

72 response = requests.post(api_url, headers=headers, json=data) 

73 else: 

74 raise NotImplementedError(f"Method {method} not implemented") 

75 

76 # Process the response. 

77 # If the response is a 429 (rate limit exceeded), wait for the specified time and retry. 

78 if response.status_code == 429: 78 ↛ 79line 78 didn't jump to line 79 because the condition on line 78 was never true

79 if "Retry-After" in response.headers: 

80 pause_time = float(response.headers["Retry-After"]) 

81 time.sleep(pause_time) 

82 response = requests.get(api_url, headers=headers, params=params) 

83 

84 # If the response is not successful, raise an exception. 

85 if response.status_code not in [200, 201]: 

86 raise requests.exceptions.RequestException(response.text) 

87 

88 return response 

89 

90 def fetch_paginated_data(self, endpoint: Text, params: Optional[Dict] = None) -> Generator: 

91 """ 

92 Fetches data from the Microsoft Graph API by making the specified request and handling pagination. 

93 

94 Args: 

95 endpoint (str): The endpoint of the Microsoft Graph API to fetch data from. 

96 params (Optional[Dict]): The parameters to include in the request. 

97 

98 Yields: 

99 List: The data fetched from the Microsoft Graph API. 

100 """ 

101 if params is None: 101 ↛ 103line 101 didn't jump to line 103 because the condition on line 101 was always true

102 params = {} 

103 api_url = self._get_api_url(endpoint) 

104 

105 # Add the pagination count to the request parameters. 

106 if "$top" not in params: 106 ↛ 109line 106 didn't jump to line 109 because the condition on line 106 was always true

107 params["$top"] = self.PAGINATION_COUNT 

108 

109 while api_url: 

110 # Make the initial request to the Microsoft Graph API. 

111 response = self._make_request(api_url, params) 

112 response_json = response.json() 

113 value = response.json()["value"] 

114 

115 # Get the next page of data if pagination is enabled. 

116 params = None 

117 api_url = response_json.get("@odata.nextLink", "") 

118 yield value 

119 

120 def _fetch_data(self, endpoint: str, params: Optional[Dict] = {}) -> Union[List, Dict, bytes]: 

121 """ 

122 Fetches data from the Microsoft Graph API by making the specified request. 

123 

124 Args: 

125 endpoint (str): The endpoint of the Microsoft Graph API to fetch data from. 

126 params (Optional[Dict]): The parameters to include in the request. 

127 

128 Returns: 

129 Union[List, Dict, bytes]: The data fetched from the Microsoft Graph API. 

130 """ 

131 api_url = self._get_api_url(endpoint) 

132 

133 response = self._make_request(api_url, params) 

134 return response 

135 

136 def fetch_data_content(self, endpoint: str, params: Optional[Dict] = {}) -> bytes: 

137 """ 

138 Fetches data content from the Microsoft Graph API by making the specified request. 

139 

140 Args: 

141 endpoint (str): The endpoint of the Microsoft Graph API to fetch data from. 

142 params (Optional[Dict]): The parameters to include in the request. 

143 

144 Returns: 

145 bytes: The data content fetched from the Microsoft Graph API. 

146 """ 

147 response = self._fetch_data(endpoint, params) 

148 return response.content 

149 

150 def fetch_data_json(self, endpoint: str, params: Optional[Dict] = {}) -> Union[List, Dict]: 

151 """ 

152 Fetches data from the Microsoft Graph API by making the specified request and returns the JSON response. 

153 

154 Args: 

155 endpoint (str): The endpoint of the Microsoft Graph API to fetch data from. 

156 params (Optional[Dict]): The parameters to include in the request. 

157 

158 Returns: 

159 Union[List, Dict]: The JSON response fetched from the Microsoft Graph API. 

160 """ 

161 response = self._fetch_data(endpoint, params) 

162 response_json = response.json() 

163 

164 if "value" in response_json: 

165 return response_json["value"] 

166 return response_json