Get Power BI Report Viewing History using Semantic Link Labs

Lately I have been building scripts to help clients audit their Fabric environment. The latest request was to get a list of reports and what users have viewed them recently. This is a quick job for a Fabric notebook and the Semantic Link Labs library.

You can download my notebook here. I’ll walk through the steps in this post. Please note that you’ll need Fabric Admin access to run this notebook as your user. You could also modify the notebook to use service principal authentication.

Code Walkthrough

First, we must install semantic-link-labs. If you already have an environment with this library installed, you can use that and skip this step.

%pip install semantic-link-labs

Next, we need to import a couple modules.

# Imports
import sempy_labs as labs
from sempy_labs import admin

import pandas as pd

Then we can start the real work. First, we need to get the desired date range in which to look for report views. I started with dates with no time component and then added the times so it would span the entire day.

#Enter dates below. Must be within 30 days of today.
start_date = '2025-06-07'
end_date = '2025-06-15'

#Times will be in UTC
start_time = 'T00:00:00'
end_time = 'T23:59:59'
start_datetime = start_date + start_time
end_datetime = end_date + end_time

print("Getting report views for " + start_datetime + " to " + end_datetime + "." )

The API can only be called for a single day at a time. So we need to loop through each date in the date range, retrieve the result, and add it to the results from the previous days. I start by creating a blank dataframe to hold my results. Then I create my date range.

combineddates_df = pd.DataFrame()

date_range = pd.date_range(start=start_date, end=end_date)

I make a for loop to execute the list_activity_events function for each date. The dates returned by pd._date_range are of type datetime64[ns]. So I convert the date to a string, then concatenate the start time to it for the start_time parameter value and concatenate the end time to it for the end_time parameter value.

Semantic Link Labs makes it easy to call the required API. It has input parameters for start time, end time, activity type, user, and an option to return results as a data frame instead of the original JSON.

There are more activities in the activity log than just report views, so we use the activity_filter to limit to just that activity type. We can set return_dataframe to True to save ourselves some work. Then we append those results to our original dataframe named combineddates_df using the pandas concat funtion.

for dtl in date_range:
    dt_str = str(dtl)[:10]
    st = dt_str + start_time
    et = dt_str + end_time
    try:
        dt_df = labs.admin.list_activity_events(start_time=st, end_time=et,activity_filter='ViewReport',return_dataframe='True')
        combineddates_df =pd.concat([combineddates_df, dt_df],ignore_index=True, join='outer')
    except:
        print("Error returned from API call for date " + dt_str +". Check that dates are within 30 days of today. If there is no report viewing history on that day, it may throw an error. Dates with no errors are shown below.")   

The API will only return data for the last 26ish days (it was originally 30 days but testing on June 15 showed data available starting May 20). If we call the API for a date when data is not available, we get a error. So we need to handle any errors for each day’s request. That is why we need the try and except blocks. If there is no data for a date, it will print an error and move on to the next date rather than filing the entire cell.

Results

To see the final result, we can display the final dataframe. The output contains about 38 columns, some of which are duplicative or irrelevant, so you can choose which columns from the dataframe to display and order them how you’d like.

display(combineddates_df[['Creation Time', 'Report Name','Dataset Name', 'Workspace Name', 'User Id','Consumption Method', 'Client IP', 'User Agent','Workspace Id', 'Report Id', 'Report Type', 'Dataset Id',  'App Name','Capacity Id', 'Capacity Name','Operation', 'Is Success'  ]])
The output table from a Fabric notebook cell, whcih shows the following columns: 'Creation Time', 'Report Name','Dataset Name', 'Workspace Name', 'User Id','Consumption Method', 'Client IP', 'User Agent','Workspace Id', 'Report Id', 'Report Type', 'Dataset Id'.

Considerations

The one big limitation to this approach is that you can only get about 26 days of history. If you need to go back further than that, you can try exporting from the M365 Unified audit logs which retain 90 days of history by default.

Another consideration is that this could return a lot of data if you run it for the full available date range on a busy tenant. Executing notebooks uses Fabric capacity. Make sure you have enough to support the execution without interrupting another workload.

More Semantic Link Labs

If you’d like to know more about Semantic Link Labs, check out my previous post Finding fields used in a Power BI report in PBIR format with Semantic Link Labs.

The post Get Power BI Report Viewing History using Semantic Link Labs first appeared on Data Savvy.

Share

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Trust DCAC with your data

Your data systems may be treading water today, but are they prepared for the next phase of your business growth?

Denny Cherry & Associates Consulting
Privacy Overview

This website uses cookies so that we can provide you with the best user experience possible. Cookie information is stored in your browser and performs functions such as recognising you when you return to our website and helping our team to understand which sections of the website you find most interesting and useful.