msfabricpysdkcore 0.0.1__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 @@
1
+ from .client import FabricClientCore
@@ -0,0 +1,61 @@
1
+ import requests
2
+ from abc import abstractmethod
3
+ from azure.identity import AzureCliCredential
4
+
5
+ class FabricAuth():
6
+ """FabricAuth class to interact with Entra ID"""
7
+
8
+ @abstractmethod
9
+ def get_token(self):
10
+ """Get token from Azure AD"""
11
+ pass
12
+
13
+ def get_headers(self):
14
+ """Get headers for API requests"""
15
+ access_token = self.get_token()
16
+ headers = {
17
+ 'Authorization': 'Bearer ' + access_token,
18
+ 'Content-Type': 'application/json'
19
+ }
20
+ return headers
21
+
22
+
23
+ class FabricAuthClient(FabricAuth):
24
+ """FabricAuthClient class to interact with Entra ID"""
25
+
26
+ def __init__(self):
27
+ print("Using Azure CLI for authentication")
28
+ self.auth = AzureCliCredential()
29
+
30
+ def get_token(self):
31
+ """Get token from Azure AD"""
32
+ token = self.auth.get_token("https://api.fabric.microsoft.com/.default")
33
+ return token.token
34
+
35
+ class FabricServicePrincipal(FabricAuth):
36
+ """FabricServicePrincipal class to interact with Entra ID"""
37
+
38
+ def __init__(self, tenant_id, client_id, client_secret):
39
+ print("Using Service Principal for authentication")
40
+
41
+ self.tenant_id = tenant_id
42
+ self.client_id = client_id
43
+ self.client_secret = client_secret
44
+
45
+ self.scope = "https://api.fabric.microsoft.com/.default"
46
+
47
+
48
+ def get_token(self):
49
+ """Get token from Azure AD"""
50
+ # Get token from Azure AD
51
+ url = f"https://login.microsoftonline.com/{self.tenant_id}/oauth2/v2.0/token"
52
+ payload = {
53
+ 'grant_type': 'client_credentials',
54
+ 'client_id': f'{self.client_id}',
55
+ 'client_secret': f'{self.client_secret}',
56
+ 'scope': self.scope
57
+ }
58
+ response = requests.post(url, data=payload)
59
+ access_token = response.json().get('access_token')
60
+ return access_token
61
+
@@ -0,0 +1,283 @@
1
+ import requests
2
+ import json
3
+ import os
4
+ from time import sleep
5
+
6
+ from msfabricpysdkcore.workspace import Workspace
7
+ from msfabricpysdkcore.auth import FabricAuthClient, FabricServicePrincipal
8
+
9
+ class FabricClientCore():
10
+ """FabricClientCore class to interact with Fabric API"""
11
+
12
+ def __init__(self, tenant_id = None, client_id = None, client_secret = None) -> None:
13
+ """Initialize FabricClientCore object"""
14
+ self.tenant_id = tenant_id if tenant_id else os.getenv("FABRIC_TENANT_ID")
15
+ self.client_id = client_id if client_id else os.getenv("FABRIC_CLIENT_ID")
16
+ self.client_secret = client_secret if client_secret else os.getenv("FABRIC_CLIENT_SECRET")
17
+
18
+ if self.client_id is None or self.client_secret is None or self.tenant_id is None:
19
+ self.auth = FabricAuthClient()
20
+ else:
21
+ self.auth = FabricServicePrincipal(tenant_id = self.tenant_id,
22
+ client_id = self.client_id,
23
+ client_secret = self.client_secret)
24
+
25
+ self.scope = "https://api.fabric.microsoft.com/.default"
26
+
27
+
28
+ def list_workspaces(self):
29
+ """List all workspaces in the tenant"""
30
+
31
+ url = "https://api.fabric.microsoft.com/v1/workspaces"
32
+
33
+ for _ in range(10):
34
+ response = requests.get(url=url, headers=self.auth.get_headers())
35
+ if response.status_code == 429:
36
+ print("Too many requests, waiting 10 seconds")
37
+ sleep(10)
38
+ continue
39
+ if response.status_code not in (200, 429):
40
+ print(response.status_code)
41
+ print(response.text)
42
+ items = json.loads(response.text)["value"]
43
+ break
44
+
45
+ ws_list = []
46
+ for i in items:
47
+ ws = Workspace.from_dict(i, auth=self.auth)
48
+ ws_list.append(ws)
49
+ return ws_list
50
+
51
+ def get_workspace_by_name(self, name):
52
+ """Get workspace by name"""
53
+ ws_list = self.list_workspaces()
54
+ for ws in ws_list:
55
+ if ws.display_name == name:
56
+ return ws
57
+
58
+ def get_workspace_by_id(self, id):
59
+ """Get workspace by id"""
60
+ url = f"https://api.fabric.microsoft.com/v1/workspaces/{id}"
61
+
62
+
63
+ for _ in range(10):
64
+ response = requests.get(url=url, headers=self.auth.get_headers())
65
+ if response.status_code == 429:
66
+ print("Too many requests, waiting 10 seconds")
67
+ sleep(10)
68
+ continue
69
+ if response.status_code not in (200, 429):
70
+ print(response.status_code)
71
+ print(response.text)
72
+ ws_dict = json.loads(response.text)
73
+ if "id" not in ws_dict:
74
+ raise Exception(f"Error getting workspace: {response.status_code} {response.text}")
75
+ ws = Workspace.from_dict(json.loads(response.text), auth=self.auth)
76
+
77
+ return ws
78
+
79
+
80
+ def get_workspace(self, id = None, name = None):
81
+ """Get workspace by id or name"""
82
+ if id:
83
+ return self.get_workspace_by_id(id)
84
+ if name:
85
+ return self.get_workspace_by_name(name)
86
+ raise ValueError("Either id or name must be provided")
87
+
88
+ def get_workspace_role_assignments(self, workspace_id):
89
+ """Get role assignments for a workspace"""
90
+ ws = self.get_workspace_by_id(workspace_id)
91
+ return ws.get_role_assignments()
92
+
93
+ def create_workspace(self, display_name, capacity_id = None, description = None, exists_ok = True):
94
+ """Create a workspace"""
95
+ body = dict()
96
+ body["displayName"] = display_name
97
+ if capacity_id:
98
+ body["capacityId"] = capacity_id
99
+ if description:
100
+ body["description"] = description
101
+
102
+ url = "https://api.fabric.microsoft.com/v1/workspaces"
103
+
104
+ for _ in range(10):
105
+ response = requests.post(url=url, headers=self.auth.get_headers(), json=body)
106
+ if response.status_code == 429:
107
+ print("Too many requests, waiting 10 seconds")
108
+ sleep(10)
109
+ continue
110
+ ws_dict = json.loads(response.text)
111
+ if response.status_code not in (201, 429):
112
+ if "errorCode" in ws_dict and ws_dict["errorCode"] == "WorkspaceNameAlreadyExists" and exists_ok:
113
+ return self.get_workspace_by_name(display_name)
114
+ else:
115
+ print(response.status_code)
116
+ print(response.text)
117
+ raise Exception(f"Error creating workspace: {response.text}")
118
+ break
119
+
120
+ ws = Workspace.from_dict(ws_dict, auth=self.auth)
121
+ return ws
122
+
123
+ def delete_workspace(self, workspace_id = None, display_name = None):
124
+ """Delete a workspace"""
125
+ if workspace_id is None and display_name is None:
126
+ raise ValueError("Either workspace_id or display_name must be provided")
127
+ ws = self.get_workspace(id = workspace_id, name = display_name)
128
+ reponse = ws.delete()
129
+ return reponse
130
+
131
+ def add_workspace_role_assignment(self, workspace_id, role, principal):
132
+ """Add a role assignment to a workspace"""
133
+ ws = self.get_workspace_by_id(workspace_id)
134
+ return ws.add_role_assignment(role, principal)
135
+
136
+ def delete_workspace_role_assignment(self, workspace_id, principal_id):
137
+ """Delete a role assignment from a workspace"""
138
+ ws = self.get_workspace_by_id(workspace_id)
139
+ return ws.delete_role_assignment(principal_id)
140
+
141
+ def update_workspace(self, workspace_id, display_name = None, description = None):
142
+ """Update a workspace"""
143
+ ws = self.get_workspace_by_id(workspace_id)
144
+ return ws.update(display_name, description)
145
+
146
+ def update_workspace_role_assignment(self, workspace_id, role, principal_id):
147
+ """Update a role assignment for a workspace"""
148
+ ws = self.get_workspace_by_id(workspace_id)
149
+ return ws.update_role_assignment(role, principal_id)
150
+
151
+ def assign_to_capacity(self, workspace_id, capacity_id):
152
+ """Assign a workspace to a capacity"""
153
+ ws = self.get_workspace_by_id(workspace_id)
154
+ return ws.assign_to_capacity(capacity_id)
155
+
156
+ def unassign_from_capacity(self, workspace_id):
157
+ """Unassign a workspace from a capacity"""
158
+ ws = self.get_workspace_by_id(workspace_id)
159
+ return ws.unassign_from_capacity()
160
+
161
+ def list_capacities(self):
162
+ """List all capacities in the tenant"""
163
+ url = "https://api.fabric.microsoft.com/v1/capacities"
164
+
165
+ for _ in range(10):
166
+ response = requests.get(url=url, headers=self.auth.get_headers())
167
+ if response.status_code == 429:
168
+ print("Too many requests, waiting 10 seconds")
169
+ sleep(10)
170
+ continue
171
+ if response.status_code not in (200, 429):
172
+ print(response.status_code)
173
+ print(response.text)
174
+ raise Exception(f"Error listing capacities: {response.text}")
175
+ break
176
+
177
+ items = json.loads(response.text)["value"]
178
+
179
+ return items
180
+
181
+ def create_item(self, workspace_id, display_name, type, definition = None, description = None):
182
+ """Create an item in a workspace"""
183
+ ws = self.get_workspace_by_id(workspace_id)
184
+
185
+ return ws.create_item(display_name = display_name,
186
+ type = type,
187
+ definition = definition,
188
+ description = description)
189
+
190
+ def get_item(self, workspace_id, item_id):
191
+ """Get an item from a workspace"""
192
+ ws = self.get_workspace_by_id(workspace_id)
193
+ return ws.get_item(item_id)
194
+
195
+ def delete_item(self, workspace_id, item_id):
196
+ """Delete an item from a workspace"""
197
+ ws = self.get_workspace_by_id(workspace_id)
198
+ return ws.delete_item(item_id)
199
+
200
+ def list_items(self, workspace_id):
201
+ """List items in a workspace"""
202
+ ws = self.get_workspace_by_id(workspace_id)
203
+ return ws.list_items()
204
+
205
+ def get_item_definition(self, workspace_id, item_id):
206
+ """Get the definition of an item"""
207
+ ws = self.get_workspace_by_id(workspace_id)
208
+ return ws.get_item_definition(item_id)
209
+
210
+ def update_item(self, workspace_id, item_id, display_name = None, description = None):
211
+ """Update an item in a workspace"""
212
+ ws = self.get_workspace_by_id(workspace_id)
213
+ return ws.get_item(item_id).update(display_name, description)
214
+
215
+ def update_item_definition(self, workspace_id, item_id, definition):
216
+ """Update the definition of an item"""
217
+ ws = self.get_workspace_by_id(id=workspace_id)
218
+ return ws.get_item(item_id=item_id).update_definition(definition=definition)
219
+
220
+ def create_shortcut(self, workspace_id, item_id, path, name, target):
221
+ ws = self.get_workspace_by_id(id=workspace_id)
222
+ return ws.get_item(item_id=item_id).create_shortcut(path=path, name=name, target=target)
223
+
224
+ def get_shortcut(self, workspace_id, item_id, path, name):
225
+ ws = self.get_workspace_by_id(id=workspace_id)
226
+ return ws.get_item(item_id=item_id).get_shortcut(path=path, name=name)
227
+
228
+ def delete_shortcut(self, workspace_id, item_id, path, name):
229
+ ws = self.get_workspace_by_id(id=workspace_id)
230
+ return ws.get_item(item_id=item_id).delete_shortcut(path=path, name=name)
231
+
232
+ def get_item_job_instance(self, workspace_id, item_id, job_instance_id):
233
+ """Get a job instance for an item"""
234
+ ws = self.get_workspace_by_id(id=workspace_id)
235
+ return ws.get_item(item_id=item_id).get_item_job_instance(job_instance_id=job_instance_id)
236
+
237
+ def run_on_demand_item_job(self, workspace_id, item_id, job_type, execution_data = None):
238
+ """Run an on demand job for an item"""
239
+ ws = self.get_workspace_by_id(id=workspace_id)
240
+ return ws.get_item(item_id=item_id).run_on_demand_item_job(job_type=job_type, execution_data=execution_data)
241
+
242
+ def cancel_item_job_instance(self, workspace_id, item_id, job_instance_id):
243
+ """Cancel a job instance for an item"""
244
+ ws = self.get_workspace_by_id(id=workspace_id)
245
+ return ws.get_item(item_id=item_id).get_item_job_instance(job_instance_id=job_instance_id).cancel()
246
+
247
+ def commit_to_git(self, workspace_id,mode, comment=None, items=None, workspace_head=None):
248
+ """Commit changes to git"""
249
+ ws = self.get_workspace_by_id(id=workspace_id)
250
+ return ws.commit_to_git(mode=mode, comment=comment, items=items, workspace_head=workspace_head)
251
+
252
+ def git_connect(self, workspace_id, git_provider_details):
253
+ """Connect to git"""
254
+ ws = self.get_workspace_by_id(id=workspace_id)
255
+ return ws.git_connect(git_provider_details=git_provider_details)
256
+
257
+ def git_disconnect(self, workspace_id):
258
+ """Disconnect from git"""
259
+ ws = self.get_workspace_by_id(id=workspace_id)
260
+ return ws.git_disconnect()
261
+
262
+ def git_get_connection(self, workspace_id):
263
+ """Get git connection details"""
264
+ ws = self.get_workspace_by_id(id=workspace_id)
265
+ return ws.git_get_connection()
266
+
267
+ def git_get_status(self, workspace_id):
268
+ """Get git status"""
269
+ ws = self.get_workspace_by_id(id=workspace_id)
270
+ return ws.git_get_status()
271
+
272
+ def git_initialize_connection(self, workspace_id, initialization_strategy):
273
+ """Initialize git"""
274
+ ws = self.get_workspace_by_id(id=workspace_id)
275
+ return ws.git_initialize_connection(initialization_strategy=initialization_strategy)
276
+
277
+ def update_from_git(self, workspace_id, remote_commit_hash, conflict_resolution = None, options = None, workspace_head = None):
278
+ """Update workspace from git"""
279
+ ws = self.get_workspace_by_id(id=workspace_id)
280
+ return ws.update_from_git(remote_commit_hash=remote_commit_hash,
281
+ conflict_resolution=conflict_resolution,
282
+ options=options,
283
+ workspace_head=workspace_head)
@@ -0,0 +1,246 @@
1
+ import json
2
+ import requests
3
+ from time import sleep
4
+
5
+ from msfabricpysdkcore.onelakeshortcut import OneLakeShortcut
6
+ from msfabricpysdkcore.job_instance import JobInstance
7
+ from msfabricpysdkcore.long_running_operation import check_long_running_operation
8
+
9
+ class Item:
10
+ """Class to represent a item in Microsoft Fabric"""
11
+
12
+ def __init__(self, id, display_name, type, workspace_id, auth, properties = None, definition=None, description="") -> None:
13
+
14
+ self.id = id
15
+ self.display_name = display_name
16
+ self.description = description
17
+ self.type = type
18
+ self.definition = definition
19
+ self.properties = properties
20
+ self.workspace_id = workspace_id
21
+
22
+ self.auth = auth
23
+
24
+ def __str__(self) -> str:
25
+ """Return a string representation of the workspace object"""
26
+ dict_ = {
27
+ 'id': self.id,
28
+ 'display_name': self.display_name,
29
+ 'description': self.description,
30
+ 'type': self.type,
31
+ 'definition': self.definition,
32
+ 'workspace_id': self.workspace_id,
33
+ 'properties': self.properties
34
+ }
35
+ return json.dumps(dict_, indent=2)
36
+
37
+ def from_dict(item_dict, auth):
38
+ """Create Item object from dictionary"""
39
+ return Item(id=item_dict['id'], display_name=item_dict['displayName'], type=item_dict['type'], workspace_id=item_dict['workspaceId'],
40
+ properties=item_dict.get('properties', None),
41
+ definition=item_dict.get('definition', None), description=item_dict.get('description', ""), auth=auth)
42
+
43
+ def delete(self):
44
+ """Delete the workspace item"""
45
+ url = f"https://api.fabric.microsoft.com/v1/workspaces/{self.workspace_id}/items/{self.id}"
46
+ for _ in range(10):
47
+ response = requests.delete(url=url, headers=self.auth.get_headers())
48
+ if response.status_code == 429:
49
+ print("Too many requests, waiting 10 seconds")
50
+ sleep(10)
51
+ continue
52
+ if response.status_code not in (200, 429):
53
+ print(response.status_code)
54
+ print(response.text)
55
+ raise Exception(f"Error deleting item: {response.text}")
56
+ break
57
+
58
+ return response.status_code
59
+
60
+ def get_definition(self):
61
+ """Get the definition of the item"""
62
+
63
+ url = f"https://api.fabric.microsoft.com/v1/workspaces/{self.workspace_id}/items/{self.id}/getDefinition"
64
+
65
+ for _ in range(10):
66
+ response = requests.post(url=url, headers=self.auth.get_headers())
67
+ if response.status_code == 429:
68
+ print("Too many requests, waiting 10 seconds")
69
+ sleep(10)
70
+ continue
71
+ if response.status_code == 202:
72
+ check_long_running_operation( response.headers, self.auth)
73
+
74
+ if response.status_code not in (200, 202, 429):
75
+ print(response.status_code)
76
+ print(response.text)
77
+ raise Exception(f"Error getting item definition: {response.text}")
78
+ break
79
+
80
+ print(response.text)
81
+ print(response.status_code)
82
+ return json.loads(response.text)
83
+
84
+ def update(self, display_name = None, description = None):
85
+ """Update the item"""
86
+ url = f"https://api.fabric.microsoft.com/v1/workspaces/{self.workspace_id}/items/{self.id}"
87
+
88
+ payload = dict()
89
+ if display_name:
90
+ payload['displayName'] = display_name
91
+ if description:
92
+ payload['description'] = description
93
+
94
+ for _ in range(10):
95
+ response = requests.patch(url=url, headers=self.auth.get_headers(), json=payload)
96
+ if response.status_code == 429:
97
+ print("Too many requests, waiting 10 seconds")
98
+ sleep(10)
99
+ continue
100
+ if response.status_code not in (200, 429):
101
+ print(response.status_code)
102
+ print(response.text)
103
+
104
+ raise Exception(f"Error updating item: {response.text}")
105
+ break
106
+ if display_name:
107
+ self.display_name = payload['displayName']
108
+ if description:
109
+ self.description = payload['description']
110
+
111
+ return self
112
+
113
+ def update_definition(self, definition):
114
+ """Update the item definition"""
115
+ url = f"https://api.fabric.microsoft.com/v1/workspaces/{self.workspace_id}/items/{self.id}/updateDefinition"
116
+ payload = {
117
+ 'definition': definition
118
+ }
119
+ for _ in range(10):
120
+ response = requests.post(url=url, headers=self.auth.get_headers(), json=payload)
121
+ if response.status_code == 429:
122
+ print("Too many requests, waiting 10 seconds")
123
+ sleep(10)
124
+ continue
125
+ if response.status_code == 202:
126
+ check_long_running_operation( response.headers, self.auth)
127
+ if response.status_code not in (200, 202, 429):
128
+ print(response.status_code)
129
+ print(response.text)
130
+
131
+ raise Exception(f"Error updating item definition: {response.text}")
132
+ break
133
+
134
+ self.definition = payload['definition']
135
+ return self
136
+
137
+ def get_shortcut(self, path, name):
138
+ """Get the shortcut in the item"""
139
+ url = f"https://api.fabric.microsoft.com/v1/workspaces/{self.workspace_id}/items/{self.id}/shortcuts/{path}/{name}"
140
+
141
+ for _ in range(10):
142
+ response = requests.get(url=url, headers=self.auth.get_headers())
143
+ if response.status_code == 429:
144
+ print("Too many requests, waiting 10 seconds")
145
+ sleep(10)
146
+ continue
147
+ if response.status_code not in (200, 429):
148
+ print(response.status_code)
149
+ print(response.text)
150
+
151
+ raise Exception(f"Error getting shortcut: {response.text}")
152
+ break
153
+
154
+ shortcut_dict = json.loads(response.text)
155
+ shortcut_dict['workspaceId'] = self.workspace_id
156
+ shortcut_dict['itemId'] = self.id
157
+ return OneLakeShortcut.from_dict(shortcut_dict,
158
+ auth = self.auth)
159
+
160
+ def create_shortcut(self, path, name, target):
161
+ """Create a shortcut in the item"""
162
+ url = f"https://api.fabric.microsoft.com/v1/workspaces/{self.workspace_id}/items/{self.id}/shortcuts"
163
+
164
+ body = {'name': name,
165
+ 'path': path,
166
+ 'target': target}
167
+
168
+ for _ in range(10):
169
+ response = requests.post(url=url, headers=self.auth.get_headers(), json=body)
170
+ if response.status_code == 429:
171
+ print("Too many requests, waiting 10 seconds")
172
+ sleep(10)
173
+ continue
174
+ if response.status_code not in (201, 429):
175
+ print(response.status_code)
176
+ print(response.text)
177
+
178
+ raise Exception(f"Error creating shortcut: {response.text}")
179
+ break
180
+
181
+ shortcut_dict = json.loads(response.text)
182
+ shortcut_dict['workspaceId'] = self.workspace_id
183
+ shortcut_dict['itemId'] = self.id
184
+ return OneLakeShortcut.from_dict(shortcut_dict,
185
+ auth = self.auth)
186
+
187
+ def delete_shortcut(self, path, name):
188
+ """Delete the shortcut in the item"""
189
+ return self.get_shortcut(path, name).delete()
190
+
191
+
192
+ def run_on_demand_item_job(self, job_type, execution_data = None):
193
+ """Run an on demand job on the item"""
194
+
195
+ # POST https://api.fabric.microsoft.com/v1/workspaces/{workspaceId}/items/{itemId}/jobs/instances?jobType={jobType}
196
+ url = f"https://api.fabric.microsoft.com/v1/workspaces/{self.workspace_id}/items/{self.id}/jobs/instances?jobType={job_type}"
197
+ payload = {
198
+ 'executionData': execution_data
199
+ }
200
+
201
+ for _ in range(10):
202
+ if execution_data:
203
+ response = requests.post(url=url, headers=self.auth.get_headers(), json=payload)
204
+ else:
205
+ response = requests.post(url=url, headers=self.auth.get_headers())
206
+ if response.status_code == 429:
207
+ print("Too many requests, waiting 10 seconds")
208
+ sleep(10)
209
+ continue
210
+
211
+ if response.status_code not in (202, 429):
212
+ print(response.status_code)
213
+ print(response.text)
214
+
215
+ raise Exception(f"Error running on demand job: {response.text}")
216
+ break
217
+ job_instance_id = response.headers["Location"].split("/")[-1]
218
+ job_instance = self.get_item_job_instance(job_instance_id=job_instance_id)
219
+ return job_instance
220
+
221
+ def get_item_job_instance(self, job_instance_id):
222
+ """Get the job instance of the item"""
223
+
224
+ url = f"https://api.fabric.microsoft.com/v1/workspaces/{self.workspace_id}/items/{self.id}/jobs/instances/{job_instance_id}"
225
+ for _ in range(10):
226
+ response = requests.get(url=url, headers=self.auth.get_headers())
227
+ if response.status_code == 429:
228
+ print("Too many requests, waiting 10 seconds")
229
+ sleep(10)
230
+ continue
231
+ if response.status_code not in (200, 429):
232
+ print(response.status_code)
233
+ print(response.text)
234
+
235
+ raise Exception(f"Error getting job instance: {response.text}")
236
+ break
237
+
238
+ job_dict = json.loads(response.text)
239
+ job_dict['workspaceId'] = self.workspace_id
240
+ job_dict['itemId'] = self.id
241
+ return JobInstance.from_dict(job_dict, auth=self.auth)
242
+
243
+ def cancel_item_job_instance(self, job_instance_id):
244
+ """Cancel a job instance ofjob the item"""
245
+ return self.get_item_job_instance(job_instance_id=job_instance_id).cancel()
246
+
@@ -0,0 +1,66 @@
1
+ import json
2
+ import requests
3
+ from time import sleep
4
+ from msfabricpysdkcore.long_running_operation import check_long_running_operation
5
+
6
+ class JobInstance:
7
+ """Class to represent a job instance in Microsoft Fabric"""
8
+
9
+ def __init__(self, id, item_id, workspace_id, auth, job_type, invoke_type, status, root_activity_id,
10
+ start_time_utc, end_time_utc, failureReason):
11
+
12
+ self.id = id
13
+ self.item_id = item_id
14
+ self.workspace_id = workspace_id
15
+ self.job_type = job_type
16
+ self.invoke_type = invoke_type
17
+ self.status = status
18
+ self.root_activity_id = root_activity_id
19
+ self.start_time_utc = start_time_utc
20
+ self.end_time_utc = end_time_utc
21
+ self.failureReason = failureReason
22
+
23
+ self.auth = auth
24
+
25
+
26
+ def __str__(self) -> str:
27
+ """Return a string representation of the workspace object"""
28
+ dict_ = {
29
+ 'id': self.id,
30
+ 'item_id': self.item_id,
31
+ 'workspace_id': self.workspace_id,
32
+ 'job_type': self.job_type,
33
+ 'invoke_type': self.invoke_type,
34
+ 'status': self.status,
35
+ 'root_activity_id': self.root_activity_id,
36
+ 'start_time_utc': self.start_time_utc,
37
+ 'end_time_utc': self.end_time_utc,
38
+ 'failureReason': self.failureReason
39
+ }
40
+ return json.dumps(dict_, indent=2)
41
+
42
+ def from_dict(job_dict, auth):
43
+ """Create JobInstance object from dictionary"""
44
+ return JobInstance(id=job_dict['id'], item_id=job_dict['itemId'], workspace_id=job_dict['workspaceId'],
45
+ job_type=job_dict['jobType'], invoke_type=job_dict['invokeType'], status=job_dict['status'],
46
+ root_activity_id=job_dict['rootActivityId'], start_time_utc=job_dict['startTimeUtc'],
47
+ end_time_utc=job_dict['endTimeUtc'], failureReason=job_dict['failureReason'], auth=auth)
48
+
49
+ def cancel(self):
50
+ """Cancel the job instance"""
51
+ url = f"https://api.fabric.microsoft.com/v1/workspaces/{self.workspace_id}/items/{self.item_id}/jobs/instances/{self.id}/cancel"
52
+ for _ in range(10):
53
+ response = requests.post(url=url, headers=self.auth.get_headers())
54
+ if response.status_code == 429:
55
+ print("Too many requests, waiting 10 seconds")
56
+ sleep(10)
57
+ continue
58
+
59
+ if response.status_code not in (202, 429):
60
+ print(response.status_code)
61
+ print(response.text)
62
+
63
+ raise Exception(f"Error running on demand job: {response.text}")
64
+ break
65
+
66
+ return response.status_code