fabrest 0.1.0__tar.gz

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.
Files changed (71) hide show
  1. fabrest-0.1.0/LICENSE +21 -0
  2. fabrest-0.1.0/PKG-INFO +406 -0
  3. fabrest-0.1.0/README.md +394 -0
  4. fabrest-0.1.0/fabrest/__init__.py +0 -0
  5. fabrest-0.1.0/fabrest/api/__init__.py +0 -0
  6. fabrest-0.1.0/fabrest/api/auth.py +111 -0
  7. fabrest-0.1.0/fabrest/api/cancel.py +97 -0
  8. fabrest-0.1.0/fabrest/api/client.py +967 -0
  9. fabrest-0.1.0/fabrest/api/constant.py +151 -0
  10. fabrest-0.1.0/fabrest/api/create.py +221 -0
  11. fabrest-0.1.0/fabrest/api/delete.py +144 -0
  12. fabrest-0.1.0/fabrest/api/get.py +274 -0
  13. fabrest-0.1.0/fabrest/api/list.py +90 -0
  14. fabrest-0.1.0/fabrest/api/load_table.py +193 -0
  15. fabrest-0.1.0/fabrest/api/run.py +105 -0
  16. fabrest-0.1.0/fabrest/api/update.py +394 -0
  17. fabrest-0.1.0/fabrest/api/url.py +189 -0
  18. fabrest-0.1.0/fabrest/logger.py +19 -0
  19. fabrest-0.1.0/fabrest/operator/__init__.py +0 -0
  20. fabrest-0.1.0/fabrest/operator/admin.py +102 -0
  21. fabrest-0.1.0/fabrest/operator/airflow.py +25 -0
  22. fabrest-0.1.0/fabrest/operator/base.py +21 -0
  23. fabrest-0.1.0/fabrest/operator/copy_job.py +43 -0
  24. fabrest-0.1.0/fabrest/operator/dashboard.py +14 -0
  25. fabrest-0.1.0/fabrest/operator/data_pipeline.py +41 -0
  26. fabrest-0.1.0/fabrest/operator/dataflow.py +58 -0
  27. fabrest-0.1.0/fabrest/operator/datalake.py +213 -0
  28. fabrest-0.1.0/fabrest/operator/environment.py +22 -0
  29. fabrest-0.1.0/fabrest/operator/eventhouse.py +24 -0
  30. fabrest-0.1.0/fabrest/operator/eventstream.py +24 -0
  31. fabrest-0.1.0/fabrest/operator/folder.py +19 -0
  32. fabrest-0.1.0/fabrest/operator/graphql_api.py +24 -0
  33. fabrest-0.1.0/fabrest/operator/item.py +23 -0
  34. fabrest-0.1.0/fabrest/operator/job.py +27 -0
  35. fabrest-0.1.0/fabrest/operator/kql_dashboard.py +24 -0
  36. fabrest-0.1.0/fabrest/operator/kql_database.py +25 -0
  37. fabrest-0.1.0/fabrest/operator/kql_queryset.py +25 -0
  38. fabrest-0.1.0/fabrest/operator/lakehouse.py +84 -0
  39. fabrest-0.1.0/fabrest/operator/livy_session.py +19 -0
  40. fabrest-0.1.0/fabrest/operator/mirrored_database.py +24 -0
  41. fabrest-0.1.0/fabrest/operator/mirrored_warehouse.py +14 -0
  42. fabrest-0.1.0/fabrest/operator/ml_experiment.py +22 -0
  43. fabrest-0.1.0/fabrest/operator/ml_model.py +22 -0
  44. fabrest-0.1.0/fabrest/operator/mounted_data_factory.py +24 -0
  45. fabrest-0.1.0/fabrest/operator/notebook.py +42 -0
  46. fabrest-0.1.0/fabrest/operator/paginated_report.py +16 -0
  47. fabrest-0.1.0/fabrest/operator/reflex.py +24 -0
  48. fabrest-0.1.0/fabrest/operator/report.py +24 -0
  49. fabrest-0.1.0/fabrest/operator/role_assignment.py +23 -0
  50. fabrest-0.1.0/fabrest/operator/schedule.py +22 -0
  51. fabrest-0.1.0/fabrest/operator/semantic_model.py +24 -0
  52. fabrest-0.1.0/fabrest/operator/spark.py +199 -0
  53. fabrest-0.1.0/fabrest/operator/spark_job_definition.py +68 -0
  54. fabrest-0.1.0/fabrest/operator/sql_database.py +22 -0
  55. fabrest-0.1.0/fabrest/operator/sql_endpoint.py +14 -0
  56. fabrest-0.1.0/fabrest/operator/table.py +22 -0
  57. fabrest-0.1.0/fabrest/operator/variable_library.py +25 -0
  58. fabrest-0.1.0/fabrest/operator/warehouse.py +23 -0
  59. fabrest-0.1.0/fabrest/operator/workspace.py +244 -0
  60. fabrest-0.1.0/fabrest/utils/__init__.py +0 -0
  61. fabrest-0.1.0/fabrest/utils/functions.py +12 -0
  62. fabrest-0.1.0/fabrest.egg-info/PKG-INFO +406 -0
  63. fabrest-0.1.0/fabrest.egg-info/SOURCES.txt +69 -0
  64. fabrest-0.1.0/fabrest.egg-info/dependency_links.txt +1 -0
  65. fabrest-0.1.0/fabrest.egg-info/requires.txt +3 -0
  66. fabrest-0.1.0/fabrest.egg-info/top_level.txt +1 -0
  67. fabrest-0.1.0/pyproject.toml +16 -0
  68. fabrest-0.1.0/setup.cfg +4 -0
  69. fabrest-0.1.0/tests/test_auth.py +55 -0
  70. fabrest-0.1.0/tests/test_data_pipeline.py +547 -0
  71. fabrest-0.1.0/tests/test_workspace.py +64 -0
