Check your eligibility for this 50% exam voucher offer and join us for free live learning sessions to get prepared for Exam DP-700.
Get StartedDon't miss out! 2025 Microsoft Fabric Community Conference, March 31 - April 2, Las Vegas, Nevada. Use code MSCUST for a $150 discount. Prices go up February 11th. Register now.
Hi Microsoft Fabric Team,
I am working on a project where I need to fetch the definition of a notebook from a workspace using the Microsoft Fabric API. While making the API call to the endpoint https://api.fabric.microsoft.com/v1/workspaces/{workspaceID}/notebooks/{notebookId}/getDefinition, I encounter a 202 Accepted response, which indicates that the request is still being processed.
I understand that this status code suggests that I need to poll a provided Location URL to check the status of the operation. However, I am facing some issues with this approach:
After receiving the 202 Accepted response, I extract the Location URL from the response headers to begin polling the status of the notebook definition retrieval.
I implemented a polling mechanism that rechecks the Location URL every few seconds until I receive a final result (200 OK).
Despite following this approach, I receive a 403 Forbidden response with the following error message:
<TridentPublicApiErrorResponse> <errorCode>RequestFailed</errorCode> <message>Unable to process the request</message> <requestId>a06f0684-8978-425b-b8ff-6f114834efd2</requestId> </TridentPublicApiErrorResponse>
I've ensured that the access token used for authorization has the required scopes (e.g., Workspace.ReadWrite.All,Notebook.ReadWrite.All,Item.ReadWrite.All), and I am able to retrieve other resources using the same token. However, the polling mechanism for this particular case seems to fail with a 403 error.
Any insights into why I might be receiving the 403 Forbidden response during the polling process would be highly appreciated.
Thank you!
Hi,
The code includes exponential backoff for polling and handles the 403 Forbidden response. Make sure to replace your_workspace_id, your_notebook_id, and your_access_token with your actual values.
import requests import time def get_notebook_definition(workspace_id, notebook_id, access_token): url = f"https://api.fabric.microsoft.com/v1/workspaces/{workspace_id}/notebooks/{notebook_id}/getDefinition" headers = { "Authorization": f"Bearer {access_token}" } response = requests.get(url, headers=headers) if response.status_code == 202: location_url = response.headers.get("Location") if not location_url: raise Exception("Location-Header nicht im 202-Response gefunden") # Polling mit exponentiellem Rückoff wartezeit = 1 # Beginne mit 1 Sekunde while True: poll_response = requests.get(location_url, headers=headers) if poll_response.status_code == 200: return poll_response.json() elif poll_response.status_code == 403: raise Exception("403 Forbidden: Anfrage konnte nicht verarbeitet werden") else: time.sleep(wartezeit) wartezeit = min(wartezeit * 2, 60) # Begrenze die Wartezeit auf 60 Sekunden else: response.raise_for_status() # Beispielaufruf workspace_id = "deine_workspace_id" notebook_id = "deine_notebook_id" access_token = "dein_access_token" try: notebook_definition = get_notebook_definition(workspace_id, notebook_id, access_token) print(notebook_definition) except Exception as e: print(f"Fehler: {e}")
Hi @Shubhorin1,
For 403 error, it means your request is authenticated but isn’t authorized to perform the requested operation on the
given resource. If this issue only appear when you request with the specific location, it means the location not existed or your not has enough permission to processing them.
403 Forbidden vs 401 Unauthorized HTTP responses - Stack Overflow
For your code, it seems well, but I think you can increase the operations interval. (currently it seems send too quickly which may trigger the rest API request limits)
Regards,
Xiaoxin Sheng
Hi @v-shex-msft
As an admin in my workspace, I have access to both the notebook from which I am making the API call and the target notebook whose content I am attempting to retrieve. Despite this, I am receiving a 403 (Forbidden) error. For the access token, I am currently using the following scopes: "https://api.fabric.microsoft.com/.default, Item.ReadWrite.All, Notebook.ReadWrite.All". With these scopes, I am able to successfully retrieve the list of notebooks within Fabric, but I am unable to access the content of the specified notebook. Is there an additional requirement or configuration needed to successfully call the API and access notebook content?
Hi @Shubhorin1,
As I said, the issue is caused by you not have permission to access. What the location that you requested?
Notice:
I suppose some of folder and path you get currently not existed or release to users. So that you still not able to access and operate even if you have admin permission and configure the correct scope.
Regards,
Xiaoxin Sheng
Hello @v-shex-msft ,
Could you please guide me on where to configure access/permission for this? The notebook I am attempting to access is located within my workspace, and I am calling the API from the same workspace. Initially, I call the API to retrieve the list of all notebooks in my workspace, and then, using the notebook ID obtained from the results, I attempt to fetch the content of a specific notebook.
HI @Shubhorin1,
Can you please share some more detail about these processes? I think 403 error may means the credentials is invalid or expired during these loop operations to REST API.
For this scenario, perhaps you can add refresh token operations and reduce the frequency during sending these requests.
In addition, you can also try to use thread functions in notebook to achieve async operations:
python - Calling pyspark function asynchronously with concurrent.futures - Stack Overflow
Regards,
Xiaoxin Sheng
Hi @v-shex-msft
Initially, I generate an access token using the Client ID, Client Secret, and Tenant ID, while specifying the necessary scopes (Workspace.ReadWrite.All, Item.ReadWrite.All). With the freshly obtained token, I proceed to call the Get Definition API using the Workspace ID and Notebook ID.
Upon invoking the API, I receive a 202 Accepted status code, indicating the request is being processed. To handle this, I implemented a polling mechanism that repeatedly checks the Location URL provided in the response header. This polling system ensures I can track the progress of the request asynchronously.
However, when navigating to the Location URL, I encounter a 403 Forbidden error. To address this, I have also incorporated an async/await system to fetch the link and concurrently retrieve the latest status in real-time.
so below i am attaching 2 approaches i used to tackle this situation can you please give your insights on this
1) without asynch await
import requests
import time
import json
workspaceID = ''
notebookId = ''
api_url = f'https://api.fabric.microsoft.com/v1/workspaces/{workspaceID}/notebooks/{notebookId}/getDefinition'
access_token = ''
headers = {
"Authorization": f"Bearer {access_token}",
"Content-Type": "application/json"
}
response = requests.post(api_url, headers=headers)
if response.status_code == 200:
notebooks = response.json()
print("Response from the API:")
print(json.dumps(notebooks, indent=4))
elif response.status_code == 202:
print("Request accepted. Processing is not yet complete.")
location_url = response.headers.get('Location')
if location_url:
print(f"Check the status at: {location_url}")
while True:
time.sleep(5)
status_response = requests.get(location_url, headers=headers)
if status_response.status_code == 200:
result = status_response.json()
print("Final result:")
print(json.dumps(result, indent=4))
break
elif status_response.status_code == 202:
print("Still processing...")
else:
print(f"Error checking status: {status_response.status_code}, {status_response.text}")
break
else:
print("No location URL provided for status checking.")
else:
print(f"Failed to fetch notebooks: {response.status_code}, {response.text}")
2) With Async await
import aiohttp
import asyncio
import json
import nest_asyncio
nest_asyncio.apply()
workspaceID = ''
notebookId = ''
api_url = f'https://api.fabric.microsoft.com/v1/workspaces/{workspaceID}/notebooks/{notebookId}/getDefinition'
access_token = ''
async def fetch_notebook(session):
headers = {
"Authorization": f"Bearer {access_token}",
"Content-Type": "application/json"
}
async with session.post(api_url, headers=headers) as response:
if response.status == 200:
notebooks = await response.json()
print("Response from the API:")
print(json.dumps(notebooks, indent=4))
elif response.status == 202:
print("Request accepted. Processing is not yet complete.")
location_url = response.headers.get('Location')
if location_url:
await poll_status(session, location_url)
else:
print("No location URL provided for status checking.")
else:
print(f"Failed to fetch notebooks: {response.status}, {await response.text()}")
async def poll_status(session, location_url):
while True:
async with session.get(location_url) as status_response:
if status_response.status == 200:
final_result = await status_response.json()
print("Final result:")
print(json.dumps(final_result, indent=4))
break
elif status_response.status == 202:
print("Still processing...")
await asyncio.sleep(5)
else:
print(f"Error checking status: {status_response.status}, {await status_response.text()}")
break
async def main():
async with aiohttp.ClientSession() as session:
await fetch_notebook(session)
await main()
Please let me know if there are any changes to be made in the code
Thanks!!
March 31 - April 2, 2025, in Las Vegas, Nevada. Use code MSCUST for a $150 discount!
Arun Ulag shares exciting details about the Microsoft Fabric Conference 2025, which will be held in Las Vegas, NV.