Pushing Streaming Data to Microsoft Power BI for Data Visualization Using Python

Power BI is a business analytics service by Microsoft that aims to provide data visualizations and business intelligence capabilities through simple report and dashboard tools.

One interesting feature is the ability to create Streaming Datasets that can receive data through a simple REST API. With this feature, data can be streamed in real-time to update dashboards.

With just a few lines of Python and the requests package, getting up and running with the Streaming Datasets feature is quick and easy.

Setting Up a Streaming Dataset

  • Select API

  • Fill in the desired data structure and value types

  • Make sure to activate Historic data analysis if you want data to be cached and retained for longer-lasting analytics
  • Click Create and you’re done!

Get API URL

  • Copy the provided Push URL that will be used in a Python code below

Python Code to Push Data

The following code will push data to the previously created API. Each time this script is run, a new data payload is sent to the Power BI dataset. Integrating this code into an IoT device (e.g., Raspberry Pi sensor) or a cron job can allow for simple data logging and dashboard views.

from datetime import datetime
import requests
import json

# copy "Push URL" from "API Info" in Power BI
url = "https://api.powerbi.com/beta/ABC-XYZ"

# timestamps should be formatted like this
now = datetime.strftime(
  datetime.now(),
  "%Y-%m-%dT%H:%M:%S"
  )

# data dict must be contained in a list
data = [
  {
    "string_value": "ABC XYZ",
    "number_value": 12345,
    "datetime_value": now
    }
  ]

# post/push data to the streaming API
headers = {
  "Content-Type": "application/json"
  }
response = requests.request(
    method="POST",
    url=url,
    headers=headers,
    data=json.dumps(data)
)

If all goes well, the returned response object will be a HTTP Status 200 OK.

Additional Notes

Lists and Data

The data dict payload must be wrapped in a list, else a HTTP status 400 Bad Request will be returned. The following code wouldn’t work.

data = {
    "string_value": "ABC XYZ",
    "number_value": 12345,
    "datetime_value": now
    }

Pushing Different Data

If a value that isn’t part of the previously defined dataset schema is sent (e.g., another_number_value), a HTTP status 404 Not Found will be returned. The following code wouldn’t work.

data = [
  {
    "string_value": "ABC XYZ",
    "number_value": 12345,
    "another_number_value": 789,
    "datetime_value": now
    }
  ]

Omitting Values

Not all values need to be included in a payload (e.g., we can send just number_value if we want), for example:

data = [
  {
    "number_value": 12345,
    }
  ]
data = [
  {
    "string_value": "ABC XYZ",
    "number_value": 12345,
    }
  ]

Multiple Data Payloads

We can send multiple data dict as part of the payload (hence the list wrapper), for example:

data = [
  {
    "string_value": "ABC",
    "number_value": 12345,
    "datetime_value": now
    },
    {
    "string_value": "XYZ",
    "number_value": 789,
    "datetime_value": now
    },
    {
    "string_value": "EFG",
    "number_value": 852,
    "datetime_value": now
    }
  ]
Nicholas Nadeau, Ph.D., P.Eng.
Nicholas Nadeau, Ph.D., P.Eng.
Founder / Fractional CTO

Nicholas Nadeau is a fractional CTO empowering startups with next-gen technology expertise, and a passion for driving corporate innovation. Stay informed on cutting-edge hard tech trends - subscribe to my newsletter. Ready to innovate? Discover my services and accelerate your growth.

Related