fabrest-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 billybillysss
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
fabrest-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,406 @@
1
+ Metadata-Version: 2.4
2
+ Name: fabrest
3
+ Version: 0.1.0
4
+ Summary: A Python Fabric Rest Client to make requests to the Fabric API
5
+ Requires-Python: >=3.11
6
+ Description-Content-Type: text/markdown
7
+ License-File: LICENSE
8
+ Requires-Dist: aiohttp>=3.12.11
9
+ Requires-Dist: azure-identity>=1.23.0
10
+ Requires-Dist: azure-storage-file-datalake>=12.20.0
11
+ Dynamic: license-file
12
+
13
+ # FabRest
14
+
15
+ FabRest is a Python library designed to interact with Microsoft Fabric REST APIs, providing a convenient interface for managing and operating various Fabric resources such as workspaces, data pipelines, lakehouses, and more.
16
+
17
+ ## Overview
18
+
19
+ FabRest aims to simplify the process of automating and managing Microsoft Fabric resources through its REST API. It offers a set of operators and API endpoints that allow developers and data engineers to create, update, delete, and monitor Fabric items programmatically.
20
+
21
+ ## Features
22
+
23
+ - **Authentication**: Securely authenticate with Microsoft Fabric using all methods supported by `azure.identity` (such as `ClientSecretCredential`, `DefaultAzureCredential`, and `InteractiveBrowserCredential`), along with a custom `ResourceOwnerPasswordCredential` provided by this package for ROPC flow.
24
+ - **Resource Management**: Create, update, delete, and list resources like workspaces, lakehouses, data pipelines, and more.
25
+ - **Data Operations**: Manage data pipelines, run jobs, and handle data within Fabric environments.
26
+ - **Comprehensive API Coverage**: Access a wide range of Fabric REST API endpoints for detailed control over your data infrastructure.
27
+ - **Asynchronous Support**: Perform operations asynchronously for improved performance in concurrent environments.
28
+
29
+ ## Installation
30
+
31
+ To install FabRest, you can use pip:
32
+
33
+ ```bash
34
+ pip install fabrest
35
+ ```
36
+
37
+ Alternatively, if you are working from the source code:
38
+
39
+ ```bash
40
+ git clone https://github.com/billybillysss/fabrest.git
41
+ cd fabrest
42
+ pip install .
43
+ ```
44
+
45
+ ## Usage
46
+
47
+ Below are examples of how to use FabRest to manage resources in your Fabric environment. The examples are divided into authentication setup and specific operations for managing data pipelines, with both synchronous and asynchronous approaches for clarity.
48
+
49
+ ### Authentication
50
+
51
+ FabRest supports all authentication methods provided by `azure.identity`, along with a custom credential class for specific use cases. Below are examples of different credential types you can use to authenticate with Microsoft Fabric:
52
+
53
+ **ClientSecretCredential**
54
+
55
+ This method is suitable for service principal authentication in automated workflows or applications.
56
+
57
+ ```python
58
+ from azure.identity import ClientSecretCredential
59
+ from fabrest.operator.workspace import WorkspaceOperator
60
+
61
+ # Initialize the client with your credentials
62
+ credential = ClientSecretCredential(
63
+ client_id="your-client-id",
64
+ client_secret="your-client-secret",
65
+ tenant_id="your-tenant-id",
66
+ )
67
+
68
+ # Initialize a workspace operator
69
+ workspace_operator = WorkspaceOperator(
70
+ id="your-workspace-id",
71
+ credential=credential
72
+ )
73
+ ```
74
+
75
+ **DefaultAzureCredential**
76
+
77
+ This method attempts to authenticate using multiple credential types in order, making it versatile for different environments (e.g., local development, CI/CD pipelines).
78
+
79
+ ```python
80
+ from azure.identity import DefaultAzureCredential
81
+ from fabrest.operator.workspace import WorkspaceOperator
82
+
83
+ # Initialize the client with default credentials
84
+ credential = DefaultAzureCredential()
85
+
86
+ # Initialize a workspace operator
87
+ workspace_operator = WorkspaceOperator(
88
+ id="your-workspace-id",
89
+ credential=credential
90
+ )
91
+ ```
92
+
93
+ **InteractiveBrowserCredential**
94
+
95
+ This method is useful for local development, prompting the user to authenticate via a browser.
96
+
97
+ ```python
98
+ from azure.identity import InteractiveBrowserCredential
99
+ from fabrest.operator.workspace import WorkspaceOperator
100
+
101
+ # Initialize the client with interactive browser credentials
102
+ credential = InteractiveBrowserCredential(
103
+ tenant_id="your-tenant-id",
104
+ client_id="your-client-id"
105
+ )
106
+
107
+ # Initialize a workspace operator
108
+ workspace_operator = WorkspaceOperator(
109
+ id="your-workspace-id",
110
+ credential=credential
111
+ )
112
+ ```
113
+
114
+ **ResourceOwnerPasswordCredential**
115
+
116
+ This custom credential class, created within the FabRest package, handles specific operations or resources in Microsoft Fabric that do not support service principal authentication and require user identity. It uses the Resource Owner Password Credential (ROPC) flow.
117
+
118
+ ```python
119
+ from fabrest.api.auth import ResourceOwnerPasswordCredential
120
+ from fabrest.operator.workspace import WorkspaceOperator
121
+
122
+ # Initialize the client with ROPC credentials for user identity
123
+ credential = ResourceOwnerPasswordCredential(
124
+ tenant_id="your-tenant-id",
125
+ client_id="your-client-id",
126
+ client_secret="your-client-secret",
127
+ username="your-username",
128
+ password="your-password"
129
+ )
130
+
131
+ # Initialize a workspace operator
132
+ workspace_operator = WorkspaceOperator(
133
+ id="your-workspace-id",
134
+ credential=credential
135
+ )
136
+ ```
137
+
138
+ ### Managing Data Pipelines
139
+
140
+ #### Synchronous Operations
141
+
142
+ **Creating a Data Pipeline**
143
+
144
+ ```python
145
+ from fabrest.operator.workspace import WorkspaceOperator
146
+ from azure.identity import ClientSecretCredential
147
+
148
+ # Initialize credentials and operator
149
+ credential = ClientSecretCredential(
150
+ client_id="your-client-id",
151
+ client_secret="your-client-secret",
152
+ tenant_id="your-tenant-id",
153
+ )
154
+ operator = WorkspaceOperator(id="your-workspace-id", credential=credential)
155
+
156
+ # Create a data pipeline
157
+ pipeline_name = "test_pipeline"
158
+ response = operator.data_pipelines.create(payload={"displayName": pipeline_name})
159
+ pipeline_data = response.json()
160
+ pipeline_id = pipeline_data["id"]
161
+ print(f"Created pipeline with ID: {pipeline_id}")
162
+ ```
163
+
164
+ **Listing Data Pipelines**
165
+
166
+ ```python
167
+ # List all data pipelines in the workspace
168
+ pipelines = operator.data_pipelines.list()
169
+ for pipeline in pipelines:
170
+ print(f"Pipeline: {pipeline['displayName']} (ID: {pipeline['id']})")
171
+ ```
172
+
173
+ **Getting a Specific Data Pipeline**
174
+
175
+ ```python
176
+ # Get details of a specific pipeline
177
+ pipeline_data = operator.data_pipelines.get(id=pipeline_id)
178
+ print(f"Retrieved pipeline: {pipeline_data['displayName']} (ID: {pipeline_data['id']})")
179
+ ```
180
+
181
+ **Updating a Data Pipeline Name**
182
+
183
+ ```python
184
+ # Update pipeline name
185
+ updated_name = pipeline_name + "_updated"
186
+ response = operator.data_pipelines.update(id=pipeline_id, payload={"displayName": updated_name})
187
+ updated_data = response.json()
188
+ print(f"Updated pipeline name to: {updated_data['displayName']}")
189
+ ```
190
+
191
+ **Updating a Data Pipeline Definition**
192
+
193
+ ```python
194
+ import json
195
+ from fabrest.utils.functions import encode_base64
196
+
197
+ # Update pipeline definition with a new activity
198
+ update_def_payload = {
199
+ "properties": {
200
+ "activities": [
201
+ {
202
+ "name": "WaitActivity",
203
+ "type": "Wait",
204
+ "dependsOn": [],
205
+ "typeProperties": {"waitTimeInSeconds": 15},
206
+ }
207
+ ]
208
+ }
209
+ }
210
+ current_definition = operator.data_pipelines.get_definition(id=pipeline_id)
211
+ parts = current_definition["definition"]["parts"]
212
+ pipeline_content = json.dumps(update_def_payload)
213
+ pipeline_part = next((p for p in parts if p["path"] == "pipeline-content.json"), None)
214
+ if pipeline_part:
215
+ pipeline_part["payload"] = encode_base64(pipeline_content)
216
+ else:
217
+ parts.append({"path": "pipeline-content.json", "payload": encode_base64(pipeline_content)})
218
+ operator.data_pipelines.update_definition(id=pipeline_id, payload=current_definition)
219
+ print("Updated pipeline definition")
220
+ ```
221
+
222
+ **Deleting a Data Pipeline**
223
+
224
+ ```python
225
+ # Delete the pipeline
226
+ operator.data_pipelines.delete(id=pipeline_id)
227
+ print("Deleted pipeline")
228
+ ```
229
+
230
+ #### Asynchronous Operations
231
+
232
+ **Creating a Data Pipeline Asynchronously**
233
+
234
+ ```python
235
+ import asyncio
236
+ from fabrest.operator.workspace import WorkspaceOperator
237
+ from azure.identity import ClientSecretCredential
238
+
239
+ async def create_pipeline():
240
+ # Initialize credentials and operator
241
+ credential = ClientSecretCredential(
242
+ client_id="your-client-id",
243
+ client_secret="your-client-secret",
244
+ tenant_id="your-tenant-id",
245
+ )
246
+ operator = WorkspaceOperator(id="your-workspace-id", credential=credential)
247
+
248
+ # Create a data pipeline asynchronously
249
+ pipeline_name = "test_pipeline_async"
250
+ response = await operator.data_pipelines.async_create(payload={"displayName": pipeline_name})
251
+ pipeline_data = await response.json()
252
+ pipeline_id = pipeline_data["id"]
253
+ print(f"Created pipeline with ID: {pipeline_id}")
254
+ return pipeline_id
255
+
256
+ # Run the async function
257
+ pipeline_id = asyncio.run(create_pipeline())
258
+ ```
259
+
260
+ **Listing Data Pipelines Asynchronously**
261
+
262
+ ```python
263
+ async def list_pipelines():
264
+ # Initialize credentials and operator as above
265
+ credential = ClientSecretCredential(
266
+ client_id="your-client-id",
267
+ client_secret="your-client-secret",
268
+ tenant_id="your-tenant-id",
269
+ )
270
+ operator = WorkspaceOperator(id="your-workspace-id", credential=credential)
271
+
272
+ # List all data pipelines asynchronously
273
+ pipelines = await operator.data_pipelines.async_list()
274
+ for pipeline in pipelines:
275
+ print(f"Pipeline: {pipeline['displayName']} (ID: {pipeline['id']})")
276
+
277
+ # Run the async function
278
+ asyncio.run(list_pipelines())
279
+ ```
280
+
281
+ **Getting a Specific Data Pipeline Asynchronously**
282
+
283
+ ```python
284
+ async def get_pipeline(pipeline_id):
285
+ # Initialize credentials and operator as above
286
+ credential = ClientSecretCredential(
287
+ client_id="your-client-id",
288
+ client_secret="your-client-secret",
289
+ tenant_id="your-tenant-id",
290
+ )
291
+ operator = WorkspaceOperator(id="your-workspace-id", credential=credential)
292
+
293
+ # Get details of a specific pipeline asynchronously
294
+ pipeline_data = await operator.data_pipelines.async_get(id=pipeline_id)
295
+ print(f"Retrieved pipeline: {pipeline_data['displayName']} (ID: {pipeline_data['id']})")
296
+
297
+ # Run the async function
298
+ asyncio.run(get_pipeline(pipeline_id))
299
+ ```
300
+
301
+ **Updating a Data Pipeline Name Asynchronously**
302
+
303
+ ```python
304
+ async def update_pipeline_name(pipeline_id):
305
+ # Initialize credentials and operator as above
306
+ credential = ClientSecretCredential(
307
+ client_id="your-client-id",
308
+ client_secret="your-client-secret",
309
+ tenant_id="your-tenant-id",
310
+ )
311
+ operator = WorkspaceOperator(id="your-workspace-id", credential=credential)
312
+
313
+ # Update pipeline name asynchronously
314
+ updated_name = "test_pipeline_async_updated"
315
+ await operator.data_pipelines.async_update(id=pipeline_id, payload={"displayName": updated_name})
316
+ updated_data = await operator.data_pipelines.async_get(id=pipeline_id)
317
+ print(f"Updated pipeline name to: {updated_data['displayName']}")
318
+
319
+ # Run the async function
320
+ asyncio.run(update_pipeline_name(pipeline_id))
321
+ ```
322
+
323
+ **Updating a Data Pipeline Definition Asynchronously**
324
+
325
+ ```python
326
+ import json
327
+ from fabrest.utils.functions import encode_base64
328
+
329
+ async def update_pipeline_definition(pipeline_id):
330
+ # Initialize credentials and operator as above
331
+ credential = ClientSecretCredential(
332
+ client_id="your-client-id",
333
+ client_secret="your-client-secret",
334
+ tenant_id="your-tenant-id",
335
+ )
336
+ operator = WorkspaceOperator(id="your-workspace-id", credential=credential)
337
+
338
+ # Update pipeline definition asynchronously
339
+ update_def_payload = {
340
+ "properties": {
341
+ "activities": [
342
+ {
343
+ "name": "AsyncWaitActivity",
344
+ "type": "Wait",
345
+ "dependsOn": [],
346
+ "typeProperties": {"waitTimeInSeconds": 20},
347
+ }
348
+ ]
349
+ }
350
+ }
351
+ current_definition = await operator.data_pipelines.async_get_definition(id=pipeline_id)
352
+ parts = current_definition["definition"]["parts"]
353
+ pipeline_content = json.dumps(update_def_payload)
354
+ pipeline_part = next((p for p in parts if p["path"] == "pipeline-content.json"), None)
355
+ if pipeline_part:
356
+ pipeline_part["payload"] = encode_base64(pipeline_content)
357
+ else:
358
+ parts.append({"path": "pipeline-content.json", "payload": encode_base64(pipeline_content)})
359
+ await operator.data_pipelines.async_update_definition(id=pipeline_id, payload=current_definition)
360
+ print("Updated pipeline definition asynchronously")
361
+
362
+ # Run the async function
363
+ asyncio.run(update_pipeline_definition(pipeline_id))
364
+ ```
365
+
366
+ **Deleting a Data Pipeline Asynchronously**
367
+
368
+ ```python
369
+ async def delete_pipeline(pipeline_id):
370
+ # Initialize credentials and operator as above
371
+ credential = ClientSecretCredential(
372
+ client_id="your-client-id",
373
+ client_secret="your-client-secret",
374
+ tenant_id="your-tenant-id",
375
+ )
376
+ operator = WorkspaceOperator(id="your-workspace-id", credential=credential)
377
+
378
+ # Delete the pipeline asynchronously
379
+ await operator.data_pipelines.async_delete(id=pipeline_id)
380
+ print("Deleted pipeline asynchronously")
381
+
382
+ # Run the async function
383
+ asyncio.run(delete_pipeline(pipeline_id))
384
+ ```
385
+
386
+ For more detailed examples and API documentation, please refer to the [documentation](#documentation).
387
+
388
+ ## Documentation
389
+
390
+ Detailed documentation is under development. For now, refer to the source code and inline comments for understanding the usage of different modules and functions.
391
+
392
+ ## Contributing
393
+
394
+ Contributions to FabRest are welcome! Please feel free to submit a Pull Request or open an Issue on our GitHub repository.
395
+
396
+ ## License
397
+
398
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
399
+
400
+ ## Contact
401
+
402
+ For any queries or support, please open an issue on the GitHub repository or contact the maintainers directly.
403
+
404
+ ---
405
+
406
+ *Note: This project is not officially affiliated with Microsoft or the Fabric team. It is a community-driven effort to facilitate interaction with Fabric REST APIs.*