Setting page visibility and the active page are often overlooked last steps when publishing a Power BI report. It’s easy to forget the active page since it’s just set to whatever page was open when you last saved the report. But we don’t have to settle for manually checking these things before we deploy to a new workspace (e.g., from dev to prod). If our report is in PBIR format, we can run Fabric notebooks to do this for us. This is where Semantic Link Labs helps us.

You can download my notebook here. I’ll walk through the steps in this post.

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 some modules.

# Imports
import sempy_labs as labs
from sempy_labs import report
import ipywidgets as widgets
from IPython.display import display

Then we can get to work. First, I’m capturing the following information using widgets: workspace ID, report ID, and page name.

w_workspace = widgets.Text( description = 'Workspace ID',style={'description_width': 'initial'}) 
w_report = widgets.Text(description = 'Report ID', style={'description_width': 'initial'})
w_activepage = widgets.Text(description = 'Active Page Name', style={'description_width': 'initial'})
display(w_workspace)
display(w_report)
display(w_activepage)

Running the code above will create 3 widgets. You will need to enter the required information into the widgets.

Fabric notebook widgets that capture workspace ID, report ID, and active page name

You could use variables in a cell to collect the required information. I’m using widgets to make it clear what information needs to be entered.

Once you have filled in the textboxes, you can run the last 2 cells. The fourth code cell is where I’m actually making the changes to the report.

var_reportname = labs.resolve_report_name(w_report.value, workspace=None)

var_rptw = labs.report.ReportWrapper(report=w_report.value, workspace=w_workspace.value,readonly=False)

var_rptw.set_active_page(w_activepage.value)
var_rptw.hide_tooltip_drillthrough_pages()
var_rptw.save_changes()

var_rptw.list_pages()

First, I use the report ID entered into the widget to get the report name.

Then I create my report wrapper (var_rptw). This object will be used with all the subsequent functions.

Next I set the active page to the page name entered into the w_activepage widget using the set_active_page() function. Then I call hide_tooltip_drillthrough_pages().

Each page has associated metadata that indicates whether it is a tooltip page and whether it is a drillthrough target page. I believe the tooltip page is determined by the page information setting labeled “Allow use as tooltip”.

Power BI page formatting options showing the Page information section containing the page name and the "allow use as tooltip" setting.
The Allow use as tooltip setting is in the Page information section

For drillthrough pages, I believe the presence of a field in the Drill through field well on the page is what causes it to be flagged as a drill through page.

The Visualizations pane in Power BI showing a field populated in the drillthrough field pane.
The drill through fields are in the Visualizations pane when the page is selected.

Calling the set_active_page() and hide_tooltip_drillthrough_pages() functions changes the metadata for the report object, but we have to save the report changes back to the report in the target workspace, for the changes to take effect. This is why we call var_rptw.save_changes().

Once we save the changes, we get a response back that lists the changes made to the report.

🟢 The 'Main' page has been set as the active page in the 'DataSavvyReport2' report within the 'SempyLabsTest' workspace. 🟢 The 'Tooltip' page has been set to 'hidden' in the 'DataSavvyReport2' report within the 'SempyLabsTest' workspace. 🟢 The 'Drillthrough' page has been set to 'hidden' in the 'DataSavvyReport2' report within the 'SempyLabsTest' workspace. 🟢 The report definition has been updated successfully.
The output from calling save_changes() lists which page was set to active, which pages have been hidden, and a confirmation that the report definition was saved.

Calling list_pages() produces a pandas DataFrame with metadata for each page. We can refer to the Hidden, Active, Type, and Drillthough Target Page columns to confirm the desired changes.

As a final confirmation, we can also view the Power BI report from within the notebook. That is what I’m doing with the launch_report() function. It provides a read-only view of the report in the notebook cell output..

Power BI report embedded in a notebook

More posts about Semantic Link Labs

So far, I’ve been exploring the report and admin subpackages of Semantic Link Labs. Below are some other blog posts I’ve written about them.

Finding fields used in a Power BI report in PBIR format with Semantic Link Labs

Get Power BI Report Viewing History using Semantic Link Labs

Want to learn more about Power BI Automation with Semantic Link Labs? Join our webinar this month covering this exact topic.

About ProcureSQL

ProcureSQL is the industry leader in providing data architecture as a service, enabling companies to harness their data and grow their business. ProcureSQL is 100% onshore in the United States and supports the four quadrants of data, including application modernization, database management, data analytics, and data visualization. ProcureSQL works as a guide, mentor, leader, and implementer to provide innovative solutions to drive better business outcomes for all businesses. Click here to learn more about our service offerings.

Do you have questions about leveraging AI, Microsoft Fabric, or the Microsoft Data Platform? You can chat with us for free one-on-one, or contact the team. We would love to share our knowledge and experience with you.

Lets talk about Images in PBIR and how to replace them.  With the PBIR format of Power BI reports, it’s much easier to make report updates outside of Power BI Desktop. One thing you may want to do is to switch out an image in a report. Maybe you need to rebrand a report, updating some of the images (logos and background images). You could import the images or use image URLs with DAX, but that comes with its own problems. If you have some dev ops or automation skills, this becomes pretty easy. Today, we will share an Data Architecture tip to get this done! When you insert an image into a report in Power BI Desktop, the original name of the image file is modified by adding a string of characters onto the end of the name. For a report in PBIR format, all images are placed into the <ReportName>.Report\StaticResources\RegisteredResources folder.
Screenshot of the RegisteredResourcesFolder in a PBIR format report containing 3 images
The RegisteredResources folder containing 3 images

