fabric-pbi 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- fabric_pbi-1.0.0.dist-info/METADATA +124 -0
- fabric_pbi-1.0.0.dist-info/RECORD +17 -0
- fabric_pbi-1.0.0.dist-info/WHEEL +5 -0
- fabric_pbi-1.0.0.dist-info/top_level.txt +1 -0
- fabricpandas/__init__.py +22 -0
- fabricpandas/auth/__init__.py +8 -0
- fabricpandas/auth/base_client.py +220 -0
- fabricpandas/bulks/__init__.py +8 -0
- fabricpandas/bulks/bulk_client.py +733 -0
- fabricpandas/client.py +80 -0
- fabricpandas/report/__init__.py +8 -0
- fabricpandas/report/report_client.py +509 -0
- fabricpandas/semantic_model/__init__.py +8 -0
- fabricpandas/semantic_model/semantic_model_client.py +643 -0
- fabricpandas/utils/__init__.py +6 -0
- fabricpandas/workspace/__init__.py +8 -0
- fabricpandas/workspace/workspace_client.py +167 -0
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: fabric-pbi
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Microsoft Fabric REST API client
|
|
5
|
+
Author-email: Your Name <you@example.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
9
|
+
Classifier: Operating System :: OS Independent
|
|
10
|
+
Requires-Python: >=3.8
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
Requires-Dist: requests
|
|
13
|
+
Requires-Dist: python-dotenv
|
|
14
|
+
Requires-Dist: msal
|
|
15
|
+
|
|
16
|
+
# Fabric PBI Client
|
|
17
|
+
|
|
18
|
+
Python client for the Microsoft Fabric REST API.
|
|
19
|
+
|
|
20
|
+
## Install
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
pip install fabric-pbi
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Quick start
|
|
27
|
+
|
|
28
|
+
```python
|
|
29
|
+
from fabricpandas import FabricClient
|
|
30
|
+
|
|
31
|
+
client = FabricClient()
|
|
32
|
+
workspaces = client.list_workspaces()
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Example `.env` for quick start:
|
|
36
|
+
|
|
37
|
+
```env
|
|
38
|
+
FABRIC_ACCESS_TOKEN=your_access_token_here
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Authentication
|
|
42
|
+
|
|
43
|
+
Authentication is loaded from a `.env` file (default) or your shell. You can:
|
|
44
|
+
|
|
45
|
+
- Provide a bearer token directly, or
|
|
46
|
+
- Use service principal credentials to request a token via MSAL, or
|
|
47
|
+
- Use interactive login via system browser.
|
|
48
|
+
|
|
49
|
+
### Option 1: Access token
|
|
50
|
+
|
|
51
|
+
Set an access token as an environment variable:
|
|
52
|
+
|
|
53
|
+
- `FABRIC_ACCESS_TOKEN` (preferred if you already have a token), or
|
|
54
|
+
- `tenant_id`, `client_id`, `client_secret` (service principal)
|
|
55
|
+
|
|
56
|
+
Example `.env`:
|
|
57
|
+
|
|
58
|
+
```env
|
|
59
|
+
FABRIC_ACCESS_TOKEN=your_access_token_here
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Option 2: Service principal (MSAL)
|
|
63
|
+
|
|
64
|
+
Set your Azure AD app credentials in `.env`:
|
|
65
|
+
|
|
66
|
+
```env
|
|
67
|
+
tenant_id=your_tenant_id
|
|
68
|
+
client_id=your_client_id
|
|
69
|
+
client_secret=your_client_secret
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
The client will request a token for:
|
|
73
|
+
|
|
74
|
+
- `https://analysis.windows.net/powerbi/api/.default`
|
|
75
|
+
|
|
76
|
+
Install MSAL if you use service principal auth:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
pip install msal
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Option 3: Interactive login (system browser)
|
|
83
|
+
|
|
84
|
+
Configure a public client app in Azure AD and add a redirect URI of `http://localhost`.
|
|
85
|
+
Set your app and tenant IDs in `.env`:
|
|
86
|
+
|
|
87
|
+
```env
|
|
88
|
+
tenant_id=your_tenant_id
|
|
89
|
+
client_id=your_client_id
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Usage:
|
|
93
|
+
|
|
94
|
+
```python
|
|
95
|
+
from fabricpandas import FabricClient
|
|
96
|
+
|
|
97
|
+
client = FabricClient(interactive_login=True)
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Or request a token directly:
|
|
101
|
+
|
|
102
|
+
```python
|
|
103
|
+
from fabricpandas.auth import get_fabric_token_interactive
|
|
104
|
+
|
|
105
|
+
token = get_fabric_token_interactive()
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Custom `.env` path
|
|
109
|
+
|
|
110
|
+
Pass a custom env file path when constructing the client:
|
|
111
|
+
|
|
112
|
+
```python
|
|
113
|
+
from fabricpandas import FabricClient
|
|
114
|
+
|
|
115
|
+
client = FabricClient(env_file="path/to/.env")
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Troubleshooting auth
|
|
119
|
+
|
|
120
|
+
- `Missing required environment variables`: set `FABRIC_ACCESS_TOKEN` or all of `tenant_id`, `client_id`, `client_secret`.
|
|
121
|
+
- `Missing required environment variables for interactive login`: set `tenant_id` and `client_id` and ensure your app is a public client with `http://localhost` redirect URI.
|
|
122
|
+
- `msal library is required`: install MSAL with `pip install msal`.
|
|
123
|
+
- `Failed to acquire token`: verify Azure AD app credentials and that the app has access to Fabric APIs.
|
|
124
|
+
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
fabricpandas/__init__.py,sha256=izM-WZUo6M4PhZXbazgH15VtBWH5dI9_z1ajiV7kTYs,692
|
|
2
|
+
fabricpandas/client.py,sha256=EofRt94ZQdwuuJ-GdAGtVvD2m55ChpGedmyVUCgaWTk,3063
|
|
3
|
+
fabricpandas/auth/__init__.py,sha256=z3OS4MxHLNI9pXE9wMOB0kTRTtn5v8q0UrInKRp2I4U,249
|
|
4
|
+
fabricpandas/auth/base_client.py,sha256=QYwvSsrqiQmqWTksoxDIrSv8pXLMipgOkOcvlDUOuu4,7271
|
|
5
|
+
fabricpandas/bulks/__init__.py,sha256=5NLN5zmSLXDm9yHrF-LaCHIe8twX0w0rPV6xnk8mQ0U,120
|
|
6
|
+
fabricpandas/bulks/bulk_client.py,sha256=xPRLVoY2c7uz_q9OxDvJyA3upEFVGbnIKHWsM5KOsP8,30903
|
|
7
|
+
fabricpandas/report/__init__.py,sha256=FOOM6hi8_a4uXWxZEMeA4XCpQrAHQ8phxXeYpNSISrE,117
|
|
8
|
+
fabricpandas/report/report_client.py,sha256=Dn-Cdhh8dAGJ_2d-CNqUpz5SdMVwrrV4fFfUM3a8z2Q,19761
|
|
9
|
+
fabricpandas/semantic_model/__init__.py,sha256=A9YGRIhrIbn8sRDcCP7VFqzonS6ZygY6yv9oJfKY6gc,147
|
|
10
|
+
fabricpandas/semantic_model/semantic_model_client.py,sha256=aqloSB8wSQvOi3XrcfZCu7l7MUIEN4EV2vjpAi4ATrg,25899
|
|
11
|
+
fabricpandas/utils/__init__.py,sha256=JdjwEJDjbQ_n6B0N2gF3JCNW6g05yGG4OpIYvor6hFE,64
|
|
12
|
+
fabricpandas/workspace/__init__.py,sha256=_-jTljVxZhw93k7mr2X5DaIzqTHxTZ0H2D-vp7-cdes,129
|
|
13
|
+
fabricpandas/workspace/workspace_client.py,sha256=4G3zKjmyazBO9-b5IeXidQicXdjI76IpQSYhOmN2YeI,5021
|
|
14
|
+
fabric_pbi-1.0.0.dist-info/METADATA,sha256=aZxltsOJQa9ozhVWFP9t4H4E7FGHXs9eTdR24EKPVm4,2954
|
|
15
|
+
fabric_pbi-1.0.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
16
|
+
fabric_pbi-1.0.0.dist-info/top_level.txt,sha256=-4vRijt7KCdbmlOm7SCjHjp16lzLiHjhQBvB4ftnvvs,13
|
|
17
|
+
fabric_pbi-1.0.0.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
fabricpandas
|
fabricpandas/__init__.py
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"""
|
|
2
|
+
FabricPandas - Microsoft Fabric REST API Client
|
|
3
|
+
A Python client for interacting with Microsoft Fabric APIs
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from .client import FabricClient
|
|
7
|
+
from .workspace import WorkspaceClient
|
|
8
|
+
from .semantic_model import SemanticModelClient
|
|
9
|
+
from .report import ReportClient
|
|
10
|
+
from .bulks import BulkClient
|
|
11
|
+
from .auth import BaseClient
|
|
12
|
+
|
|
13
|
+
__version__ = "1.0.0"
|
|
14
|
+
__all__ = [
|
|
15
|
+
"FabricClient", # Main convenience class
|
|
16
|
+
"BaseClient", # Base authentication class
|
|
17
|
+
"WorkspaceClient", # Workspace operations
|
|
18
|
+
"SemanticModelClient", # Semantic Model operations
|
|
19
|
+
"ReportClient", # Report operations
|
|
20
|
+
"BulkClient", # Bulk operations
|
|
21
|
+
]
|
|
22
|
+
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Base Fabric API Client
|
|
3
|
+
Provides core functionality for Microsoft Fabric REST API interactions.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import requests
|
|
7
|
+
from typing import Optional, Dict, Any
|
|
8
|
+
from dataclasses import dataclass
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def get_fabric_token(env_file: str = ".env") -> str:
|
|
12
|
+
"""
|
|
13
|
+
Get Fabric access token from .env file
|
|
14
|
+
|
|
15
|
+
Args:
|
|
16
|
+
env_file: Path to .env file
|
|
17
|
+
|
|
18
|
+
Returns:
|
|
19
|
+
Access token string
|
|
20
|
+
"""
|
|
21
|
+
import os
|
|
22
|
+
from dotenv import load_dotenv
|
|
23
|
+
|
|
24
|
+
# Load environment variables
|
|
25
|
+
load_dotenv(env_file)
|
|
26
|
+
|
|
27
|
+
# Check if we already have an access token in env
|
|
28
|
+
access_token = os.getenv("FABRIC_ACCESS_TOKEN")
|
|
29
|
+
if access_token:
|
|
30
|
+
return access_token
|
|
31
|
+
|
|
32
|
+
# Otherwise, get token using service principal
|
|
33
|
+
tenant_id = os.getenv("tenant_id")
|
|
34
|
+
client_id = os.getenv("client_id")
|
|
35
|
+
client_secret = os.getenv("client_secret")
|
|
36
|
+
|
|
37
|
+
if not all([tenant_id, client_id, client_secret]):
|
|
38
|
+
raise ValueError(
|
|
39
|
+
"Missing required environment variables. Please set either:\n"
|
|
40
|
+
" - FABRIC_ACCESS_TOKEN\n"
|
|
41
|
+
"Or:\n"
|
|
42
|
+
" - tenant_id, client_id, client_secret"
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
# Get token using MSAL
|
|
46
|
+
try:
|
|
47
|
+
import msal
|
|
48
|
+
|
|
49
|
+
authority = f"https://login.microsoftonline.com/{tenant_id}"
|
|
50
|
+
app = msal.ConfidentialClientApplication(
|
|
51
|
+
client_id=client_id,
|
|
52
|
+
authority=authority,
|
|
53
|
+
client_credential=client_secret
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
# Fabric API scope
|
|
57
|
+
scopes = ["https://analysis.windows.net/powerbi/api/.default"]
|
|
58
|
+
|
|
59
|
+
result = app.acquire_token_for_client(scopes=scopes)
|
|
60
|
+
|
|
61
|
+
if "access_token" in result:
|
|
62
|
+
return result["access_token"]
|
|
63
|
+
else:
|
|
64
|
+
error = result.get("error_description", result.get("error", "Unknown error"))
|
|
65
|
+
raise Exception(f"Failed to acquire token: {error}")
|
|
66
|
+
|
|
67
|
+
except ImportError:
|
|
68
|
+
raise ImportError(
|
|
69
|
+
"msal library is required for service principal authentication. "
|
|
70
|
+
"Install it with: pip install msal"
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def get_fabric_token_interactive(
|
|
75
|
+
env_file: str = ".env",
|
|
76
|
+
tenant_id: Optional[str] = None,
|
|
77
|
+
client_id: Optional[str] = None,
|
|
78
|
+
redirect_uri: str = "http://localhost",
|
|
79
|
+
scopes: Optional[list] = None
|
|
80
|
+
) -> str:
|
|
81
|
+
"""
|
|
82
|
+
Get Fabric access token using interactive login in a system browser.
|
|
83
|
+
|
|
84
|
+
Args:
|
|
85
|
+
env_file: Path to .env file
|
|
86
|
+
tenant_id: Azure AD tenant ID (optional; falls back to env)
|
|
87
|
+
client_id: Azure AD app client ID (optional; falls back to env)
|
|
88
|
+
redirect_uri: Redirect URI for the public client app
|
|
89
|
+
scopes: Optional list of scopes to request
|
|
90
|
+
|
|
91
|
+
Returns:
|
|
92
|
+
Access token string
|
|
93
|
+
"""
|
|
94
|
+
import os
|
|
95
|
+
from dotenv import load_dotenv
|
|
96
|
+
|
|
97
|
+
load_dotenv(env_file)
|
|
98
|
+
|
|
99
|
+
resolved_tenant_id = tenant_id or os.getenv("tenant_id")
|
|
100
|
+
resolved_client_id = client_id or os.getenv("client_id")
|
|
101
|
+
|
|
102
|
+
if not all([resolved_tenant_id, resolved_client_id]):
|
|
103
|
+
raise ValueError(
|
|
104
|
+
"Missing required environment variables for interactive login. "
|
|
105
|
+
"Please set tenant_id and client_id."
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
try:
|
|
109
|
+
import msal
|
|
110
|
+
|
|
111
|
+
authority = f"https://login.microsoftonline.com/{resolved_tenant_id}"
|
|
112
|
+
app = msal.PublicClientApplication(
|
|
113
|
+
client_id=resolved_client_id,
|
|
114
|
+
authority=authority
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
requested_scopes = scopes or ["https://analysis.windows.net/powerbi/api/.default"]
|
|
118
|
+
|
|
119
|
+
result = app.acquire_token_interactive(
|
|
120
|
+
scopes=requested_scopes,
|
|
121
|
+
redirect_uri=redirect_uri
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
if "access_token" in result:
|
|
125
|
+
return result["access_token"]
|
|
126
|
+
|
|
127
|
+
error = result.get("error_description", result.get("error", "Unknown error"))
|
|
128
|
+
raise Exception(f"Failed to acquire token interactively: {error}")
|
|
129
|
+
|
|
130
|
+
except ImportError:
|
|
131
|
+
raise ImportError(
|
|
132
|
+
"msal library is required for interactive authentication. "
|
|
133
|
+
"Install it with: pip install msal"
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
@dataclass
|
|
138
|
+
class FabricConfig:
|
|
139
|
+
"""Configuration for Fabric API client"""
|
|
140
|
+
base_url: str = "https://api.fabric.microsoft.com/v1"
|
|
141
|
+
access_token: Optional[str] = None
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
class BaseClient:
|
|
145
|
+
"""Base client for Microsoft Fabric API interactions"""
|
|
146
|
+
|
|
147
|
+
def __init__(
|
|
148
|
+
self,
|
|
149
|
+
access_token: Optional[str] = None,
|
|
150
|
+
base_url: str = "https://api.fabric.microsoft.com/v1",
|
|
151
|
+
env_file: str = ".env",
|
|
152
|
+
interactive_login: bool = False,
|
|
153
|
+
tenant_id: Optional[str] = None,
|
|
154
|
+
client_id: Optional[str] = None,
|
|
155
|
+
redirect_uri: str = "http://localhost"
|
|
156
|
+
):
|
|
157
|
+
"""
|
|
158
|
+
Initialize Fabric client
|
|
159
|
+
|
|
160
|
+
Args:
|
|
161
|
+
access_token: Bearer token for authentication (optional, will be acquired from .env if not provided)
|
|
162
|
+
base_url: Base URL for Fabric API (default: https://api.fabric.microsoft.com/v1)
|
|
163
|
+
env_file: Path to .env file for authentication (default: ".env")
|
|
164
|
+
interactive_login: Use interactive login flow if no access token provided
|
|
165
|
+
tenant_id: Azure AD tenant ID for interactive login (optional)
|
|
166
|
+
client_id: Azure AD app client ID for interactive login (optional)
|
|
167
|
+
redirect_uri: Redirect URI for interactive login (default: http://localhost)
|
|
168
|
+
"""
|
|
169
|
+
# If no access token provided, get one from .env credentials
|
|
170
|
+
if access_token is None:
|
|
171
|
+
if interactive_login:
|
|
172
|
+
access_token = get_fabric_token_interactive(
|
|
173
|
+
env_file=env_file,
|
|
174
|
+
tenant_id=tenant_id,
|
|
175
|
+
client_id=client_id,
|
|
176
|
+
redirect_uri=redirect_uri
|
|
177
|
+
)
|
|
178
|
+
else:
|
|
179
|
+
access_token = get_fabric_token(env_file)
|
|
180
|
+
|
|
181
|
+
self.config = FabricConfig(base_url=base_url, access_token=access_token)
|
|
182
|
+
self.session = requests.Session()
|
|
183
|
+
self.session.headers.update({
|
|
184
|
+
"Authorization": f"Bearer {access_token}",
|
|
185
|
+
"Content-Type": "application/json"
|
|
186
|
+
})
|
|
187
|
+
|
|
188
|
+
def _make_request(
|
|
189
|
+
self,
|
|
190
|
+
method: str,
|
|
191
|
+
endpoint: str,
|
|
192
|
+
data: Optional[Dict[str, Any]] = None,
|
|
193
|
+
params: Optional[Dict[str, Any]] = None
|
|
194
|
+
) -> requests.Response:
|
|
195
|
+
"""
|
|
196
|
+
Make HTTP request to Fabric API
|
|
197
|
+
|
|
198
|
+
Args:
|
|
199
|
+
method: HTTP method (GET, POST, PUT, DELETE, PATCH)
|
|
200
|
+
endpoint: API endpoint path
|
|
201
|
+
data: Request body data
|
|
202
|
+
params: Query parameters
|
|
203
|
+
|
|
204
|
+
Returns:
|
|
205
|
+
Response object
|
|
206
|
+
"""
|
|
207
|
+
url = f"{self.config.base_url}/{endpoint.lstrip('/')}"
|
|
208
|
+
|
|
209
|
+
response = self.session.request(
|
|
210
|
+
method=method,
|
|
211
|
+
url=url,
|
|
212
|
+
json=data,
|
|
213
|
+
params=params
|
|
214
|
+
)
|
|
215
|
+
|
|
216
|
+
# Raise exception for error status codes
|
|
217
|
+
response.raise_for_status()
|
|
218
|
+
|
|
219
|
+
return response
|
|
220
|
+
|