msdev-kit 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,88 @@
1
+ import time
2
+ import requests
3
+ from typing import Dict
4
+
5
+
6
+ class Notebook:
7
+
8
+ def __init__(self, token: str):
9
+ """
10
+ Initialize variables.
11
+ """
12
+ self.fabric_api_base_url = 'https://api.fabric.microsoft.com'
13
+ self.token = token
14
+ self.headers = {'Authorization': f'Bearer {self.token}'}
15
+
16
+
17
+ def _request_with_retry(self, method: str, url: str, max_retries: int = 3, **kwargs) -> requests.Response:
18
+ """
19
+ Makes an HTTP request with automatic retry on 429 (Too Many Requests).
20
+ Respects the Retry-After header when present.
21
+ """
22
+ for attempt in range(max_retries + 1):
23
+ response = requests.request(method, url, **kwargs)
24
+ if response.status_code != 429:
25
+ return response
26
+
27
+ retry_after = int(response.headers.get('Retry-After', 5))
28
+ print(f" Rate limited (429). Retrying in {retry_after}s... (attempt {attempt + 1}/{max_retries})")
29
+ time.sleep(retry_after)
30
+
31
+ return response
32
+
33
+
34
+ def list_notebooks(self, workspace_id: str) -> Dict:
35
+ """
36
+ Lists all notebooks in a workspace.
37
+
38
+ Args:
39
+ workspace_id (str): The ID of the workspace.
40
+
41
+ Returns:
42
+ Dict: 'message' and 'content' (list of notebook dicts with id, displayName, description).
43
+ """
44
+ if workspace_id == '':
45
+ return {'message': 'Missing workspace id, please check.', 'content': ''}
46
+
47
+ api_url = f'{self.fabric_api_base_url}/v1/workspaces/{workspace_id}/notebooks'
48
+ notebooks = []
49
+
50
+ while api_url:
51
+ response = self._request_with_retry('GET', api_url, headers=self.headers)
52
+ if response.status_code != 200:
53
+ error_data = response.json() if response.headers.get('content-type', '').startswith('application/json') else {}
54
+ error_message = error_data.get('message', error_data.get('error', {}).get('message', response.text))
55
+ return {'message': {'error': error_message, 'status_code': response.status_code}}
56
+
57
+ data = response.json()
58
+ notebooks.extend(data.get('value', []))
59
+ api_url = data.get('continuationUri', None)
60
+
61
+ return {'message': 'Success', 'content': notebooks}
62
+
63
+
64
+ def get_notebook(self, workspace_id: str, notebook_id: str) -> Dict:
65
+ """
66
+ Gets the metadata of a specific notebook.
67
+
68
+ Args:
69
+ workspace_id (str): The ID of the workspace.
70
+ notebook_id (str): The ID of the notebook.
71
+
72
+ Returns:
73
+ Dict: 'message' and 'content' (notebook dict with id, displayName, description, etc.).
74
+ """
75
+ if workspace_id == '':
76
+ return {'message': 'Missing workspace id, please check.', 'content': ''}
77
+ if notebook_id == '':
78
+ return {'message': 'Missing notebook id, please check.', 'content': ''}
79
+
80
+ api_url = f'{self.fabric_api_base_url}/v1/workspaces/{workspace_id}/notebooks/{notebook_id}'
81
+ response = self._request_with_retry('GET', api_url, headers=self.headers)
82
+
83
+ if response.status_code == 200:
84
+ return {'message': 'Success', 'content': response.json()}
85
+ else:
86
+ error_data = response.json() if response.headers.get('content-type', '').startswith('application/json') else {}
87
+ error_message = error_data.get('message', error_data.get('error', {}).get('message', response.text))
88
+ return {'message': {'error': error_message, 'status_code': response.status_code}}
@@ -0,0 +1,108 @@
1
+ import json
2
+ import requests
3
+ from typing import Dict
4
+ from .utilities import create_directory
5
+
6
+
7
+ class Operations:
8
+
9
+ def __init__(self, token: str):
10
+ """
11
+ Initialize variables.
12
+ """
13
+ self.main_url = 'https://api.fabric.microsoft.com/v1'
14
+ self.token = token
15
+ self.headers = {'Authorization': f'Bearer {self.token}'}
16
+ self.data_dir = './data/operations'
17
+
18
+ create_directory(self.data_dir)
19
+
20
+
21
+ def get_operation_state(
22
+ self,
23
+ operation_id: str = '') -> str:
24
+ """
25
+ Get the operation state for a long running operation.
26
+
27
+ Args:
28
+ operation_id (str, optional): operation id to check state.
29
+
30
+ Returns:
31
+ Dict: message and operation state.
32
+ """
33
+
34
+ DEFAULT_STATE = 'unknown'
35
+
36
+ # Main URL
37
+ request_url = f'{self.main_url}/operations/{operation_id}'
38
+
39
+ # If operation ID was not informed, return error message...
40
+ if operation_id == '':
41
+ return {'message': 'Missing operation id, please check.', 'operation_state': DEFAULT_STATE}
42
+
43
+ # If workspace ID was informed...
44
+ else:
45
+
46
+ # Make the request
47
+ r = requests.get(url=request_url, headers=self.headers)
48
+
49
+ # Get HTTP status and content
50
+ status = r.status_code
51
+ response = json.loads(r.content)
52
+
53
+ # If success...
54
+ if status == 200:
55
+ # Get the state
56
+ operation_state = response.get('status', DEFAULT_STATE)
57
+
58
+ return {'message': 'Success', 'operation_state': operation_state}
59
+
60
+ else:
61
+ # If any error happens, return message.
62
+ response = json.loads(r.content)
63
+ error_message = response['error']['message']
64
+
65
+ return {'message': {'error': error_message}, 'operation_state': DEFAULT_STATE}
66
+
67
+
68
+ def get_operation_result(
69
+ self,
70
+ operation_id: str = '') -> Dict:
71
+ """
72
+ Get the operation result for a long running operation.
73
+
74
+ Args:
75
+ operation_id (str, optional): operation id to get result from.
76
+
77
+ Returns:
78
+ Dict: json with it's contents.
79
+ """
80
+
81
+ # Main URL
82
+ request_url = f'{self.main_url}/operations/{operation_id}/result'
83
+
84
+ # If operation ID was not informed, return error message...
85
+ if operation_id == '':
86
+ return {'message': 'Missing operation id, please check.', 'content': ''}
87
+
88
+ # If workspace ID was informed...
89
+ else:
90
+
91
+ # Make the request
92
+ r = requests.get(url=request_url, headers=self.headers)
93
+
94
+ # Get HTTP status and content
95
+ status = r.status_code
96
+ response = json.loads(r.content)
97
+
98
+ # If success...
99
+ if status == 200:
100
+
101
+ return {'message': 'Success', 'content': response}
102
+
103
+ else:
104
+ # If any error happens, return message.
105
+ response = json.loads(r.content)
106
+ error_message = response['error']['message']
107
+
108
+ return {'message': {'error': error_message}, 'content': ''}