Replacing an image with the same name

If you have the name of the file that is in the RegisteredResources folder, you can simply replace it with a file of the same name. This assumes the dimensions and resolution of the file are the same so it looks ok in the report. You could automate this in Azure DevOps pipelines or Github Actions, or just write a PowerShell script that checks out the branch in source control, replaces the image, and then checks it back in.

Replacing an image with a different name

If you need to replace the image file with a file that has a different name, there are more modifications to be done. The image file name is referenced in 2 files:
  • the report.json file for the report, found in the <ReportName>.Report\definition folder
  • the visual.json file for the visual that contains the image, found in the <ReportName>.Report\definition\pages\<PageName>\visuals\<VisualName> folder
Screenshot of the report.json folder showing the references to the 3 images from the RegisteredResources folder.
report.json file containing references to the image in PBIR files
You could delete the original image, add the new image with new file name, and then update the references in those two files. I’ve tested both ways using an Azure DevOps pipeline for automation. I added a step that runs a PowerShell script. Unless the image name is very important to you, I would just rename the new image to match the current image and avoid having to update the JSON files. The post Replacing Images in PBIR Format Reports first appeared on Data Savvy.

Have you ever wondered where a certain field is used in a report? Or maybe you need an easy way to find broken field references in a report? Certain 3rd-party tools such as Measure Killer and Power BI Helper (not updated recently) have helped us with this task in the past. But now we can perform this task with a notebook in Fabric! Lets take a look in this month’s Data Architecture tip.

This is made possible by the Semantic Link Labs Python library. Please note that PBIR format is still in preview at the time of publishing this blog post, so use it at your own risk. Also, this works only on reports published to the Power BI service. Since this notebook is not making any changes to the report, I feel it’s pretty safe to run, but do remember that it uses CUs on your Fabric capacity while you run it.

Using Semantic Link Labs with Power BI

To use the Semantic Link Labs package in your notebook, you need to install it and import the subpackages you need. You can also create an environment with Semantic Link Labs installed, and then you can skip the install step.

If you need to install and import, you would just write some Python like this:

%pip install semantic-link-labs

import sempy_labs as labs
from sempy_labs import report as rep
from sempy_labs.report import ReportWrapper

The important functions used in my field usage notebook are:

The list_semantic_model_objects function shows a list of all semantic model objects (measures, columns, hierarchies) that are used in a report and where the objects were used (i.e. visual, report filter, page filter, visual filter). It has a parameter that allows you to add an extra column that identifies whether the semantic model object used in the report exists in the semantic model which feeds data to the report.

The list_visuals function shows a list of visuals in a specified report.

I call these two functions and merge the results to give you a nice field usage list.

Using My Notebook

I created a notebook (download from Github here) that combines the Semantic Link Labs functions with some basic Python to allow you to do the following:

  • See a list of all fields and where they are used in a report
  • Search for a specific field to see where it is used in a report
  • Search for fields from a specific table to see where they are used in a report
  • Search for broken field references (i.e., the measure in the semantic model was renamed and the report was not updated)

You’ll find documentation and instructions at the top of my notebook to help you use it. First, read the documentation.

Then skip or run the install step as needed. Run the import step to get all the required libraries for the notebook to work.

The third code cell in my notebook creates some widgets to accept input for which report and fields you would like to search. You must enter at least the report name and workspace name. You may optionally specify a table name alone, or a table name and field name. By default, the notebook will look for all fields, whether they are valid or invalid (broken field reference). Change the selection if you would like to see only valid or only invalid.

The last cell of the notebook returns a table with the following columns:

  • Table Name – the table in which the field is located
  • Object Name – the field name
  • Object Type – indicates whether the field is a measure or column
  • Report Source – The part of the report in which the field is used (visual, report filter, etc.)
  • Report Source Object – The name of the object in which the field is used (usually the report name, page name, or visual name)
  • Valid Semantic Model Object – true/false as to if the field reference is valid
  • Page Name – unique ID of the page within the report where the field is used
  • Page Display Name – the page name you see in Power BI where the field is used
  • Visual Name – if the field is used in a visual, the unique ID of the visual where the field is used
  • Display Type – if the field is used in a visual, the type of visual where the field is used; e.g., Bar chart, Slicer, HTML Content (lite)
  • Visual Loc X – if the field is used in a visual, the x-coordinate of the visual
  • Visual Loc Y – if the field is used in a visual, the y-coordinate of the visual
  • Visual Loc Z – if the field is used in a visual, the z-order of the visual

If I have a report named WOW2024Wk37 and I want to see where all the fields in the __Measures table are used, I can enter that information and run the final cell.

the notebook widgets allow input for report, workspace, table, field, and invalid fields. The selection shows a report, workspace, and table entered. The field widget is blank, and invalid fields is set to all fields.

My results will help me see things like my [Color – CY] measure is used on the Sales Report page in a card, a bar chart, and a custom column chart. If I need to find the visual in the report, I can look at the x and y coordinates to give me an idea of where to look.

The results table in the notebook shows all 25 rows where fields from the __Measures table are used inn the selected report

Exploring Semantic Link Labs

I’m just getting into Semantic Link Labs, and I’m really enjoying the report package. I’m sure you’ll see more from me about this library as it is a great wrapper for easy access to Power BI APIs and a good way to automate the tasks of getting metadata and making updates in Power BI reports. If you are using Semantic Link Labs, I’d love to know what you are doing with it.

The post Finding fields used in a Power BI report in PBIR format with Semantic Link Labs first appeared on Data Savvy.