Question

Looker API

  • 19 November 2015
  • 12 replies
  • 898 views

Userlevel 2

Are there any organizations out there that are using the Looker API as a data feed to end-user analysts?


12 replies

We are looking to do just that in the near future. Currently, we are embedding SSO dashboards, creating users, setting up access filters. We will be working on creating and running queries and downloading data.


I’m implementing a .NET SDK for the Looker API. We have successfully generated the code using Swagger Codegen. You can see my post on Generating .NET Clients

Broadcasting Embedded Dashboard Events to the Parent Page


Looker provides a way to allow an embedded dashboard to broadcast events to the parent page using the embedded dashboard API. This works when the dashboard is embedded using the <iframe /> tag in HTML.


Getting set up


Get the embedded dashboard URL


First, we need to get the embed URL for the dashboard.




  1. Navigate to a dashboard you want to embed.




  2. Copy the URL from the browser navigation bar.




  3. Add /embed to the URL just before /dashboards/.

    For instance, if the original URL was: https://mydomain.com/dashboards/...

    then change the URL to:

    https://mydomain.com/embed/dashboards/...

    Make sure to leave the rest of the domain as it is.




  4. You must add the URL parameter embed_domain with the domain of the parent page, for instance:


    https://mydomain.com/embed/dashboards/52?embed_domain=https://parentpagedomain.com


    or


    https://mydomain.com/embed/dashboards/52?[some other parameters]&embed_domain=https://parentpagedomain.com


    NOTE: This domain must match a whitelist of domains as entered by an admin for your Looker instance. An admin may go to https://[yourinstance]/admin/embed to access this setting.




Load the dashboard in an iframe tag


Use an iframe to load the embedded dashboard into your parent page. Replace [embedded dashboard URL] with the URL you created above:


<iframe id="looker" width="500" height="500" src="[embedded dashboard URL]"></iframe>

For example, to embed this dashboard:

https://lookerinstance.com/dashboards/23

on a page hosted at https://parentdomain.com, the embed code would look like this:


<iframe id="looker" width="500" height="500" src="https://lookerinstance.com/embed/dashboards/23?embed_domain=https://parentdomain.com"></iframe>

Listen to message events on the window


The <iframe> embedded page will use JavaScript’s postMessage method to send event data which can be captured by listening to those events. To receive these events, add an event listener to the parent window like this:


window.addEventListener("message", function (event) {
if (event.source === document.getElementById("looker").contentWindow) { // confirm message came from Looker
console.log(JSON.parse(event.data));
}
});

If you are using jQuery this could look like this:


$(window).on("message", function (event) {
if (event.source === $("#looker")[0].contentWindow) { // confirm message came from Looker
console.log(JSON.parse(event.data));
}
});

NOTE: Other iframes could also be sending data to your page’s window. As shown above, make sure to confirm that the source of the message was the iframe with the embedded Looker dashboard before you parse the data.


Explore the data sent from the dashboard


The callback function will receive the event object. To get to the data you want, you will need to parse event.data which has all of the data of interest to you. As shown earlier, you use JSON.parse(event.data) to get a standard JavaScript object with the data.


That data object will look something like this, for example:


{
type: "dashboard:tile:start",
dashboard: {
id: 23,
title: "My Dashboard",
absoluteUrl: "https://mydomain.com/embed/dashboard/...",
url: "/embed/dashboard/...",
filters: {
"Sale date": "Last 28 days",
"Sale amount": "Greater than 100"
}
},
tile: {
id: 65,
title: "Quarterly Sales",
listen: {
"Sale date": "order.date",
"Sale amount": "order.amount"
}
}
}

The attribute type indicates the type of event. The value of type determines what data objects are returned. The possible types, their meaning, and the accompanying data are shown below:















































Type Description Accompanying data
"dashboard:run:start" Dashboard has begun loading. Tiles will start loading and querying for data. dashboard
"dashboard:run:complete" Dashboard has finished running and all tiles have finished loading and querying. dashboard
"dashboard:tile:start" Tile is loading and/or querying for data.
dashboard, tile
"dashboard:tile:complete" Tile has finished querying for data.
dashboard, tile
"dashboard:download" PDF of dashboard has been downloaded.
dashboard, fileFormat
"dashboard:tile:download" Tile data has been downloaded.
dashboard, tile*, fileFormat
"dashboard:filters:changed" Dashboard filters have been applied or changed. dashboard

\* The `tile` object for the `"dashboard:tile:download"` event only contains the `title` parameter.

The definitions of the possible data accompanying the type attribute are as follows:


Data: dashboard


Format: Object


