msfabricpysdkcore 0.0.11__py3-none-any.whl → 0.0.13__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/adminapi.py +49 -1
- msfabricpysdkcore/coreapi.py +72 -7
- msfabricpysdkcore/environment.py +11 -10
- msfabricpysdkcore/item.py +147 -6
- msfabricpysdkcore/long_running_operation.py +9 -4
- msfabricpysdkcore/otheritems.py +29 -0
- msfabricpysdkcore/tests/test_admin_apis.py +20 -0
- msfabricpysdkcore/tests/test_deployment_pipeline.py +1 -2
- msfabricpysdkcore/tests/test_external_data_shares.py +51 -0
- msfabricpysdkcore/tests/test_git.py +2 -2
- msfabricpysdkcore/tests/test_items_incl_lakehouse.py +14 -52
- msfabricpysdkcore/tests/test_one_lake_data_access_security.py +65 -0
- msfabricpysdkcore/tests/test_sparkjobdefinition.py +55 -0
- msfabricpysdkcore/tests/test_workspaces_capacities.py +57 -47
- msfabricpysdkcore/workspace.py +123 -8
- {msfabricpysdkcore-0.0.11.dist-info → msfabricpysdkcore-0.0.13.dist-info}/METADATA +123 -8
- {msfabricpysdkcore-0.0.11.dist-info → msfabricpysdkcore-0.0.13.dist-info}/RECORD +20 -17
- {msfabricpysdkcore-0.0.11.dist-info → msfabricpysdkcore-0.0.13.dist-info}/WHEEL +1 -1
- {msfabricpysdkcore-0.0.11.dist-info → msfabricpysdkcore-0.0.13.dist-info}/LICENSE +0 -0
- {msfabricpysdkcore-0.0.11.dist-info → msfabricpysdkcore-0.0.13.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,65 @@
|
|
1
|
+
import unittest
|
2
|
+
from dotenv import load_dotenv
|
3
|
+
from msfabricpysdkcore.coreapi import FabricClientCore
|
4
|
+
|
5
|
+
load_dotenv()
|
6
|
+
|
7
|
+
class TestFabricClientCore(unittest.TestCase):
|
8
|
+
|
9
|
+
def __init__(self, *args, **kwargs):
|
10
|
+
super(TestFabricClientCore, self).__init__(*args, **kwargs)
|
11
|
+
self.fc = FabricClientCore()
|
12
|
+
|
13
|
+
def test_one_lake_data_access_security(self):
|
14
|
+
|
15
|
+
fc = self.fc
|
16
|
+
|
17
|
+
workspace_id = "d8a5abe0-9eed-406d-ab46-343bc57ddbe5"
|
18
|
+
item_id = "50368cf3-29e7-4a09-aaf0-289fb5748364"
|
19
|
+
|
20
|
+
resp = fc.list_data_access_roles(workspace_id=workspace_id, item_id=item_id)
|
21
|
+
self.assertEqual(len(resp), 2)
|
22
|
+
|
23
|
+
roles = resp[0]
|
24
|
+
etag = resp[1]
|
25
|
+
|
26
|
+
role1 = roles[1]
|
27
|
+
|
28
|
+
self.assertIn('members', role1)
|
29
|
+
self.assertIn('fabricItemMembers', role1['members'])
|
30
|
+
self.assertGreater(len(role1['members']['fabricItemMembers']), 0)
|
31
|
+
self.assertIn('itemAccess', role1['members']['fabricItemMembers'][0])
|
32
|
+
|
33
|
+
|
34
|
+
|
35
|
+
item_access = role1["members"]["fabricItemMembers"][0]['itemAccess']
|
36
|
+
item_access_old = list(item_access)
|
37
|
+
if 'ReadAll' in item_access:
|
38
|
+
item_access = ['Read', 'Write', 'Execute']
|
39
|
+
else:
|
40
|
+
item_access.append('ReadAll')
|
41
|
+
|
42
|
+
role1["members"]["fabricItemMembers"][0]['itemAccess'] = item_access
|
43
|
+
roles[1] = role1
|
44
|
+
|
45
|
+
resp = fc.create_or_update_data_access_roles(workspace_id=workspace_id,
|
46
|
+
item_id=item_id,
|
47
|
+
data_access_roles=roles,
|
48
|
+
etag_match={"If-Match":etag})
|
49
|
+
|
50
|
+
|
51
|
+
resp = fc.list_data_access_roles(workspace_id=workspace_id, item_id=item_id)
|
52
|
+
self.assertEqual(len(resp), 2)
|
53
|
+
|
54
|
+
roles = resp[0]
|
55
|
+
etag = resp[1]
|
56
|
+
|
57
|
+
role1 = roles[1]
|
58
|
+
|
59
|
+
self.assertIn('members', role1)
|
60
|
+
self.assertIn('fabricItemMembers', role1['members'])
|
61
|
+
self.assertGreater(len(role1['members']['fabricItemMembers']), 0)
|
62
|
+
self.assertIn('itemAccess', role1['members']['fabricItemMembers'][0])
|
63
|
+
|
64
|
+
item_access = role1["members"]["fabricItemMembers"][0]['itemAccess']
|
65
|
+
self.assertNotEqual(item_access, item_access_old)
|
@@ -0,0 +1,55 @@
|
|
1
|
+
import unittest
|
2
|
+
from datetime import datetime
|
3
|
+
from dotenv import load_dotenv
|
4
|
+
from msfabricpysdkcore.coreapi import FabricClientCore
|
5
|
+
|
6
|
+
load_dotenv()
|
7
|
+
|
8
|
+
class TestFabricClientCore(unittest.TestCase):
|
9
|
+
|
10
|
+
def __init__(self, *args, **kwargs):
|
11
|
+
super(TestFabricClientCore, self).__init__(*args, **kwargs)
|
12
|
+
self.fc = FabricClientCore()
|
13
|
+
|
14
|
+
def test_spark_job_definitions(self):
|
15
|
+
|
16
|
+
fc = self.fc
|
17
|
+
workspace_id = 'd8a5abe0-9eed-406d-ab46-343bc57ddbe5'
|
18
|
+
|
19
|
+
datetime_str = datetime.now().strftime("%Y%m%d%H%M%S")
|
20
|
+
spark_job_definition_name = f"sjd{datetime_str}"
|
21
|
+
|
22
|
+
spark_job_definition_w_content = fc.get_spark_job_definition(workspace_id, spark_job_definition_name="helloworld")
|
23
|
+
|
24
|
+
result = fc.run_on_demand_spark_job_definition(workspace_id=workspace_id,
|
25
|
+
spark_job_definition_id=spark_job_definition_w_content.id,
|
26
|
+
job_type="sparkjob")
|
27
|
+
self.assertIsNotNone(result)
|
28
|
+
self.assertEqual(result.job_type, "sparkjob")
|
29
|
+
definition = fc.get_spark_job_definition_definition(workspace_id, spark_job_definition_w_content.id)
|
30
|
+
|
31
|
+
self.assertIsNotNone(definition)
|
32
|
+
self.assertIn("definition", definition)
|
33
|
+
definition = definition["definition"]
|
34
|
+
|
35
|
+
spark_job_definition = fc.create_spark_job_definition(workspace_id, display_name=spark_job_definition_name)
|
36
|
+
fc.update_spark_job_definition_definition(workspace_id, spark_job_definition.id, definition=definition)
|
37
|
+
spark_job_definition = fc.get_spark_job_definition(workspace_id, spark_job_definition_id=spark_job_definition.id)
|
38
|
+
self.assertEqual(spark_job_definition.display_name, spark_job_definition_name)
|
39
|
+
self.assertIsNotNone(spark_job_definition.definition)
|
40
|
+
|
41
|
+
spark_job_definitions = fc.list_spark_job_definitions(workspace_id)
|
42
|
+
spark_job_definition_names = [sjd.display_name for sjd in spark_job_definitions]
|
43
|
+
self.assertGreater(len(spark_job_definitions), 0)
|
44
|
+
self.assertIn(spark_job_definition_name, spark_job_definition_names)
|
45
|
+
|
46
|
+
sjd = fc.get_spark_job_definition(workspace_id, spark_job_definition_name=spark_job_definition_name)
|
47
|
+
self.assertIsNotNone(sjd.id)
|
48
|
+
self.assertEqual(sjd.display_name, spark_job_definition_name)
|
49
|
+
|
50
|
+
sjd = fc.update_spark_job_definition(workspace_id, sjd.id, display_name=f"{spark_job_definition_name}2")
|
51
|
+
sjd = fc.get_spark_job_definition(workspace_id, spark_job_definition_id=sjd.id)
|
52
|
+
self.assertEqual(sjd.display_name, f"{spark_job_definition_name}2")
|
53
|
+
|
54
|
+
status_code = fc.delete_spark_job_definition(workspace_id, sjd.id)
|
55
|
+
self.assertEqual(status_code, 200)
|
@@ -10,118 +10,128 @@ class TestFabricClientCore(unittest.TestCase):
|
|
10
10
|
def __init__(self, *args, **kwargs):
|
11
11
|
super(TestFabricClientCore, self).__init__(*args, **kwargs)
|
12
12
|
self.fc = FabricClientCore()
|
13
|
-
|
14
|
-
self.display_name = "testws" + datetime_str
|
15
|
-
self.workspace_id = None
|
13
|
+
|
16
14
|
|
17
15
|
def test_end_to_end_workspace(self):
|
18
|
-
|
19
|
-
|
16
|
+
fc = self.fc
|
17
|
+
datetime_str = datetime.now().strftime("%Y%m%d%H%M%S")
|
18
|
+
display_name = "testws" + datetime_str
|
19
|
+
ws_created = fc.create_workspace(display_name=display_name,
|
20
20
|
description="test workspace",
|
21
21
|
exists_ok=False)
|
22
22
|
# Add assertions here to verify the result
|
23
|
-
self.assertEqual(ws_created.display_name,
|
24
|
-
|
25
|
-
ws =
|
26
|
-
self.assertEqual(ws.display_name,
|
23
|
+
self.assertEqual(ws_created.display_name, display_name)
|
24
|
+
workspace_id = ws_created.id
|
25
|
+
ws = fc.get_workspace_by_id(id = workspace_id)
|
26
|
+
self.assertEqual(ws.display_name, display_name)
|
27
27
|
self.assertEqual(ws.description, "test workspace")
|
28
28
|
|
29
29
|
# def test_assign_to_capacity(self):
|
30
30
|
|
31
|
-
result_status_code =
|
31
|
+
result_status_code = fc.assign_to_capacity(workspace_id=ws.id,
|
32
32
|
capacity_id="41cb829c-c231-4e9f-b4fc-f9042a6f9840")
|
33
33
|
self.assertEqual(result_status_code, 202)
|
34
34
|
|
35
35
|
|
36
36
|
# def test_list_workspaces(self):
|
37
37
|
|
38
|
-
result =
|
38
|
+
result = fc.list_workspaces()
|
39
39
|
display_names = [ws.display_name for ws in result]
|
40
|
-
self.assertIn(
|
40
|
+
self.assertIn(display_name, display_names)
|
41
41
|
|
42
42
|
for ws in result:
|
43
|
-
if ws.display_name ==
|
43
|
+
if ws.display_name == display_name:
|
44
44
|
self.assertEqual(ws.capacity_id, "41cb829c-c231-4e9f-b4fc-f9042a6f9840")
|
45
45
|
|
46
46
|
|
47
47
|
# def test_get_workspace_by_name(self):
|
48
48
|
|
49
|
-
workspace_name =
|
50
|
-
ws =
|
51
|
-
self.assertEqual(ws.display_name,
|
49
|
+
workspace_name = display_name
|
50
|
+
ws = fc.get_workspace_by_name(name = workspace_name)
|
51
|
+
self.assertEqual(ws.display_name, display_name)
|
52
52
|
|
53
53
|
# def test_get_workspace_by_id(self):
|
54
|
-
ws =
|
55
|
-
self.assertEqual(
|
54
|
+
ws = fc.get_workspace_by_id(id = workspace_id)
|
55
|
+
self.assertEqual(display_name, ws.display_name)
|
56
56
|
|
57
57
|
|
58
58
|
# def test_get_workspace(self):
|
59
|
-
result =
|
60
|
-
self.assertEqual(result.display_name,
|
59
|
+
result = fc.get_workspace_by_id(id = workspace_id)
|
60
|
+
self.assertEqual(result.display_name, display_name)
|
61
61
|
|
62
62
|
# def test_add_role_assignment(self):
|
63
|
-
result_status =
|
64
|
-
|
65
|
-
|
66
|
-
|
63
|
+
result_status = fc.add_workspace_role_assignment(workspace_id = ws.id,
|
64
|
+
principal = {"id" : "fe9dee5d-d244-4c93-8ea1-d5e6a2225c69",
|
65
|
+
"type" : "ServicePrincipal"},
|
66
|
+
role = 'Member')
|
67
67
|
|
68
|
-
self.assertEqual(result_status,
|
68
|
+
self.assertEqual(result_status, 201)
|
69
69
|
|
70
70
|
# def test_get_workspace_role_assignments(self):
|
71
|
-
result =
|
72
|
-
self.assertTrue(
|
73
|
-
|
74
|
-
for user in result["value"]:
|
71
|
+
result = fc.list_workspace_role_assignments(workspace_id = ws.id)
|
72
|
+
self.assertTrue(len(result) == 2)
|
73
|
+
for user in result:
|
75
74
|
if user["principal"]["displayName"] == "fabrictestuser":
|
76
|
-
self.
|
75
|
+
self.assertEqual(user["role"], "Member")
|
76
|
+
|
77
|
+
# Get get_workspace_role_assignment
|
78
|
+
|
79
|
+
result = fc.get_workspace_role_assignment(workspace_id = ws.id,
|
80
|
+
workspace_role_assignment_id = "fe9dee5d-d244-4c93-8ea1-d5e6a2225c69")
|
81
|
+
|
82
|
+
self.assertEqual(result["role"], "Member")
|
77
83
|
|
78
84
|
# def test_update_workspace_role_assignment(self):
|
79
85
|
|
80
|
-
result_status_code =
|
86
|
+
result_status_code = fc.update_workspace_role_assignment(workspace_id = ws.id,
|
81
87
|
role = "Contributor",
|
82
|
-
|
88
|
+
workspace_role_assignment_id= "fe9dee5d-d244-4c93-8ea1-d5e6a2225c69")
|
83
89
|
|
84
90
|
self.assertEqual(result_status_code, 200)
|
85
91
|
|
86
|
-
result =
|
87
|
-
self.assertTrue(
|
88
|
-
|
89
|
-
for user in result["value"]:
|
92
|
+
result = fc.list_workspace_role_assignments(workspace_id = ws.id)
|
93
|
+
self.assertTrue(len(result) == 2)
|
94
|
+
for user in result:
|
90
95
|
if user["principal"]["displayName"] == "fabrictestuser":
|
91
96
|
self.assertTrue(user["role"] == "Contributor")
|
92
97
|
|
93
98
|
# def test_delete_role_assignment(self):
|
94
|
-
result_status_code =
|
95
|
-
|
99
|
+
result_status_code = fc.delete_workspace_role_assignment(workspace_id = ws.id,
|
100
|
+
workspace_role_assignment_id = "fe9dee5d-d244-4c93-8ea1-d5e6a2225c69")
|
96
101
|
self.assertEqual(result_status_code, 200)
|
97
102
|
|
98
103
|
# def test_get_workspace_role_assignments(self):
|
99
|
-
result =
|
100
|
-
self.assertTrue(
|
101
|
-
|
102
|
-
user = result["value"][0]
|
104
|
+
result = fc.list_workspace_role_assignments(workspace_id = ws.id)
|
105
|
+
self.assertTrue(len(result) == 1)
|
106
|
+
user = result[0]
|
103
107
|
# self.assertTrue(user["principal"]["displayName"] == "fabricapi")
|
104
108
|
self.assertTrue(user["role"] == "Admin")
|
105
109
|
|
106
110
|
# def test_update_workspace(self):
|
107
|
-
ws_updated =
|
111
|
+
ws_updated = fc.update_workspace(workspace_id=ws.id,
|
108
112
|
display_name="newn912389u8293",
|
109
113
|
description="new description")
|
110
114
|
self.assertEqual(ws_updated.display_name, "newn912389u8293")
|
111
115
|
self.assertEqual(ws_updated.description, "new description")
|
112
|
-
ws =
|
116
|
+
ws = fc.get_workspace_by_id(id = ws.id)
|
113
117
|
self.assertEqual(ws.display_name, "newn912389u8293")
|
114
118
|
self.assertEqual(ws.description, "new description")
|
115
119
|
|
116
120
|
# def test_unassign_from_capacity(self):
|
117
121
|
|
118
|
-
result_status_code =
|
122
|
+
result_status_code = fc.unassign_from_capacity(workspace_id=ws.id)
|
119
123
|
self.assertEqual(result_status_code, 202)
|
120
|
-
ws =
|
124
|
+
ws = fc.get_workspace_by_id(ws.id)
|
121
125
|
self.assertEqual(ws.capacity_id, None)
|
122
126
|
|
127
|
+
# result = fc.provision_identity(workspace_id=ws.id)
|
128
|
+
# self.assertIsNotNone(result["applicationId"])
|
129
|
+
# fc.deprovision_identity(workspace_id=ws.id)
|
130
|
+
|
131
|
+
|
132
|
+
|
123
133
|
# def test_delete_workspace(self):
|
124
|
-
result_status =
|
134
|
+
result_status = fc.delete_workspace(display_name="newn912389u8293")
|
125
135
|
self.assertEqual(result_status, 200)
|
126
136
|
|
127
137
|
def test_list_capacities(self):
|
msfabricpysdkcore/workspace.py
CHANGED
@@ -42,10 +42,13 @@ class Workspace:
|
|
42
42
|
def __repr__(self) -> str:
|
43
43
|
return self.__str__()
|
44
44
|
|
45
|
-
def
|
46
|
-
"""
|
45
|
+
def list_role_assignments(self, continuationToken = None):
|
46
|
+
"""List role assignments for the workspace"""
|
47
47
|
url = f"https://api.fabric.microsoft.com/v1/workspaces/{self.id}/roleAssignments"
|
48
48
|
|
49
|
+
if continuationToken:
|
50
|
+
url = f"{url}?continuationToken={continuationToken}"
|
51
|
+
|
49
52
|
for _ in range(10):
|
50
53
|
response = requests.get(url=url, headers=self.auth.get_headers())
|
51
54
|
if response.status_code == 429:
|
@@ -58,7 +61,14 @@ class Workspace:
|
|
58
61
|
raise Exception(f"Error getting role assignments: {response.text}")
|
59
62
|
break
|
60
63
|
|
61
|
-
|
64
|
+
resp_dict = json.loads(response.text)
|
65
|
+
role_assignments = resp_dict["value"]
|
66
|
+
|
67
|
+
if "continuationToken" in resp_dict:
|
68
|
+
role_assignments_next = self.list_role_assignments(continuationToken=resp_dict["continuationToken"])
|
69
|
+
role_assignments.extend(role_assignments_next)
|
70
|
+
|
71
|
+
return role_assignments
|
62
72
|
|
63
73
|
def delete(self):
|
64
74
|
"""Delete the workspace"""
|
@@ -94,7 +104,7 @@ class Workspace:
|
|
94
104
|
print("Too many requests, waiting 10 seconds")
|
95
105
|
sleep(10)
|
96
106
|
continue
|
97
|
-
if response.status_code not in (
|
107
|
+
if response.status_code not in (201, 429):
|
98
108
|
print(response.status_code)
|
99
109
|
print(response.text)
|
100
110
|
raise Exception(f"Error adding role assignments: {response.text}")
|
@@ -103,9 +113,9 @@ class Workspace:
|
|
103
113
|
return response.status_code
|
104
114
|
|
105
115
|
|
106
|
-
def delete_role_assignment(self,
|
116
|
+
def delete_role_assignment(self, workspace_role_assignment_id):
|
107
117
|
"""Delete a role assignment from the workspace"""
|
108
|
-
url = f"https://api.fabric.microsoft.com/v1/workspaces/{self.id}/roleAssignments/{
|
118
|
+
url = f"https://api.fabric.microsoft.com/v1/workspaces/{self.id}/roleAssignments/{workspace_role_assignment_id}"
|
109
119
|
|
110
120
|
for _ in range(10):
|
111
121
|
response = requests.delete(url=url, headers=self.auth.get_headers())
|
@@ -150,10 +160,29 @@ class Workspace:
|
|
150
160
|
self.description = description
|
151
161
|
|
152
162
|
return self
|
163
|
+
|
164
|
+
def get_role_assignment(self, workspace_role_assignment_id):
|
165
|
+
# GET https://api.fabric.microsoft.com/v1/workspaces/{workspaceId}/roleAssignments/{workspaceRoleAssignmentId}
|
166
|
+
|
167
|
+
"""Get a role assignment from the workspace"""
|
168
|
+
url = f"https://api.fabric.microsoft.com/v1/workspaces/{self.id}/roleAssignments/{workspace_role_assignment_id}"
|
169
|
+
|
170
|
+
for _ in range(10):
|
171
|
+
response = requests.get(url=url, headers=self.auth.get_headers())
|
153
172
|
|
154
|
-
|
173
|
+
if response.status_code == 429:
|
174
|
+
print("Too many requests, waiting 10 seconds")
|
175
|
+
sleep(10)
|
176
|
+
continue
|
177
|
+
if response.status_code not in (200, 429):
|
178
|
+
raise Exception(f"Error getting role assignments: {response.status_code}, {response.text}")
|
179
|
+
break
|
180
|
+
|
181
|
+
return json.loads(response.text)
|
182
|
+
|
183
|
+
def update_role_assignment(self, role, workspace_role_assignment_id):
|
155
184
|
"""Update a role assignment in the workspace"""
|
156
|
-
url = f"https://api.fabric.microsoft.com/v1/workspaces/{self.id}/roleAssignments/{
|
185
|
+
url = f"https://api.fabric.microsoft.com/v1/workspaces/{self.id}/roleAssignments/{workspace_role_assignment_id}"
|
157
186
|
body = {
|
158
187
|
'role': role
|
159
188
|
}
|
@@ -222,6 +251,45 @@ class Workspace:
|
|
222
251
|
self.capacity_id = None
|
223
252
|
return response.status_code
|
224
253
|
|
254
|
+
def provision_identity(self):
|
255
|
+
# POST https://api.fabric.microsoft.com/v1/workspaces/{workspaceId}/provisionIdentity
|
256
|
+
"""Provision identity for the workspace"""
|
257
|
+
url = f"https://api.fabric.microsoft.com/v1/workspaces/{self.id}/provisionIdentity"
|
258
|
+
|
259
|
+
for _ in range(10):
|
260
|
+
response = requests.post(url=url, headers=self.auth.get_headers())
|
261
|
+
if response.status_code == 429:
|
262
|
+
print("Too many requests, waiting 10 seconds")
|
263
|
+
sleep(10)
|
264
|
+
continue
|
265
|
+
if response.status_code == 202:
|
266
|
+
return check_long_running_operation( response.headers, self.auth)
|
267
|
+
if response.status_code not in (200, 201, 202, 429):
|
268
|
+
raise Exception(f"Error provisioning identity: {response.status_code}, {response.text}")
|
269
|
+
break
|
270
|
+
|
271
|
+
return response
|
272
|
+
|
273
|
+
def deprovision_identity(self):
|
274
|
+
# POST https://api.fabric.microsoft.com/v1/workspaces/{workspaceId}/deprovisionIdentity
|
275
|
+
"""Deprovision identity for the workspace"""
|
276
|
+
url = f"https://api.fabric.microsoft.com/v1/workspaces/{self.id}/deprovisionIdentity"
|
277
|
+
|
278
|
+
for _ in range(10):
|
279
|
+
response = requests.post(url=url, headers=self.auth.get_headers())
|
280
|
+
if response.status_code == 429:
|
281
|
+
print("Too many requests, waiting 10 seconds")
|
282
|
+
sleep(10)
|
283
|
+
continue
|
284
|
+
if response.status_code == 202:
|
285
|
+
return check_long_running_operation( response.headers, self.auth)
|
286
|
+
if response.status_code not in (200, 201, 202, 429):
|
287
|
+
raise Exception(f"Error deprovisioning identity: {response.status_code}, {response.text}")
|
288
|
+
break
|
289
|
+
|
290
|
+
return response
|
291
|
+
|
292
|
+
|
225
293
|
def get_item_specific(self, item_dict):
|
226
294
|
if item_dict["type"] == "DataPipeline":
|
227
295
|
return self.get_data_pipeline(item_dict["id"])
|
@@ -1218,6 +1286,11 @@ class Workspace:
|
|
1218
1286
|
"""Update the definition of a spark job definition in a workspace"""
|
1219
1287
|
return self.get_spark_job_definition(spark_job_definition_id=spark_job_definition_id).update_definition(definition=definition)
|
1220
1288
|
|
1289
|
+
def run_on_demand_spark_job_definition(self, spark_job_definition_id, job_type = "sparkjob"):
|
1290
|
+
"""Run on demand spark job definition"""
|
1291
|
+
sjd = self.get_spark_job_definition(spark_job_definition_id=spark_job_definition_id)
|
1292
|
+
return sjd.run_on_demand_spark_job_definition(job_type=job_type)
|
1293
|
+
|
1221
1294
|
# warehouses
|
1222
1295
|
|
1223
1296
|
def list_warehouses(self, with_properties = False):
|
@@ -1399,3 +1472,45 @@ class Workspace:
|
|
1399
1472
|
|
1400
1473
|
return json.loads(response.text)
|
1401
1474
|
|
1475
|
+
# External Data Shares
|
1476
|
+
|
1477
|
+
# create
|
1478
|
+
|
1479
|
+
def create_external_data_share(self, item_id, paths, recipient):
|
1480
|
+
item = self.get_item(item_id=item_id)
|
1481
|
+
return item.create_external_data_share(paths = paths, recipient = recipient)
|
1482
|
+
|
1483
|
+
# get
|
1484
|
+
|
1485
|
+
def get_external_data_share(self, item_id, external_data_share_id):
|
1486
|
+
item = self.get_item(item_id=item_id)
|
1487
|
+
return item.get_external_data_share(external_data_share_id=external_data_share_id)
|
1488
|
+
|
1489
|
+
|
1490
|
+
# list
|
1491
|
+
|
1492
|
+
def list_external_data_shares_in_item(self, item_id):
|
1493
|
+
item = self.get_item(item_id=item_id)
|
1494
|
+
return item.list_external_data_shares_in_item()
|
1495
|
+
|
1496
|
+
# revoke
|
1497
|
+
|
1498
|
+
def revoke_external_data_share(self, item_id, external_data_share_id):
|
1499
|
+
item = self.get_item(item_id=item_id)
|
1500
|
+
return item.revoke_external_data_share(external_data_share_id=external_data_share_id)
|
1501
|
+
|
1502
|
+
|
1503
|
+
# One Lake Data Access Security
|
1504
|
+
|
1505
|
+
# create and update
|
1506
|
+
|
1507
|
+
def create_or_update_data_access_roles(self, item_id, data_access_roles, dryrun = False, etag_match = None):
|
1508
|
+
item = self.get_item(item_id=item_id).create_or_update_data_access_roles(data_access_roles = data_access_roles,
|
1509
|
+
dryrun = dryrun, etag_match = etag_match)
|
1510
|
+
return item
|
1511
|
+
|
1512
|
+
# list
|
1513
|
+
|
1514
|
+
def list_data_access_roles(self, item_id):
|
1515
|
+
item = self.get_item(item_id=item_id)
|
1516
|
+
return item.list_data_access_roles()
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: msfabricpysdkcore
|
3
|
-
Version: 0.0.
|
3
|
+
Version: 0.0.13
|
4
4
|
Summary: A Python SDK for Microsoft Fabric
|
5
5
|
Author: Andreas Rederer
|
6
6
|
Project-URL: Homepage, https://github.com/DaSenf1860/ms-fabric-sdk-core
|
@@ -38,14 +38,17 @@ Currently it supports all Core APIs, Admin APIs, Lakehouse APIs and all other it
|
|
38
38
|
- Core APIs
|
39
39
|
- [Capacities](#working-with-capacities)
|
40
40
|
- [Deployment Pipelines](#deployment-pipelines)
|
41
|
+
- [External Data Shares](#external-data-shares)
|
41
42
|
- [Git](#working-with-git)
|
42
43
|
- [Items](#working-with-items)
|
43
44
|
- [Job Scheduler](#working-with-job-scheduler)
|
44
45
|
- [Long Running Operations](#long-running-operations)
|
46
|
+
- [OneLakeDataAccessSecurity](#one-lake-data-access-security)
|
45
47
|
- [OneLakeShortcuts](#working-with-one-lake-shortcuts)
|
46
48
|
- [Workspaces](#working-with-workspaces)
|
47
49
|
- Admin APIs
|
48
50
|
- [Domains](#admin-api-for-domains)
|
51
|
+
- [External Data Shares](#admin-api-for-external-data-shares)
|
49
52
|
- [Items](#admin-api-for-items)
|
50
53
|
- [Labels](#admin-api-for-labels)
|
51
54
|
- [Tenants](#admin-api-for-tenants)
|
@@ -148,26 +151,40 @@ ws.add_role_assignment(principal = {"id" : "abadfbafb",
|
|
148
151
|
role = 'Member')
|
149
152
|
|
150
153
|
|
151
|
-
#
|
152
|
-
fc.
|
154
|
+
# List workspace role assignments
|
155
|
+
fc.list_workspace_role_assignments(workspace_id = ws.id)
|
153
156
|
# or
|
154
|
-
ws.
|
157
|
+
ws.list_role_assignments()
|
155
158
|
|
156
159
|
|
160
|
+
# Get workspace role assignment
|
161
|
+
fc.get_workspace_role_assignment(workspace_id = ws.id,
|
162
|
+
workspace_role_assignment_id = "dagdasf")
|
163
|
+
# or
|
164
|
+
ws.get_role_assignment(workspace_role_assignment_id = "fsgdg")
|
165
|
+
|
157
166
|
# Update workspace role assignment
|
158
167
|
fc.update_workspace_role_assignment(workspace_id = ws.id,
|
159
168
|
role = "Contributor",
|
160
|
-
|
169
|
+
workspace_role_assignment_id = "abadfbafb")
|
161
170
|
# or
|
162
171
|
ws.update_role_assignment(role = "Contributor",
|
163
|
-
|
172
|
+
workspace_role_assignment_id = "abadfbafb")
|
164
173
|
|
165
174
|
|
166
175
|
# Delete workspace role assignment
|
167
176
|
fc.delete_workspace_role_assignment(workspace_id = ws.id,
|
168
|
-
|
177
|
+
workspace_role_assignment_id = "abadfbafb")
|
169
178
|
# or
|
170
|
-
ws.delete_role_assignment(
|
179
|
+
ws.delete_role_assignment(workspace_role_assignment_id = "abadfbafb")
|
180
|
+
|
181
|
+
|
182
|
+
# Provision Identity
|
183
|
+
result = fc.provision_identity(workspace_id=ws.id)
|
184
|
+
print(result["applicationId"]))
|
185
|
+
|
186
|
+
# Deprovision Identity
|
187
|
+
fc.deprovision_identity(workspace_id=ws.id)
|
171
188
|
|
172
189
|
```
|
173
190
|
|
@@ -235,6 +252,43 @@ response = pipe.deploy(source_stage_id=dev_stage.id,target_stage_id=prod_stage.i
|
|
235
252
|
|
236
253
|
```
|
237
254
|
|
255
|
+
### External Data Shares
|
256
|
+
|
257
|
+
```python
|
258
|
+
from msfabricpysdkcore.coreapi import FabricClientCore
|
259
|
+
|
260
|
+
fc = FabricClientCore()
|
261
|
+
|
262
|
+
workspace_id = 'yxcvyxcvyxcv'
|
263
|
+
item_id = 'sdfsdfsdfsf'
|
264
|
+
|
265
|
+
|
266
|
+
# Create
|
267
|
+
|
268
|
+
recipient = {
|
269
|
+
"userPrincipalName": "lisa4@fabrikam.com"
|
270
|
+
}
|
271
|
+
paths=["Files/external"]
|
272
|
+
|
273
|
+
data_share = fc.create_external_data_share(workspace_id, item_id, paths, recipient)
|
274
|
+
|
275
|
+
# Get
|
276
|
+
|
277
|
+
data_share2 = fc.get_external_data_share(workspace_id, item_id, data_share['id'])
|
278
|
+
|
279
|
+
# List
|
280
|
+
|
281
|
+
data_share_list = fc.list_external_data_shares_in_item(workspace_id, item_id)
|
282
|
+
|
283
|
+
data_share_ids = [ds['id'] for ds in data_share_list]
|
284
|
+
|
285
|
+
# Revoke
|
286
|
+
|
287
|
+
response_code = fc.revoke_external_data_share(workspace_id, item_id, data_share['id'])
|
288
|
+
|
289
|
+
```
|
290
|
+
|
291
|
+
|
238
292
|
### Working with items
|
239
293
|
|
240
294
|
```python
|
@@ -438,6 +492,44 @@ results = fc.get_operation_results(operation_id)
|
|
438
492
|
|
439
493
|
```
|
440
494
|
|
495
|
+
### One Lake Data Access Security
|
496
|
+
|
497
|
+
```python
|
498
|
+
from msfabricpysdkcore import FabricClientCore
|
499
|
+
|
500
|
+
fc = FabricClientCore()
|
501
|
+
|
502
|
+
workspace_id = "d8aafgasdsdbe5"
|
503
|
+
item_id = "503hsdfhs48364"
|
504
|
+
|
505
|
+
# List
|
506
|
+
|
507
|
+
resp = fc.list_data_access_roles(workspace_id=workspace_id, item_id=item_id)
|
508
|
+
|
509
|
+
roles = resp[0]
|
510
|
+
etag = resp[1]
|
511
|
+
|
512
|
+
|
513
|
+
# Create or Update
|
514
|
+
|
515
|
+
role1 = roles[1]
|
516
|
+
|
517
|
+
item_access = role1["members"]["fabricItemMembers"][0]['itemAccess']
|
518
|
+
+
|
519
|
+
if 'ReadAll' in item_access:
|
520
|
+
item_access = ['Read', 'Write', 'Execute']
|
521
|
+
else:
|
522
|
+
item_access.append('ReadAll')
|
523
|
+
|
524
|
+
role1["members"]["fabricItemMembers"][0]['itemAccess'] = item_access
|
525
|
+
roles[1] = role1
|
526
|
+
|
527
|
+
resp = fc.create_or_update_data_access_roles(workspace_id=workspace_id,
|
528
|
+
item_id=item_id,
|
529
|
+
data_access_roles=roles,
|
530
|
+
etag_match={"If-Match":etag})
|
531
|
+
|
532
|
+
```
|
441
533
|
|
442
534
|
### Admin API for Workspaces
|
443
535
|
|
@@ -597,6 +689,29 @@ status_code = fca.role_assignments_bulk_unassign(domain.id, "Contributors", [pri
|
|
597
689
|
status_code = fca.delete_domain(domain.id)
|
598
690
|
```
|
599
691
|
|
692
|
+
### Admin API for External Data Shares
|
693
|
+
|
694
|
+
```python
|
695
|
+
from msfabricpysdkcore import FabricClientAdmin
|
696
|
+
|
697
|
+
fca = FabricClientAdmin()
|
698
|
+
|
699
|
+
# List external data shares
|
700
|
+
|
701
|
+
data_shares = fca.list_external_data_shares()
|
702
|
+
ws = fca.list_workspaces(name="testworkspace")[0]
|
703
|
+
|
704
|
+
data_shares = [d for d in data_shares if d['workspaceId'] == ws.id]
|
705
|
+
|
706
|
+
# Revoke external data share
|
707
|
+
|
708
|
+
fca.revoke_external_data_share(external_data_share_id = data_shares[0]['id'],
|
709
|
+
item_id = data_shares[0]['itemId'],
|
710
|
+
workspace_id = data_shares[0]['workspaceId'])
|
711
|
+
|
712
|
+
|
713
|
+
```
|
714
|
+
|
600
715
|
|
601
716
|
Note: This SDK is not an official SDK from Microsoft. It is a community project and not supported by Microsoft. Use it at your own risk.
|
602
717
|
Also the API is still in preview and might change. This SDK is not yet feature complete and might not cover all APIs yet. Feel free to contribute to this project to make it better.
|