Using Service Principal Authentication With FabricRestClient

I wrote a blog on using FabricRestClient from Semantic Link to call Power/Fabric REST API in Fabric notebooks. It makes it super easy. However, as I noted in the blog, it uses the calling user’s identify. It didn’t support SPN. Well, that was then and now you can use SPN to generate auth token.
All I had to do was see how Semantic Link Lab does it. I looked at the source code (Labs is open source) and copy it. So, all credit goes to Michael Kovalsky and Semantic Link Labs contributors, I am just copying what they did.
Create a service principal. Make sure you give it the permissions as required by whichever API you are calling and the API supports SPN (check the API documentation for that)
Create client secret
While optional, I very highly recommend using Azure Key Vault (hopefully one day this will be possible natively in Fabric) to store the SPN credentials. Use
notebookutils
to retrieve the creds from AKV.
Below, I create a class to get the token which is used in FabricRestClient
.
from sempy.fabric import FabricRestClient
from azure.identity import ClientSecretCredential
key_vault = "https://sempykeyvaultsandeep.vault.azure.net/"
tenant_id = notebookutils.credentials.getSecret(key_vault , "tenantid")
client_id = notebookutils.credentials.getSecret(key_vault , "clientid")
client_secret = notebookutils.credentials.getSecret(key_vault , "secret")
class ServicePrincipalTokenProvider:
def __init__(self, tenant_id, client_id, client_secret):
self.credential = ClientSecretCredential(
tenant_id=tenant_id,
client_id=client_id,
client_secret=client_secret
)
# The scope for the API
self.scope = "https://analysis.windows.net/powerbi/api/.default"
def __call__(self):
token = self.credential.get_token(self.scope)
return token.token
# init service principal credentials
token_provider = ServicePrincipalTokenProvider(
tenant_id=tenant_id,
client_id=client_id,
client_secret=client_secret
)
# Create the Fabric client
client = FabricRestClient(token_provider=token_provider)
# call the required API, below is using admin api to get tennat settings
# change the api url as required
response = client.get("/v1/admin/tenantsettings")
response.json()
If you have used the .admin
functions in Labs, you know that it uses the context managers to call the API, i.e. you use with
to localize the call. You don’t have to but that’s the recommended way to ensure isolation, security and performance. With the context manager, you use the SPN token only during that particular call and use your own identify for all other calls. Let’s implement that too:
from sempy.fabric import FabricRestClient
from azure.identity import ClientSecretCredential
import contextlib
class ServicePrincipalAuth: #base class
def __init__(self, tenant_id, client_id, client_secret):
self.tenant_id = tenant_id
self.client_id = client_id
self.client_secret = client_secret
self.client = None
def __enter__(self):
token_provider = self._create_token_provider()
self.client = FabricRestClient(token_provider=token_provider)
return self.client
def __exit__(self, exc_type, exc_val, exc_tb):
self.client = None
def _create_token_provider(self):
# create a creds
credential = ClientSecretCredential(
tenant_id=self.tenant_id,
client_id=self.client_id,
client_secret=self.client_secret
)
def token_provider(): #replace the provder url if required
token = credential.get_token("https://analysis.windows.net/powerbi/api/.default")
return token.token
return token_provider
# use it in context manager
with ServicePrincipalAuth(tenant_id, client_id, client_secret) as client:
# Use the client inside the context - replace with the api url
#always check the api documentation for requirements and details
response = client.get("/v1/admin/workspaces") #get all workspaces as an admin
# Process the response
workspacess = response.json()
What are the use cases here? Well, when you call APIs directly or indirectly using Semantic Link and Semantic Link Labs, you use your own identify. But with SPN you can execute notebooks using your identify but call APIs using the SPN as required.
Thanks again to Semantic Link Labs !
Resources
Refer to this if you want to learn more about SPNs: https://youtu.be/1SO19uik1rw?si=hUemf6qJbRuShaz1
Another guide for setting up SPN: Fivetran for OneLake | Destination Setup Guide
microsoft/semantic-link-labs: Early access to new features for Microsoft Fabric's Semantic Link.
Scan Fabric Workspaces With Scanner API Using Semantic Link Labs
Microsoft Fabric REST API references - Microsoft Fabric REST APIs | Microsoft Learn
Subscribe to my newsletter
Read articles from Sandeep Pawar directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Sandeep Pawar
Sandeep Pawar
Microsoft MVP with expertise in data analytics, data science and generative AI using Microsoft data platform.