Description: Data about the dashboard that sent event data to the parent page.


Parameters:





































Attribute Format Description
id Number The ID number of the dashboard
absoluteUrl String The full dashboard URL
url String The relative dashboard URL (just the path)
title String The title, as shown at the top of the dashboard
filters Object The applied filters. This object has the format: {"Filter name 1": "value 1", "Filter name 2": "value 2", ...}

Example:


dashboard: {
id: 23,
title: "My Dashboard",
absoluteUrl: "https://mydomain.com/embed/dashboard/...",
url: "/embed/dashboard/...",
filters: {
"Sale date": "Last 28 days",
"Sale amount": "Greater than 100"
}
}

Data: tile


Format: Object


Description: Data about an tile on the dashboard that triggered the event.


Parameters:



























Attribute Format Description
id Number The ID number of the event
title String The tile title as shown at the top of the tile
listen Object The global filters this tile is listening for. This object has the format: {"Filter name 1": "applied model 1", "Filter name 2": "applied model 2", ...}

Example:


tile: {
id: 65,
title: "Quarterly Sales",
listen: {
"Sale date": "order.date",
"Sale amount": "order.amount"
}
}

Note: As previously mentioned, the tile object for the “dashboard:tile:download” event only contains the title parameter.


Data: fileFormat


Format: String


Description: The file-type extension for the downloaded file, such as "txt" or "csv".

I am unable to make this work. Also, the example shows embed_domain in a querystring that is not encoded which seems odd. I tried both encoded and unencoded and neither worked for me. I wired up an event listener, removed the safety check to debug, and no events are raised against my window.


I’m able to see events come through if I manually fire them from the looker iframe, so I know the event is wired correctly. To do this, simply switch chrome to the looker iframe and do something like this:


window.top.postMessage('HERE IS THE MESSAGE', 'http://localhost:8000' || 'your app domain')

Is this functionality still supported? Thank you for the help.

Is there a way to use embed_domain with SSO login scenario. Adding the embed_domain parameter throws ‘This request includes invalid params: [“embed_domain”]’ error message in url validator

Userlevel 2

hello @rdharmadhikari,


embed_domain parameter isn’t its own bonafide SSO parameter, but rather gets put directly in the embed_url parameter like so:


embed_url: "/embed/looks/6384?embed_domain=http://localhost:8081"

Please give that a try.


Thanks,

Philip M.

Thank you Philip, that seems to have solved the problem. Started getting “Refused to embed in a frame because it set ‘X-Frame-Options’ to ‘sameorigin’” - will work on it.

I have not been able to get this working. I am using localhost/virtual directory. We have the iframe in a .aspx page,

Userlevel 7
Badge +1

Hey Traci!


What part specifically are you unable to get working? Is it a similar error to the above “X-Frame-Options” error, or something different?

Hi,


I am trying to implement this myself through SSO but the generated URI is giving me the message " * This request includes invalid params: [“embed_domain”]".


My URI without the embed_domain parameter is valid.


Here is an example of how it looks:

https://localhost:4200/login/embed/%2Fembed%2Fdashboards%2F7?nonce=%22d7f37e89-b6b5-4275-aee5-5b29511299f0%22&time=1557757858&session_length=600&external_user_id=%22testuser01.testautomation%40craneware.com%22&permissions=%5B%22access_data%22%2C%22see_looks%22%2C%22see_user_dashboards%22%2C%22see_lookml_dashboards%22%2C%22explore%22%5D&models=%5B%22Issues%22%5D&group_ids=%5B1%5D&external_group_id=%22%22&user_attributes=%7B%7D&access_filters=%7B%7D&force_logout_login=true&signature=3lhglaGmWkq6ZXhoCFo%2BaRiU6DQ%3D&embed_domain=http%3A%2F%2Fhttp%3A%2Flocalhost%3A4200


I have tried both encoding and not encoding the embed_domain parameter.


Any help would be appreciated.


Thanks

Userlevel 7
Badge +1

This is a sneaky trick that always gets me, too.


Even though “embed_domain” is kinda sorta technically a “parameter”, in the context of an SSO script, it’s more like a URL modifier. It goes in the actual embed_url parameter of your script like 'https://localhost:4200/embed/dashboards/7?embed_domain=http://localhost:8000'.


You don’t want to add an extra parameter to the script, since that’ll both mess up the signature and confuse Looker with a parameter it’s not familiar with. Give modifying the embed_url a shot, and let us know!

Ty Izzy. That is now working. Followed your advice and added the embed query params after the embed_domain


Did you misnamed embed_path as embed_url?

Reply