msfabricpysdkcore 0.0.9__py3-none-any.whl → 0.0.10__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.
- msfabricpysdkcore/admin_item.py +7 -0
- msfabricpysdkcore/admin_workspace.py +20 -1
- msfabricpysdkcore/adminapi.py +133 -7
- msfabricpysdkcore/coreapi.py +299 -15
- msfabricpysdkcore/deployment_pipeline.py +240 -0
- msfabricpysdkcore/environment.py +222 -0
- msfabricpysdkcore/item.py +11 -7
- msfabricpysdkcore/lakehouse.py +42 -1
- msfabricpysdkcore/long_running_operation.py +2 -6
- msfabricpysdkcore/otheritems.py +90 -3
- msfabricpysdkcore/spark_custom_pool.py +118 -0
- msfabricpysdkcore/tests/test_admin_apis.py +20 -9
- msfabricpysdkcore/tests/test_deployment_pipeline.py +64 -0
- msfabricpysdkcore/tests/test_domains.py +3 -2
- msfabricpysdkcore/tests/test_environments.py +48 -0
- msfabricpysdkcore/tests/test_git.py +3 -1
- msfabricpysdkcore/tests/test_items_incl_lakehouse.py +72 -12
- msfabricpysdkcore/tests/test_jobs.py +4 -0
- msfabricpysdkcore/tests/test_shortcuts.py +3 -1
- msfabricpysdkcore/tests/test_spark.py +91 -0
- msfabricpysdkcore/tests/test_workspaces_capacities.py +2 -1
- msfabricpysdkcore/workspace.py +291 -16
- {msfabricpysdkcore-0.0.9.dist-info → msfabricpysdkcore-0.0.10.dist-info}/METADATA +82 -32
- msfabricpysdkcore-0.0.10.dist-info/RECORD +35 -0
- msfabricpysdkcore-0.0.9.dist-info/RECORD +0 -29
- {msfabricpysdkcore-0.0.9.dist-info → msfabricpysdkcore-0.0.10.dist-info}/LICENSE +0 -0
- {msfabricpysdkcore-0.0.9.dist-info → msfabricpysdkcore-0.0.10.dist-info}/WHEEL +0 -0
- {msfabricpysdkcore-0.0.9.dist-info → msfabricpysdkcore-0.0.10.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,240 @@
|
|
1
|
+
import json
|
2
|
+
from time import sleep
|
3
|
+
|
4
|
+
import requests
|
5
|
+
from msfabricpysdkcore.long_running_operation import check_long_running_operation
|
6
|
+
|
7
|
+
|
8
|
+
class DeploymentPipeline:
|
9
|
+
"""Class to represent a deployment pipeline in Microsoft Fabric"""
|
10
|
+
|
11
|
+
def __init__(self, id, display_name, description, auth) -> None:
|
12
|
+
self.id = id
|
13
|
+
self.display_name = display_name
|
14
|
+
self.description = description
|
15
|
+
self.auth = auth
|
16
|
+
|
17
|
+
|
18
|
+
def from_dict(dict, auth):
|
19
|
+
"""Create a Workspace object from a dictionary"""
|
20
|
+
if dict["displayName"] == None:
|
21
|
+
dict["displayName"] = dict["display_name"]
|
22
|
+
|
23
|
+
|
24
|
+
return DeploymentPipeline(
|
25
|
+
id=dict["id"],
|
26
|
+
display_name=dict["displayName"],
|
27
|
+
description=dict["description"],
|
28
|
+
auth=auth
|
29
|
+
)
|
30
|
+
|
31
|
+
|
32
|
+
def __str__(self) -> str:
|
33
|
+
"""Return a string representation of the workspace object"""
|
34
|
+
dict_ = {"id": self.id, "display_name": self.display_name, "description": self.description}
|
35
|
+
|
36
|
+
return json.dumps(dict_, indent=2)
|
37
|
+
|
38
|
+
def __repr__(self) -> str:
|
39
|
+
return self.__str__()
|
40
|
+
|
41
|
+
def get_pipeline(deployment_pipeline_id, auth):
|
42
|
+
"""Get a deployment pipeline"""
|
43
|
+
# GET https://api.fabric.microsoft.com/v1/deploymentPipelines/{deploymentPipelineId}
|
44
|
+
|
45
|
+
url = f"https://api.fabric.microsoft.com/v1/deploymentPipelines/{deployment_pipeline_id}"
|
46
|
+
|
47
|
+
for _ in range(10):
|
48
|
+
response = requests.get(url=url, headers=auth.get_headers())
|
49
|
+
if response.status_code == 429:
|
50
|
+
print("Too many requests, waiting 10 seconds")
|
51
|
+
sleep(10)
|
52
|
+
continue
|
53
|
+
if response.status_code not in (200, 429):
|
54
|
+
print(response.status_code)
|
55
|
+
print(response.text)
|
56
|
+
raise Exception(f"Error getting item: {response.text}")
|
57
|
+
break
|
58
|
+
|
59
|
+
item_dict = json.loads(response.text)
|
60
|
+
return DeploymentPipeline.from_dict(item_dict, auth)
|
61
|
+
|
62
|
+
def get_stages(self, continuationToken = None):
|
63
|
+
"""Get stages in a deployment pipeline"""
|
64
|
+
# GET https://api.fabric.microsoft.com/v1/deploymentPipelines/{deploymentPipelineId}/stages
|
65
|
+
|
66
|
+
url = f"https://api.fabric.microsoft.com/v1/deploymentPipelines/{self.id}/stages"
|
67
|
+
|
68
|
+
if continuationToken:
|
69
|
+
url += f"?continuationToken={continuationToken}"
|
70
|
+
|
71
|
+
for _ in range(10):
|
72
|
+
response = requests.get(url=url, headers=self.auth.get_headers())
|
73
|
+
if response.status_code == 429:
|
74
|
+
print("Too many requests, waiting 10 seconds")
|
75
|
+
sleep(10)
|
76
|
+
continue
|
77
|
+
if response.status_code not in (200, 429):
|
78
|
+
print(response.status_code)
|
79
|
+
print(response.text)
|
80
|
+
raise Exception(f"Error getting stages: {response.text}")
|
81
|
+
break
|
82
|
+
|
83
|
+
resp_dict = json.loads(response.text)
|
84
|
+
items = resp_dict["value"]
|
85
|
+
for item in items:
|
86
|
+
item["deploymentPipelineId"] = self.id
|
87
|
+
stages = [Deployment_Pipeline_Stage.from_dict(item, self.auth) for item in items]
|
88
|
+
|
89
|
+
if "continuationToken" in resp_dict:
|
90
|
+
stages_next = self.get_stages(continuationToken=resp_dict["continuationToken"])
|
91
|
+
stages.extend(stages_next)
|
92
|
+
|
93
|
+
return stages
|
94
|
+
|
95
|
+
|
96
|
+
def deploy(self, source_stage_id, target_stage_id, created_workspace_details = None,
|
97
|
+
items = None, note = None, wait_for_completion = True):
|
98
|
+
# POST https://api.fabric.microsoft.com/v1/deploymentPipelines/{deploymentPipelineId}/deploy
|
99
|
+
|
100
|
+
url = f"https://api.fabric.microsoft.com/v1/deploymentPipelines/{self.id}/deploy"
|
101
|
+
|
102
|
+
body = {
|
103
|
+
"sourceStageId": source_stage_id,
|
104
|
+
"targetStageId": target_stage_id
|
105
|
+
}
|
106
|
+
|
107
|
+
if created_workspace_details:
|
108
|
+
body["createdWorkspaceDetails"] = created_workspace_details
|
109
|
+
if items:
|
110
|
+
body["items"] = items
|
111
|
+
if note:
|
112
|
+
body["note"] = note
|
113
|
+
|
114
|
+
|
115
|
+
for _ in range(10):
|
116
|
+
response = requests.post(url=url, headers=self.auth.get_headers(), json=body)
|
117
|
+
if response.status_code == 429:
|
118
|
+
print("Too many requests, waiting 10 seconds")
|
119
|
+
sleep(10)
|
120
|
+
continue
|
121
|
+
if response.status_code == 202 and wait_for_completion:
|
122
|
+
print("successfully started the operation")
|
123
|
+
try:
|
124
|
+
operation_result = check_long_running_operation( response.headers, self.auth)
|
125
|
+
return operation_result
|
126
|
+
except Exception as e:
|
127
|
+
print("Problem waiting for long running operation. Returning initial response.")
|
128
|
+
print(e)
|
129
|
+
return response
|
130
|
+
if response.status_code not in (200, 429):
|
131
|
+
print(response.status_code)
|
132
|
+
print(response.text)
|
133
|
+
raise Exception(f"Error deploying: {response.text}")
|
134
|
+
break
|
135
|
+
|
136
|
+
return response.json()
|
137
|
+
|
138
|
+
|
139
|
+
|
140
|
+
def get_deployment_pipeline_stages_items(self, stage_id = None, stage_name = None):
|
141
|
+
"""Get items in a deployment pipeline stage"""
|
142
|
+
|
143
|
+
if stage_id == None and stage_name == None:
|
144
|
+
raise Exception("Please provide either stage_id or stage_name")
|
145
|
+
stages = self.get_stages()
|
146
|
+
if stage_id is None:
|
147
|
+
dep_pip_stages = [stage for stage in stages if stage.display_name == stage_name]
|
148
|
+
if len(dep_pip_stages) == 0:
|
149
|
+
raise Exception(f"Stage with name {stage_name} not found")
|
150
|
+
else:
|
151
|
+
dep_pip_stages = [stage for stage in stages if stage.id == stage_id]
|
152
|
+
if len(dep_pip_stages) == 0:
|
153
|
+
raise Exception(f"Stage with id {stage_id} not found")
|
154
|
+
dep_pip_stage = dep_pip_stages[0]
|
155
|
+
return dep_pip_stage.get_items()
|
156
|
+
|
157
|
+
class Deployment_Pipeline_Stage():
|
158
|
+
|
159
|
+
"""Class to represent a deployment pipeline stage in Microsoft Fabric"""
|
160
|
+
|
161
|
+
def __init__(self, id, order, display_name, description, workspace_id, workspace_name, is_public, deployment_pipeline_id, auth) -> None:
|
162
|
+
self.id = id
|
163
|
+
self.order = order
|
164
|
+
self.display_name = display_name
|
165
|
+
self.description = description
|
166
|
+
self.workspace_id = workspace_id
|
167
|
+
self.workspace_name = workspace_name
|
168
|
+
self.is_public = is_public
|
169
|
+
self.deployment_pipeline_id = deployment_pipeline_id
|
170
|
+
self.auth = auth
|
171
|
+
|
172
|
+
|
173
|
+
def from_dict(dict, auth):
|
174
|
+
"""Create a Workspace object from a dictionary"""
|
175
|
+
if dict["displayName"] is None:
|
176
|
+
dict["displayName"] = dict["display_name"]
|
177
|
+
|
178
|
+
if dict.get("workspaceId", None) is None:
|
179
|
+
dict["workspaceId"] = dict.get("workspace_id", None)
|
180
|
+
|
181
|
+
if dict.get("workspaceName", None) is None:
|
182
|
+
dict["workspaceName"] = dict.get("workspace_name", None)
|
183
|
+
|
184
|
+
if dict["deploymentPipelineId"] is None:
|
185
|
+
dict["deploymentPipelineId"] = dict["deployment_pipeline_id"]
|
186
|
+
|
187
|
+
if dict["isPublic"] is None:
|
188
|
+
dict["isPublic"] = dict["is_public"]
|
189
|
+
|
190
|
+
|
191
|
+
return Deployment_Pipeline_Stage(id=dict["id"],
|
192
|
+
order=dict["order"],
|
193
|
+
display_name=dict["displayName"],
|
194
|
+
description=dict["description"],
|
195
|
+
workspace_id=dict["workspaceId"],
|
196
|
+
workspace_name=dict["workspaceName"],
|
197
|
+
is_public=dict["isPublic"],
|
198
|
+
deployment_pipeline_id=dict["deploymentPipelineId"],
|
199
|
+
auth=auth
|
200
|
+
)
|
201
|
+
|
202
|
+
def __str__(self) -> str:
|
203
|
+
"""Return a string representation of the workspace object"""
|
204
|
+
dict_ = {"id": self.id, "order": self.order, "display_name": self.display_name,
|
205
|
+
"description": self.description, "workspace_id": self.workspace_id,
|
206
|
+
"workspace_name": self.workspace_name,
|
207
|
+
"deployment_pipeline_id": self.deployment_pipeline_id,
|
208
|
+
"is_public": self.is_public}
|
209
|
+
|
210
|
+
return json.dumps(dict_, indent=2)
|
211
|
+
|
212
|
+
def __repr__(self) -> str:
|
213
|
+
return self.__str__()
|
214
|
+
|
215
|
+
|
216
|
+
def get_items(self, continuationToken = None):
|
217
|
+
"""Get items in a deployment pipeline stage"""
|
218
|
+
# GET https://api.fabric.microsoft.com/v1/deploymentPipelines/{deploymentPipelineId}/stages/{stageId}/items
|
219
|
+
|
220
|
+
url = f"https://api.fabric.microsoft.com/v1/deploymentPipelines/{self.deployment_pipeline_id}/stages/{self.id}/items"
|
221
|
+
if continuationToken is not None:
|
222
|
+
url += f"?continuationToken={continuationToken}"
|
223
|
+
|
224
|
+
for _ in range(10):
|
225
|
+
response = requests.get(url=url, headers=self.auth.get_headers())
|
226
|
+
if response.status_code == 429:
|
227
|
+
print("Too many requests, waiting 10 seconds")
|
228
|
+
sleep(10)
|
229
|
+
continue
|
230
|
+
if response.status_code not in (200, 429):
|
231
|
+
print(response.status_code)
|
232
|
+
print(response.text)
|
233
|
+
raise Exception(f"Error getting items: {response.text}")
|
234
|
+
break
|
235
|
+
|
236
|
+
resp_dict = json.loads(response.text)
|
237
|
+
items = resp_dict["value"]
|
238
|
+
return items
|
239
|
+
|
240
|
+
|
@@ -0,0 +1,222 @@
|
|
1
|
+
import json
|
2
|
+
import requests
|
3
|
+
from time import sleep
|
4
|
+
|
5
|
+
from msfabricpysdkcore.item import Item
|
6
|
+
from msfabricpysdkcore.long_running_operation import check_long_running_operation
|
7
|
+
|
8
|
+
class Environment(Item):
|
9
|
+
"""Class to represent a item in Microsoft Fabric"""
|
10
|
+
|
11
|
+
def __init__(self, id, display_name, type, workspace_id, auth, properties = None, definition=None, description="",
|
12
|
+
sparkcompute = None, staging_sparkcompute = None, libraries = None, staging_libraries = None):
|
13
|
+
super().__init__(id, display_name, type, workspace_id, auth, properties, definition, description)
|
14
|
+
|
15
|
+
self.sparkcompute = sparkcompute
|
16
|
+
self.staging_sparkcompute = staging_sparkcompute
|
17
|
+
self.libraries = libraries
|
18
|
+
self.staging_libraries = staging_libraries
|
19
|
+
|
20
|
+
def from_dict(item_dict, auth):
|
21
|
+
return Environment(id=item_dict['id'], display_name=item_dict['displayName'], type=item_dict['type'], workspace_id=item_dict['workspaceId'],
|
22
|
+
properties=item_dict.get('properties', None),
|
23
|
+
definition=item_dict.get('definition', None), description=item_dict.get('description', ""),
|
24
|
+
sparkcompute=item_dict.get('sparkcompute', None),
|
25
|
+
staging_sparkcompute=item_dict.get('staging_sparkcompute', None),
|
26
|
+
libraries=item_dict.get('libraries', None),
|
27
|
+
staging_libraries=item_dict.get('staging_libraries', None),
|
28
|
+
auth=auth)
|
29
|
+
|
30
|
+
# GET https://api.fabric.microsoft.com/v1/workspaces/{workspaceId}/environments/{environmentId}/sparkcompute
|
31
|
+
def get_published_settings(self):
|
32
|
+
"""Get the published settings of the environment"""
|
33
|
+
url = f"https://api.fabric.microsoft.com/v1/workspaces/{self.workspace_id}/environments/{self.id}/sparkcompute"
|
34
|
+
|
35
|
+
for _ in range(10):
|
36
|
+
response = requests.get(url=url, headers=self.auth.get_headers())
|
37
|
+
if response.status_code == 429:
|
38
|
+
print("Too many requests, waiting 10 seconds")
|
39
|
+
sleep(10)
|
40
|
+
continue
|
41
|
+
if response.status_code not in (200, 429):
|
42
|
+
print(response.status_code)
|
43
|
+
print(response.text)
|
44
|
+
print(self)
|
45
|
+
raise Exception(f"Error getting published settings: {response.text}")
|
46
|
+
break
|
47
|
+
|
48
|
+
resp_json = json.loads(response.text)
|
49
|
+
self.sparkcompute = resp_json
|
50
|
+
return resp_json
|
51
|
+
|
52
|
+
# GET https://api.fabric.microsoft.com/v1/workspaces/{workspaceId}/environments/{environmentId}/staging/sparkcompute
|
53
|
+
|
54
|
+
def get_staging_settings(self):
|
55
|
+
"""Get the staging settings of the environment"""
|
56
|
+
url = f"https://api.fabric.microsoft.com/v1/workspaces/{self.workspace_id}/environments/{self.id}/staging/sparkcompute"
|
57
|
+
|
58
|
+
for _ in range(10):
|
59
|
+
response = requests.get(url=url, headers=self.auth.get_headers())
|
60
|
+
if response.status_code == 429:
|
61
|
+
print("Too many requests, waiting 10 seconds")
|
62
|
+
sleep(10)
|
63
|
+
continue
|
64
|
+
if response.status_code not in (200, 429):
|
65
|
+
print(response.status_code)
|
66
|
+
print(response.text)
|
67
|
+
print(self)
|
68
|
+
raise Exception(f"Error getting staging settings: {response.text}")
|
69
|
+
break
|
70
|
+
|
71
|
+
resp_json = json.loads(response.text)
|
72
|
+
self.staging_sparkcompute = resp_json
|
73
|
+
return resp_json
|
74
|
+
|
75
|
+
def update_staging_settings(self, instance_pool, driver_cores, driver_memory, executor_cores, executor_memory,
|
76
|
+
dynamic_executor_allocation, spark_properties, runtime_version):
|
77
|
+
"""Update the staging settings of the environment"""
|
78
|
+
url = f"https://api.fabric.microsoft.com/v1/workspaces/{self.workspace_id}/environments/{self.id}/staging/sparkcompute"
|
79
|
+
body = {
|
80
|
+
"instancePool": instance_pool,
|
81
|
+
"driverCores": driver_cores,
|
82
|
+
"driverMemory": driver_memory,
|
83
|
+
"executorCores": executor_cores,
|
84
|
+
"executorMemory": executor_memory,
|
85
|
+
"dynamicExecutorAllocation": dynamic_executor_allocation,
|
86
|
+
"sparkProperties": spark_properties,
|
87
|
+
"runtimeVersion": runtime_version
|
88
|
+
}
|
89
|
+
for _ in range(10):
|
90
|
+
response = requests.patch(url=url, headers=self.auth.get_headers(), json=body)
|
91
|
+
if response.status_code == 429:
|
92
|
+
print("Too many requests, waiting 10 seconds")
|
93
|
+
sleep(10)
|
94
|
+
continue
|
95
|
+
if response.status_code not in (200, 429):
|
96
|
+
print(response.status_code)
|
97
|
+
print(response.text)
|
98
|
+
print(self)
|
99
|
+
raise Exception(f"Error updating staging settings: {response.text}")
|
100
|
+
break
|
101
|
+
|
102
|
+
self.staging_sparkcompute = body
|
103
|
+
return body
|
104
|
+
|
105
|
+
# GET https://api.fabric.microsoft.com/v1/workspaces/{workspaceId}/environments/{environmentId}/libraries
|
106
|
+
|
107
|
+
def get_published_libraries(self):
|
108
|
+
"""Get the published libraries of the environment"""
|
109
|
+
url = f"https://api.fabric.microsoft.com/v1/workspaces/{self.workspace_id}/environments/{self.id}/libraries"
|
110
|
+
|
111
|
+
for _ in range(10):
|
112
|
+
response = requests.get(url=url, headers=self.auth.get_headers())
|
113
|
+
if response.status_code == 429:
|
114
|
+
print("Too many requests, waiting 10 seconds")
|
115
|
+
sleep(10)
|
116
|
+
continue
|
117
|
+
if response.status_code not in (200, 429):
|
118
|
+
print(response.status_code)
|
119
|
+
print(response.text)
|
120
|
+
print(self)
|
121
|
+
raise Exception(f"Error getting published libraries: {response.text}")
|
122
|
+
break
|
123
|
+
|
124
|
+
resp_json = json.loads(response.text)
|
125
|
+
self.libraries = resp_json
|
126
|
+
return resp_json
|
127
|
+
|
128
|
+
# GET https://api.fabric.microsoft.com/v1/workspaces/{workspaceId}/environments/{environmentId}/staging/libraries
|
129
|
+
|
130
|
+
def get_staging_libraries(self):
|
131
|
+
"""Get the staging libraries of the environment"""
|
132
|
+
url = f"https://api.fabric.microsoft.com/v1/workspaces/{self.workspace_id}/environments/{self.id}/staging/libraries"
|
133
|
+
|
134
|
+
for _ in range(10):
|
135
|
+
response = requests.get(url=url, headers=self.auth.get_headers())
|
136
|
+
if response.status_code == 429:
|
137
|
+
print("Too many requests, waiting 10 seconds")
|
138
|
+
sleep(10)
|
139
|
+
continue
|
140
|
+
if response.status_code not in (200, 429):
|
141
|
+
print(response.status_code)
|
142
|
+
print(response.text)
|
143
|
+
print(self)
|
144
|
+
raise Exception(f"Error getting staging libraries: {response.text}")
|
145
|
+
break
|
146
|
+
|
147
|
+
resp_json = json.loads(response.text)
|
148
|
+
self.staging_libraries = resp_json
|
149
|
+
return resp_json
|
150
|
+
|
151
|
+
|
152
|
+
def update_staging_libraries(self):
|
153
|
+
raise NotImplementedError("This method is not implemented yet because the REST API is not complete")
|
154
|
+
|
155
|
+
# DELETE https://api.fabric.microsoft.com/v1/workspaces/{workspaceId}/environments/{environmentId}/staging/libraries?libraryToDelete={libraryToDelete}
|
156
|
+
|
157
|
+
def delete_staging_library(self, library_to_delete):
|
158
|
+
"""Delete a library from the staging libraries of the environment"""
|
159
|
+
url = f"https://api.fabric.microsoft.com/v1/workspaces/{self.workspace_id}/environments/{self.id}/staging/libraries?libraryToDelete={library_to_delete}"
|
160
|
+
|
161
|
+
for _ in range(10):
|
162
|
+
response = requests.delete(url=url, headers=self.auth.get_headers())
|
163
|
+
if response.status_code == 429:
|
164
|
+
print("Too many requests, waiting 10 seconds")
|
165
|
+
sleep(10)
|
166
|
+
continue
|
167
|
+
if response.status_code not in (200, 429):
|
168
|
+
print(response.status_code)
|
169
|
+
print(response.text)
|
170
|
+
print(self)
|
171
|
+
raise Exception(f"Error deleting staging libraries: {response.text}")
|
172
|
+
break
|
173
|
+
|
174
|
+
return response.text
|
175
|
+
|
176
|
+
# POST https://api.fabric.microsoft.com/v1/workspaces/{workspaceId}/environments/{environmentId}/staging/publish
|
177
|
+
|
178
|
+
def publish_environment(self):
|
179
|
+
"""Publish the staging settings and libraries of the environment"""
|
180
|
+
url = f"https://api.fabric.microsoft.com/v1/workspaces/{self.workspace_id}/environments/{self.id}/staging/publish"
|
181
|
+
|
182
|
+
for _ in range(10):
|
183
|
+
response = requests.post(url=url, headers=self.auth.get_headers())
|
184
|
+
if response.status_code == 429:
|
185
|
+
print("Too many requests, waiting 10 seconds")
|
186
|
+
sleep(10)
|
187
|
+
continue
|
188
|
+
if response.status_code == 202:
|
189
|
+
publish_info = check_long_running_operation(response.headers, self.auth)
|
190
|
+
return publish_info
|
191
|
+
if response.status_code not in (200, 429):
|
192
|
+
print(response.status_code)
|
193
|
+
print(response.text)
|
194
|
+
print(self)
|
195
|
+
raise Exception(f"Error publishing staging: {response.text}")
|
196
|
+
break
|
197
|
+
|
198
|
+
resp_dict = json.loads(response.text)
|
199
|
+
return resp_dict
|
200
|
+
|
201
|
+
|
202
|
+
# POST https://api.fabric.microsoft.com/v1/workspaces/{workspaceId}/environments/{environmentId}/staging/cancelPublish
|
203
|
+
|
204
|
+
def cancel_publish(self):
|
205
|
+
"""Cancel the publishing of the staging settings and libraries of the environment"""
|
206
|
+
url = f"https://api.fabric.microsoft.com/v1/workspaces/{self.workspace_id}/environments/{self.id}/staging/cancelPublish"
|
207
|
+
|
208
|
+
for _ in range(10):
|
209
|
+
response = requests.post(url=url, headers=self.auth.get_headers())
|
210
|
+
if response.status_code == 429:
|
211
|
+
print("Too many requests, waiting 10 seconds")
|
212
|
+
sleep(10)
|
213
|
+
continue
|
214
|
+
if response.status_code not in (200, 429):
|
215
|
+
print(response.status_code)
|
216
|
+
print(response.text)
|
217
|
+
print(self)
|
218
|
+
raise Exception(f"Error canceling publishing: {response.text}")
|
219
|
+
break
|
220
|
+
|
221
|
+
resp_dict = json.loads(response.text)
|
222
|
+
return resp_dict
|
msfabricpysdkcore/item.py
CHANGED
@@ -41,11 +41,6 @@ class Item:
|
|
41
41
|
def from_dict(item_dict, auth):
|
42
42
|
"""Create Item object from dictionary"""
|
43
43
|
|
44
|
-
if item_dict['type'] == "Lakehouse":
|
45
|
-
from msfabricpysdkcore.lakehouse import Lakehouse
|
46
|
-
return Lakehouse(id=item_dict['id'], display_name=item_dict['displayName'], type=item_dict['type'], workspace_id=item_dict['workspaceId'],
|
47
|
-
properties=item_dict.get('properties', None),
|
48
|
-
definition=item_dict.get('definition', None), description=item_dict.get('description', ""), auth=auth)
|
49
44
|
return Item(id=item_dict['id'], display_name=item_dict['displayName'], type=item_dict['type'], workspace_id=item_dict['workspaceId'],
|
50
45
|
properties=item_dict.get('properties', None),
|
51
46
|
definition=item_dict.get('definition', None), description=item_dict.get('description', ""), auth=auth)
|
@@ -71,10 +66,15 @@ class Item:
|
|
71
66
|
|
72
67
|
return response.status_code
|
73
68
|
|
74
|
-
def get_definition(self):
|
69
|
+
def get_definition(self, type = None, format = None):
|
75
70
|
"""Get the definition of the item"""
|
76
71
|
|
77
72
|
url = f"https://api.fabric.microsoft.com/v1/workspaces/{self.workspace_id}/items/{self.id}/getDefinition"
|
73
|
+
if type:
|
74
|
+
url = f"https://api.fabric.microsoft.com/v1/workspaces/{self.workspace_id}/{type}/{self.id}/getDefinition"
|
75
|
+
|
76
|
+
if format:
|
77
|
+
url += f"?format={format}"
|
78
78
|
|
79
79
|
for _ in range(10):
|
80
80
|
response = requests.post(url=url, headers=self.auth.get_headers())
|
@@ -127,9 +127,13 @@ class Item:
|
|
127
127
|
|
128
128
|
return self
|
129
129
|
|
130
|
-
def update_definition(self, definition):
|
130
|
+
def update_definition(self, definition, type = None):
|
131
131
|
"""Update the item definition"""
|
132
132
|
url = f"https://api.fabric.microsoft.com/v1/workspaces/{self.workspace_id}/items/{self.id}/updateDefinition"
|
133
|
+
|
134
|
+
if type:
|
135
|
+
url = f"https://api.fabric.microsoft.com/v1/workspaces/{self.workspace_id}/{type}/{self.id}/updateDefinition"
|
136
|
+
|
133
137
|
payload = {
|
134
138
|
'definition': definition
|
135
139
|
}
|
msfabricpysdkcore/lakehouse.py
CHANGED
@@ -3,6 +3,7 @@ import requests
|
|
3
3
|
from time import sleep
|
4
4
|
|
5
5
|
from msfabricpysdkcore.item import Item
|
6
|
+
from msfabricpysdkcore.long_running_operation import check_long_running_operation
|
6
7
|
|
7
8
|
class Lakehouse(Item):
|
8
9
|
"""Class to represent a item in Microsoft Fabric"""
|
@@ -10,6 +11,10 @@ class Lakehouse(Item):
|
|
10
11
|
def __init__(self, id, display_name, type, workspace_id, auth, properties = None, definition=None, description=""):
|
11
12
|
super().__init__(id, display_name, type, workspace_id, auth, properties, definition, description)
|
12
13
|
|
14
|
+
def from_dict(item_dict, auth):
|
15
|
+
return Lakehouse(id=item_dict['id'], display_name=item_dict['displayName'], type=item_dict['type'], workspace_id=item_dict['workspaceId'],
|
16
|
+
properties=item_dict.get('properties', None),
|
17
|
+
definition=item_dict.get('definition', None), description=item_dict.get('description', ""), auth=auth)
|
13
18
|
|
14
19
|
def list_tables(self, continuationToken = None):
|
15
20
|
"""List all tables in the lakehouse"""
|
@@ -92,4 +97,40 @@ class Lakehouse(Item):
|
|
92
97
|
|
93
98
|
sleep(3)
|
94
99
|
return False
|
95
|
-
|
100
|
+
|
101
|
+
# run on demand table maintenance
|
102
|
+
# POST https://api.fabric.microsoft.com/v1/workspaces/{workspaceId}/lakehouses/{lakehouseId}/jobs/instances?jobType={jobType}
|
103
|
+
|
104
|
+
def run_on_demand_table_maintenance(self, execution_data, job_type = "TableMaintenance", wait_for_completion = True):
|
105
|
+
"""Run on demand table maintenance"""
|
106
|
+
url = f"https://api.fabric.microsoft.com/v1/workspaces/{self.workspace_id}/lakehouses/{self.id}/jobs/instances?jobType={job_type}"
|
107
|
+
|
108
|
+
body = {
|
109
|
+
"executionData": execution_data
|
110
|
+
}
|
111
|
+
|
112
|
+
for _ in range(10):
|
113
|
+
response = requests.post(url=url, headers=self.auth.get_headers(), json=body)
|
114
|
+
if response.status_code == 429:
|
115
|
+
print("Too many requests, waiting 10 seconds")
|
116
|
+
sleep(10)
|
117
|
+
continue
|
118
|
+
if response.status_code == 202 and wait_for_completion:
|
119
|
+
print("successfully started the operation")
|
120
|
+
try:
|
121
|
+
operation_result = check_long_running_operation( response.headers, self.auth)
|
122
|
+
return operation_result
|
123
|
+
except Exception as e:
|
124
|
+
|
125
|
+
print("Problem waiting for long running operation. Returning initial response.")
|
126
|
+
print(e)
|
127
|
+
return response
|
128
|
+
|
129
|
+
if response.status_code not in (200, 202, 429):
|
130
|
+
print(response.status_code)
|
131
|
+
print(response.text)
|
132
|
+
|
133
|
+
raise Exception(f"Error at run on demand table maintenance: {response.text}")
|
134
|
+
break
|
135
|
+
|
136
|
+
return response
|
@@ -25,9 +25,7 @@ class LongRunningOperation:
|
|
25
25
|
if response.status_code == 400:
|
26
26
|
return None
|
27
27
|
if response.status_code not in (200, 429):
|
28
|
-
|
29
|
-
print(response.text)
|
30
|
-
raise Exception(f"Error getting operation results: {response.text}")
|
28
|
+
raise Exception(f"Error getting operation results: {response.status_code}, {response.text}")
|
31
29
|
break
|
32
30
|
|
33
31
|
return json.loads(response.text)
|
@@ -43,9 +41,7 @@ class LongRunningOperation:
|
|
43
41
|
sleep(10)
|
44
42
|
continue
|
45
43
|
if response.status_code not in (200, 429):
|
46
|
-
|
47
|
-
print(response.text)
|
48
|
-
raise Exception(f"Error getting operation state: {response.text}")
|
44
|
+
raise Exception(f"Error getting operation state: {response.status_code}, {response.text}")
|
49
45
|
break
|
50
46
|
|
51
47
|
return json.loads(response.text)
|