Good morning, good afternoon and good evening and welcome to Power BI Dev Camp. Today's welcome to Power BI Dev Camp. Today's session is about building solutions using Power Automate and the Power BI REST APIs. I'm gonna hand it over to Ted Pattison, Principal Program Manager of the Power BI customer advisory team, to tell us a little bit more. How's it going Ted yeah, it's going great. Thank you for the introduction, Daniel. I hope everyone is doing well today. Hello to you, if you're watching this recording afterwards anyway, today our mission is to talk about working with the Power Platform Power Automate te and canvas apps. And how do we talk to the power BI REST APIs? And we're going to look at a couple different solutions some kind of our focus that user level permissions later on we'll get into kind of the admin level permissions. So without further ado let's go ahead and I want to kind of point out that we have. A portal for Power BI Dev camp. Let me go ahead and move over and also note that we have different camp sessions. We're up to 17 right now. Thanks Kelly for all your help along the way to get us up to 17. It's about a year and a half's worth. And also note that when you go to these sessions they also have links. So here's the PowerPoint slides here is s sample code for the session and if I kind of go to the sample code for the session you'll see that we have a. Link to a GitHub repo now in n this GitHub repo, there's a couple different things but mainly what you're going to see is that we have a power platform solution. And what this means is get back to the slides here is that I put together some sample code and what I did is I kind of put everything in a power platform solution It's something which you can think of it as you build things on top of the Power Platform with canvas, apps and flows, model driven apps in the Dataverse they have a packaging format you know which is the solution you know.
So there is a zip file that you should be able to take. And you will have to have some knowledge of Power Platform and. Importing solutions and things, but the idea is that I wanted to have something that was something that you could take and use and so within this solution we're going to look at three different canvas apps as we go through today, we're going to look at several different cloud flows, some which called the power BI Rest API as a user, some which called the power BI Rest API as a service principal You we're going to get into learning how to do both and then also. It has two different custom connectors so custom connectors is a big part of what we're going to talk about. OK, so that kind of takes us to the end of the intro now for this session. We're gonna look at our first section. You know how to create a custom connector, so from a canvas app or from a flow you can call to the power BI Rest API There's going to be some nuts and bolts of how to wire up API calls from a no code platform, and then the next three seconds we're going to get into, you know, taking the custom connector and using it, so we'll see how to call the power BI Rest API from a canvas app, we'll see how to call it from a flow. You know, both as a user and as a service principle. And then at the very end, we're going to look at using flows to execute some of the admin API tasks. Maybe you want to call it get groups as admin or post workspace info to do a workspace scan or a workspace scan or you want to extract event data from the power you know so those are the things we're going to look at in the final section. OK, sounds good now the first section n we're going to drill into custom connectors, and the first thing to point out is that Power BI has something called custom connectors, which is completely different. So the custom connectors that we create for power BI contain M code and they pull data back and use it to import data into data sets. What we're talking about here has nothing to do with this, so this is something over in the power platform and the idea a is a custom connector allows you to call custom web APIs from canvas apps and from flows. So each custom connector really kind of defines the set of actions which map to Web API operations So because the power BI Rest API is a custom API from this perspective, you know we're going to create a custom connector to call to those Now some of the nice things about custom connectors it is it abstracts away the details of acquiring access tokens and including the access token when we make API calls. What's nice is custom connectors. Just do all that behind the scenes. It also you know provides a way that when you provide a username and password and you need to have the system remember that. We have to manage credentials and hide secrets in a good way and not something that's sloppy and so custom credentials has this built in support to manage credentials and hide the things that are important things s like passwords and keys OK now when we create a custom connector you know what we're able to do is inside the power platform, and maybe we'll just kind of follow along here. Let's say that now we go back and here we're going to go to. Data. And here's just a demo environment, so I'm gonna go to custom connectors now. There are two connectors I've already created. But let's just kind of create one from scratch. So what I'm gonna do is I'm gonna create one and I'm going to call this a power BI. And the one I have in the demos called Power BI so o I need to make this name a little different. So I'll just call this one power be I demo. OK, let's go ahead and choose continue and so now we get into this particular editor where I'm able to add things and so one of the things that we're going to do here is we have the Power Automate here the e files that I have you. I'm just going to grab an image here to upload that particular image and then down here. What we're going to do is we're going to say API powerbi.com and d notice that we're going to leave at HTTPS, and then what is the base URL And it's be one point slash my org slash. So basically all the API calls that we're going to call go through this path right here. Now we're going to go ahead and click next, and now we get to the security tab. There's lots of different ways that you can authenticate with a custom connector. Note that custom connector is you we're going g to use Oauth 2. And we're going to use Oauth 2, and once we choose that, we can pick a particular provider and we're going to choose Azure Active Directory. Note that when you do this. It provides user authentication support so you can authenticate as a user and it you know there's ways that we can remember. You know what the credentials were. But it does not give us support to authenticate as a service principal now w, once you've added this inside here, you're going to have to have Azure AD application. So the idea here is, let's say that we go over into Azure AD. And so once I get into Azure AD, we're going to need to have permissions to create things inside there in particular and Azure AD application. So let's go ahead and click new registration and so we'll call this power BI API demo and we're going to leave it with the first section inside here. Now what platform it turns out What we want is web. So what that means is that it's going to have things like the app ID and the app secret.
And it's going to go through the authorization grant flow. Now we need to put in a redirect your eye but we don't know what it is yet. We're going to come back and see that in a second, but let's go ahead and click register. And so at this point I've created this new. Azure AD application so one e thing I'm gonna do is I'm gonna grab the application ID. OK, and now let's go back to the custom connector that we're creating, and So what is the client ID application ID great? The next thing we need is an application secret. So just to kind of quickly demo how to create one of those, let's go back to the application Let's go over to where it says certificates and secrets and we're going to create a new client secret, basically it acts as a password, so I'll just call that SEK one, and I can put it for some duration. I'll pick the maximum of 12 months, and once you do that, you have a new application secret and you have this one time chance. Before you refresh the browser to go ahead and copy the value. So we copy the value. Let's go back here and let's put the application secret inside OK couple other things. We need the tenant ID. You can leave this as common, but what I would recommend is we go back to overview. And here's the application that we have and this is just the gued that identifies your tenant, so we're going to add this in here as so now let's keep going down here. And you have this thing which is the resource URL. As far as the resource URL goes. What I need to do is I need to get to my cheater file right here and inside of my cheater file sees me. Let me try that one more time. That was the wrong cheer file OK, so back to cheater one and here's why. I have some things that I need in particular there is this resource. And so you can kind of think of this. As the ID for power BI secured objects So when we get access tokens and we get things like data set, read or report read right, they all are identified as power BI jumped by this little string right here. Now the next two things scope we're going to keep this empty. And the idea was scope is that? Let's go back to our application. Let's go back to APIs and permissions. So what we're going to do is we're going to define a couple permissions on this application So we're going to say out of permission. Now that we've sent out a permission, we're going to go find the power BI service. I want a couple permissions for this, and we want delegated permissions, don't ever go into application permissions for power BI API permissions. There's nothing but trouble there, but here we're going to go to delegated permissions and so which ones do I want? So let's say I want to be able to get the workspaces for the current users, so there is work space and we can pick a workspace read d all OK, maybe I want to get. At datasets and I could add those inside there as well. But the idea is that you need to add these inside here for this demo I'm just going to add 1 now. Note that you can click on grant admin consent. I'm not gonna do that 'cause I want it to, kind of show up in a later part of the demo, but the idea here is that if we list leave scope blank, this is the set of permissions it's going to automatically use the default permissions, which are the ones that I just registered. Now. At this point I'm going to go ahead and click. Create connector. And the idea of creating the connector is that the connector to be created. Before the power platform will tell you what the redirect URL is. So when this is all done here, which should be just in a couple more seconds, you know what we should be able to do is go down to the bottom. Hey, look there is the redirect URL Let's go ahead and copy that. We'll go back here. And this is the application we've created, so I'm going to go to authentication. And notice that here we're going to say add a platform in which one web and d then what is your redirect? UR I I'm going to go ahead and add that. So the whole idea here is then we now have a redirect your eye and this should work. So at this point, let's go back to this right here and what we should have is everything working inside here as far as configuring the authentication. So now we're going to go to definitions. OK, let's go in this back to the slides and I'm just going to go a couple more slides. But what you saw is it's possible to create a custom connector from scratch. It's also possible to create a custom connector. From some other formats such h as files that have opened API formatting or postman collections, a lot of it just kind of Looks like swagger files that many of us have been using over the last couple years now I went t through the authentication settings for your custom connector and what we did is we added things so that the current user can authenticate and get an access token that will allow me to call the power BI Rest API. And I went through. I created the application Your application might need far more than just works pastry permissions. But what I wanted to do in my demo was just do something very simple. But there are lots of different permissions and each API call in the power BI Rest API has specific user permissions or delegated permissions that are required so you'll have to kind of research that and make sure you ask for the right ones. And as I went through, you kind of saw, there's some other things that you need to add, such as the resource, the scope, and the redirect URL. And finally at the end of the demo kind of showed you have to save the custom connector, yet the redirect URL and then go back and update your Azure pplication. OK, so now we're on to the good part and that's creating actions, so we can actually call the API. So the idea is we're going to go and click on new action and we're going to create them So let's go back here. And So what I want to do is let's go ahead and get a new action, and so let's say that I want to get workspaces, so we'll create a new action and there is a friendly name and there is a description which you can't leave blank, and then an operation ID and d note that this cannot have any spaces, it turns out that this.
Is the name of the method or function that you'll see when you call this from a canvas app. Once we do this, we have to kind of create the request and so the next thing that I want to do is let's go to the documentation for the power BI Rest API. I could see going through and doing what we're about to do without this documentation so we're going to look at exactly one of these calls called get groups, and it runs as a user, and So what I'm going to do is, I'm going to take this URL here, or better yet this one has querystring parameters. We're going to go ahead and copy that. Now, once we do that, we're going to come back here and we have to tell it what the request looks like, so I'm going to say import from sample this is s going to be a get request, this is the URL and notice we have a bunch of querystring parameters inside there I'm going g to go ahead and call import, and now that we've done that, what you see is there's the URL, and here are the querystring parameters. Note that sometimes when you look into the querystring parameters, you might need to kind of change whether they're required, whether they have a default value, whether the user sees them, no need to do that here and then The last thing that we have to do is define what the response looks like. And so the idea is when the API call returns a bunch of Jason. You know what is it gonna look like and once again n I'm going to go back to the documentation I'm going to go down and see there is a sample response so let's just kind of take that sample response here and I'm going to copy that. We're going to go back here and note that if I say import from. Sample. And I just kind of put the body of the Jason I'm expecting to get back. It's able to take that and parameterise it OK now I've done one example here. Let's go ahead and update the connector. And what I wanna do is I wanna go ahead and test this out. So one thing I thought was kind of hard was getting through these first couple steps so I'm gonna spend I guess I'm pretty good amount of time in the demo doing this, but the idea is that now we've created our first action. And what do we want to do? We want to go test it out So before I test it in a canvas app or flow I can test it right from the custom connector editor by going to the test tab. Now note that we don't have a connection yet. So you have a custom connector definition but you need a connection based on that, so here we're going to say give me a new connection. We're gonna go ahead and authenticate. As this particular user and the first time you do that, here is the dialogue that you're going to see. Once again, I told you if you create the application and you do an admin consent, you can make it so users don't see this, but if you don't, each user will see this the very first time they run it. OK, so now that we've done that we've created this and note that. We can now go down here and test the operation, and if we've done everything right, the operation still paying provisions. Sometimes when you create these, you might have to wait a minute 2 minutes s, sometimes 5 minutes. If it's a busy day, OK but let's go ahead and I think it's just a matter of time because I can see operation is being provisioned. Please try again later but let's go back to the slides and you know, as we get back to the slides, one of the things that I wanted you to. You see there is that we create a new action. You have to know what is the shape of the URL. Are there input query parameters Are their path parameters? What is the response And so looking at this documentation can help and you kind of saw my first example that I was able to go through and create this new action. Define what the request looks like. Note that the example I did did not include path parameters. But Let's say I wanted to call get datasets and workspace. Well then the URL both the Workspace ID and the data set ID and as you create those you're able e to add. Parameters in the path and the idea is put curly braces around them and then what you'll do is you'll have path parameters and what's kind of neat about this is that when I now call this from a canvas app, I'll just have it get data set in workspace method that takes these two different parameters. Note that when you have querystring parameters, you can mark them as optional or required. But passed parameters are always required and you can kind of see that by that little that little red asterisk right here. OK, also note that you have the response and I kind of showed how you are able to find a snippet of the JSON that's returned and it's able to kind of build strong bindings So in the Jason comes back it's able to turn it into an object that's easy to work with in a canvas app or a flow. OK, let's go back here and now. Let's go ahead and try one more time and let me go ahead and refresh this one more time. And as I refresh this, what I'm hoping is we can come back here and execute that OK and still resources not found so o let's not worry about this. But those are the steps to go through and create one of these. Now what we're going to do now is we're going to move out of the section of building the plumbing the custom connector. And now let's look at some examples of canvas apps and flows that start using this. So the first one we're going to look at is the Workspace manager. And the workspace manager is going to use. One of the API's or one of the custom connectors. So back here let's kind of start. By going to. My solution? And when I get to my solution here. What I wanna do is I wanna open it up. Let's go ahead and open this thing up. And what you'll see is that you can search for justice the custom connectors. So there's two custom connectors and the e difference is that with the power BI connector that just requires user level permissions Once we get to the power BI Admin API's and the caller has to be a power BI administrator or global tenant admin, I broke those out into a separate custom connector. So let's look at this first one here. So if I take this custom connector and I go ahead and I call edit and I bring it up in the editor. You know what I want to see here is that if I go look at various definitions, you re is yet workspace we have e things for, create workspace and what does the body look like. But there's just a whole bunch of different actions inside here, but I wanted to show you this first because the next thing that we're going to do is let's go back to the solution and let's go look at a canvas app that leverages all those actions. I put into my custom connector. So. What I'm gonna do here is we're gonna open up one of the sample apps. And this one runs with user permissions. So when it calls get workspaces. It's gonna basically return all the workspaces that this current user has access to. So let's go ahead and open this up in edit mode. So what I want to see here. Is. How were able to work with this? And as I work with a power app I also want to go back and just kind of look at this power BI environment that I'm working with. So in this power BI environment. When this refreshes right here, you'll notice that I have a certain number of workspaces, great. Back in our solution right here. I have a workspace screen and a couple other screens, but let's kind of start with this basic idea of they're the different workspaces Let's create 2 new workspaces, so I'll create. Demo one and this one. I'll just say leave it in the shared capacity. That's fine. OK, there's and then we'll create a second one In this one is going to be demo 2, but this one I wanna put into. A assigned capacity. You can kind of see over here where is this guy live in the shared capacity? Now let's look at a couple of things behind this. First of all, when the application starts, we have a initialization method, so the application can have an on start and the idea is that we're going to call get workspaces. And it's going to bring back all the workspaces this user to. And then we're going to get all the capacities to. So I have one. Power BI Premium per user capacity but if things aren't in that capacity, they're going to be in the share capacity. So here I'm just kind of hard coding a row in, you know, but the idea is, you know, as my application loads let's go back here and kind of take a look at collections. You know some of f the things that we could do is we could basically load in the workspaces. And as we kind of load in the workspace is right here. Uhm? Where able to kind of see them here you top. OK, I didn't show the workspaces aces, I think. I must have those over here. OK, let me try one more time to see if I can find those where it's the very top one but you can kind of see the data we're getting back here for capacities you kind of see that I was able to get information about all the dedicated capacities. But I just kind of hard coded a row here you deal with the share the share capacity. So now let's take one our workspaces here. And you what I might want to do is I might want to go to the workspace itself So if I click OK, yeah, sure easy for me to create a power app that redirects me to the workspace. But now let's go ahead and click and so now I go to another screen and we call a whole bunch of API's to see who are the users water their workspaces. Now, let's say that I want to add a user. Or I want to go to this workspace I just created d an ad and Azure AD group as a viewer or I want to add a service principal as an admin of the workspace Why would I want to do that? Maybe I'd want to do that because now I have a button. If I click on it, it's going to run a flow that runs as a service principal, will look at this coming up, but it's then going to upload a PBX file and go through a process of updating parameters in the data set. And setting credentials and starting a refresh operation OK. Once again, we're going to look at this, but just kind of wanted to show that after this runs right here, we're able to kind of see users and imports. If I go ahead and close this down you can see here that when I click on this button, what are we doing? We're basically just calling into my custom connector action to add a user, and if it's a user I add an email address. I can also here let me get this a little bit up and out of the way if I wanna add a group, I specify the identifier and the principle type is group. If I wanna add a service principal well then I say principle type equals app and I add the grid you know of the service principle object ID. OK, once again you can see there's easy ways to kind of get around inside here. Now let's look at a little bit more. Yeah, let's go back here. And let's look at one of these workspaces that I created earlier. So I want to come back up here and now when this runs. The idea is you pick a workspace on the first screen. Let's go back here one more time you pick a workspace here and you navigate to another location. But as navigate. What we're going to do here? Let me go ahead and click off and then click on this so you can kind of see the code behind this. And the idea here if I go to on select is every time we go to that workspace detail form. We're going to take the currently selected Workspace and we're going to make calls to get the data sets and everything in there and I've also got something where I navigate to a loading screen so when you click here while it's making those API calls, it's showing the user something interesting and then n when they're done, we're able to drill inside here and see all the different users the different PBX files that have been imported. I can see my different datasets, my reports dashboards, so once again it kind of gives you an easy way to. The lay of the land of the things that you are know have access to. Now let's say that I go something like this customer sales in Contoso Dev. Now before I do that. Let's go back here and I'm going to go to Contoso Dev. And let's say that one of the things I was really interested in is making sure we have data refresh going. So what I've been doing is I've been kind of drilling down into this particular data set once I I drill down into the data set, I can see the refresh history. Now one other thing, let's go back here and let's kick off a refresh through the UI, so I'll go ahead and kick this off. And the idea is that this is running. I can have a scheduled refresh, but what I want to show is that you can look at the refresh history. We can look at the data sources behind, so as this is is is running right here. Let's go back here. Let's go back to that data set. Let's drill into it as I do that, it's going to call and you can see that I can see the refresh history inside here I can see the data sources for this, so being able to kind of drill down. Also, let's say that I do a refresh now. All of a sudden we've got an API that's called to start another refresh on that particular data set. OK. One other nice thing is that there is a data set. Property is refreshable. So if you look at this refresh now button, if you look at the visible property, it's only visible if we have a refreshable data set inside there. Now you've had seen this particular demo. One of the things that I kind of wanted to bring out is what type of applications that you can start building with these custom connectors. And once again, if I go back. Here. And I go back to the power BI rest API. Just kind of think about just about everything that you see here is accessible to you from power platform. I will say there are some things that you can't call directly from Canvas apps because they have asynchronous patterns that we have to call from a flow. But once again, everything is just bounded by your imagination and how you're able to credibly use APIs that you saw there A data set details page. That we have there. OK, now let's say I want to call a. Connect your action from a flow that is possible but let's say before we do that, I want to call. Flow from my canvas app. So let's say that I go back here and I'm going to go back. To the workspace detail screen and in the workspace detail screen there is this import wingtip. So here I have the name of a flow. And the idea is when I click that I'm able to pass a lot of parameters from my canvas app into the flow. So let's go, let's look at this. What we're going to do. Is. I am now going to go back into my cloud flows. And let's look at import. To workspace. Now. The first thing to note here is that when you are going to call A. Flow from a canvas app. Something they did about a year ago is they added a new trigger, which is the power apps V2 trigger and that allows you to add inputs. So now I can define a set of parameters that I want to pass from the Canvas app into the flow. Now. One of the things that we're going to do here is we're going to get an access token, and I'll talk about that. In a couple slides, but this is the flow that actually. Gets an access token for a service principal. But now what we're able to do is to either have the flow call into a custom connector, or have the flow directly call the power BI API itself. Here's an example when you u run as a service principal. You can't use a custom connector 'cause they're not supported. Yeah, so ultimately what you're going to do is you're going to get an access token, and I'll cover that in a little bit and put it in the authorization header. But now what we're able to do is we're able to target a particular workspace with our URL. Imported to PBX file is tricky because you have to use a multipart form and you have to kind of build the body inside here, but if I take this up flow. And we go back and kind of look at the history when I click that button. 7 minutes to go in my demo What actually happened? So this flow ran we e got an access token I wanted to get a template. And note that I should have stepped through a little bit more. Let's go back here, but there is an action. To go into power BI, I'm sorry to go into a SharePoint site and find a PBX file. And the idea is that I can leave my template files here in SharePoint and what's kind of neat about that is that I can also use version history so I can upload another version and another version, and if I import version three but we want it back to version two, we can just kind of back up here and rerun the flow. OK yeah, but the idea here is we're going to grab this template and then we're going to use that in the import process. One of the things that's a little bit tricky about this type of a flow. Is that when you call PBX import? What you'll find is that it returns right away. But not necessarily with any data about whether it's done. So after you make this call to post import then what you're going to have to do is you're going to have to kind of loop around and call get import state. And the idea is that when you start an import operation, it gives you back Duguid which is s basically the import ID. And then you call another call inside here and you get that import ID and that kind of gives you the status of it. And the idea is that when you look at that status, we're going to keep running this until we basically have a status that says complete and then we keep going you d the reason we need to kind of do this do while is that we've just uploaded a PBX file and So what we have to do is we have to pause and keep saying are you done yet? Are you done yet and when it is we fall out of this loop? Now from the very last call to get import status, I can see the datasets and reports that have been created so I can get the data set ID and d now here's examples of you nging the database details so I can update parameters and now we're going to set credentials. And once we've set credentials, we're going to start a refresh operation. OK, so once again you can kind of see how we're able to kind of put all this together you into a single flow. And once again, one of the things I wanted to demonstrate here. Is that quite often if you u have a power BI API call where you just call it and get back data, you can call it from a canvas app, but when you call it and get back and import ID and then you have to keep saying. Is this import job associated with this import ID done yet and you keep pulling? You know that's s something where? Now we have to kind of do that work in a flow. OK, but now that you've kind of seen that you've seen how we can get in there. You've kind of seen executing that flow from a campus app, and you kind of saw that the power apps V2 trigger is the key to defining all the parameters you want to pass from your canvas app. You know to your flow. Now. You saw calling that from the canvas app, and this is kind of interesting because we're calling it from an app that's authenticated as a user, but once the flow runs, it basically says forget who the user is. You know we're going to use a service principle. And that's why I had to add the service principle as a user to that site. So the service principle can then be the one that uploads data sets and does things like manages dentials and takes care of running refresh operations, not the only way to do it, but a pretty good way to do it now One of the things in my last demo I didn't go into yet is this whole idea of calling the power BI Rest API as a service principle. Now, the way we're going to do that. As I mentioned, we can't use custom connectors. So instead, we're just going to do the client credentials flow directly. From my flow. So let's go back to cloud flows here. When I get to kalvos, we're going to open up this. Get access token for service principle. Now. One nice thing about working with. Custom connectors is not only do they kind of hide the details of. Obtaining access tokens and adding them to the authentic authentication authorization header behind the scenes. They also do a great job of hiding your secrets, so here this is a proof of concept and note that I have my client ID and I have my client secret just kind of hard coded in so this is a proof of concept and so what I say if you want to take this and run with it, you're going to have to find a better way to kind of take your client secret and not put it in a flow definition. But put it in Azure Key Vault or some other place where you feel confident you know that your secrets aren't going to get around. But the idea here is that I can run client credentials flow. And when we run this right here, it's gonna. Send a post right up against Azure AD It turns out that this is an endpoint that you use to get access tokens and it's wide e open. You don't need authentication to call this. But the idea is that we're going to call this inside here and then there's a bunch of complicated stuff we have to put inside the body because we have a content type of application X WWW form. You'll encoded great stuff, but the idea here is, let's go ahead and run this right here. And as we run this right here. This is going to get those details we're going to o have this request that goes across. You can kind of see what comes back. There's my access token we can see e that it expires in an hour. And then there's one more thing we do here, and that is, we take the client credentials flow and we use something to kind of put it into a prettier output format here. And the idea is that now what we're able to do is we're able to send a response, and it's kind of nice about this is that when we use it from another flow? It's gonna be easy for us to get the access token. OK, that you've seen that you've kind of seen the child flow that we're going to use to run as a service principal. Yeah, let's one more time. Go back to our solution. Up back in our solution we're going to go back to the import PBX and let's go ahead and open that into edit mode. And what you're gonna see here. Is that? When you add an action. Like let's say that I wanted to call a child flow, so I'll go ahead. Click, add an action, and when this comes up and I click on child down here you can see run a child flow. OK now I've e done that here. What child flow do I want to call? I'm going to call this one right here. Get access token for principle and then back over here you can kind of see that because I kind of added a strongly typed response when I run this child flow, I can just take the access token. And drop it in here and that's what gives me the ability now to make any API call, because as long as I say authorization bearer and we add that access token, yeah, I'm able to make any call. I want you as a service principal. OK, now. I'm not going to go into the details of how to get the service principle configured so it can call into power BI. I've done that in many other sessions, but just with the amount of things we need to cover, if you have never configured service principle access before, we have good documentation for that up in the power BI docs for developers. OK, let's go ahead and move back to my slides now. So what I wanted to kind of show how you can call the power BI Rest API as a service principal and. Because we can't use custom connectors. The idea is to go through client credentials flow and just basically get the access token right back into your flow and then make calls using the HTTP action. It's a little bit more work. But I also find that it gives you complete flexibility. We saw client credentials flow how to o get that access token and then I showed you an example of importing PBX files using the HTTP action and kind of showed how you're able to take the access token and add it inside there. OK, so where we got left? I think we got about. OK at this point we're into our last section right here at Daniel. Do we have any questions that we could take? We got a few questions. The first one is from anonymous. How many days of estimated development effort, for example, for creating an auditing report using the API in terms of getting failed refreshes, including who owns the data set data flows, and what is the cost of data verse? So it's like a two part question, how long will it take? And the example would be, how long would it take to run 100 yard dash? We can compare me to the world champion and there would be quite different times but I think if there is a few months to get up to speed on campus app or flow development, so if you have someone who's already up to speed and confident with that. And you have to kind of learn the basics of rest API calls, so that's another learning curve. But for someone who knew those, I think you onth or two would be a reasonable development time to kind of create a reasonable application using this approach. OK, I got another couple questions. Are these canvas app samples provided in the git in the downloadable file they are in the downloadable file now w that being said, you'll have to import a solution and get the custom connector configured. So there will be some things you have to wrestle with to get these working, but if you get the custom connector and the Azure AD applications behind it up and working you should be able to import the power platform solution and get things working inside there. One last yeah, the last question how to generate the multipart? How to generate a multipart. Unfortunately, there's too many details to go through to give you a really good answer to that, but let's go back here and I think kind of what you're getting in is post import you. How did you build the multipart? And that's not the right one. This is the right one here. But this was something I had to really wrestle with to kind of get this working. And. Hopefully you know this solution will kind of show you, but I've seen no guidance or anything else, but by kind of taking things I saw after Googling. Figuring out how to put that together. So once again I can't tell you documentation for multipart form, but it's been a requirement of PBX and we used to have to do that in C and then they just kind of built it into PowerShell and built it into the API just to kind of make it all go away. But if you're going to do it. From a flow you have to know the details so I I wish I could tell you more, but I really don't have those other than you taking a look at the sample I've created. OK, let's go, maybe we can hit some more questions at the very end Daniel, but let me get back to my slides here. And So what we're gonna end with is looking at a couple things as far as automating tasks using the power BI admin APIs. Now there is a second connector, powerbi admin. And we have things like calls et groups as admin. Now. One thing to note here is that. The API's use the old names, get groups as admin know. But what I found is I created my custom connectors is that you can name them whatever you want if you want t to make things easier calling them get workspaces as admin instead of get groups behind the scenes you u still have to have something that maps to groups but t once again when it comes to kind of naming the method or naming. Path parameters you can switch those to anything that you want and make them you more readable, you know, but the idea here is let's go back. And there is another application that we're going to look at here. And if we look at this application. This is going to call get groups as admin, so let's go back here and we're going to open this up. And so we got 10 minutes and two more applications to look at. So let's go and we look at the power BI asset auditor. So first of all, remember this is Colleen Admin API's and so the current user must authenticate with the user account that either is a power BI service administrator or global tenant admin and during the authentication process if the user r doesn't have those permissions. It's going to fail, not given access token just because of the way that acquiring tokens works. Now with this application right here one of the things that you can see here is that when we start up this, we're going to do things like call get capacities as admin get t refresh tables as admin, get pipelines We're going to get workspaces as admin here, and when I call get workspaces is admin. Notice that this lets me do and expand. OK, now if I go back here too, I slide for a second. Note that when we've defined know this, we have an expand. And with expand, you can say, don't just give me the workspace, but give me all the users and all the data sets and all the reports ere's also a filter parameter. And you can filter on things like the type ou want to find personal workspaces, or V2 workspaces or V1 workspaces? What's the state? Do you want to see if they're deleted or not? OK, when we call this let's go back here what you can see here is if I go ahead and run this, I'm able to see all the different app workspaces. If I want to see App Workspaces that have been deleted, yeah, I can basically see those as well. If I want to just say personal workspaces instead of app Workspaces, I can do that. Furthermore, the way that this works, I should see things like capacities refreshable's, gateways, apps My application is not that beautiful, I apologize for that and also you as we drill into something. You know what I can do is I can start seeing you know all the different things and unlike my first demo where I called and got all the workspaces and then when I wanted to kind of see workspace details we kind of call. Get data sets and get reports and get imports. But here I got all the data back at once. It's kind of strange about this call, right Here is if I go back to view and we look at our collections that we look at workspaces each time we call one of those. And I think I'll have to go over here, or I can see that the name of the workspace. But the idea here is if I have this workspace. And now we go over and say what are the datasets? Now you can see it passes all that back. And so here you can see that with that information we're able to o kind of go back and forth and see details such as you. What are all the assets in there? Now. Get workspaces admin. It was great. OK, and you're thinking can I just call this and can I have my cake and eat it too? And the answer is yes as long as your cake isn't very big. So one of the issues with calling get groups as admin is let's say you're in an environment that has 2000. 2000 different workspaces and you're saying give me the top 100 and now each time you're making the call you're trying to get back all the detail for 100 different workspaces so o what you'll find is that this only goes so far, so we've found that some of our customers have tried some really tricky things with filtering and we have to kind of put some throttling in place. So the things that I'll call out here is that when you call the get groups Admin API, it's going to be on a priority thread. But it has 30 seconds or they timeout. Also, we're not going to let you know any customer continually call get groups as admin. Just because of the taxation so the idea is you're limited to 50 calls per hour. If get groups as admin is something that only scales so far, where do I go next and the answer is basically scanning a workflow. The idea of scanning a workflow if you have a workspace ID, you can do a scan and it's far more scalable because we don't put a limit on it. And one of the reasons we don't put a limit on it is 'cause we don't run it on a foreground thread. Think of it runs on a background thread and so you can queue up as many scans as you want. Now it's going to be more difficult to call because it's in asynchronous API. Let's go ahead and kind of see two things. The first thing I want to look at here. And I keep spawning all these different windows. Here is, let's say that I go back to my apps in the last one here is s scan man. So I'm gonna open this up. Now what we're going to do here is when we call get groups as admin, we're not going to expand. We're going to have that be a very expensive way just to get back the idea of the workspace and the name, and maybe a little bit of other data. Furthermore, I can put things like a search box in place so when I get my workspaces back, OK I'm sorry this demo is not as polished as it could be, but the idea. Is once you go ahead and execute this, let's go back here and I go to unselect and so. What you're gonna see here is as I click on this. And I go to this other workspace right here. Gosh, you can see it's still in on the whiteboard. Still in the prototyping phase here, but the idea is we just scanned or workspace. So how do we scan a workspace? And So what I want to see here is if I go back to the workspace scan screen. And we go to. On visible. What we're gonna do is we're going to go ahead and we're going to. Run a flow which is scan workspace and the idea is I'm going to run this flow. I'm going to pass out the workspace ID and it's going to give me back a scan result. Once I get that scan result back I I know there's only one workspace, so I'm going to basically say give me the first workspace in the workspaces collection, and then I'm going to pull the data sources out. When I look at this flow let's go back here. We got about 3 minutes left so I gotta go quickly here. And So what we're going to look at is scan workspace. So let's go ahead and open this up. Now. When we scan a workspace, what we need first of all is we need the workspace ID so that's going to be passed in from the Canvas app. But once that gets passed in, we're going to run a child flow to get an access token and then we're going to post Workspace info. So the idea here is that I post this and then how do I tell it what workspaces and here we're going to basically put together the Jason body that we need to call this inside? Once this runs. This doesn't give you back any info, this just gives you back a kind of a scan operation ID. And the idea is that once we get these scan ID now what we need to do is to basically say now that we've started the scan. Let's wait some amount of seconds. So I'm gonna wait two seconds and the idea is we'll keep running this every two seconds to pole. We're going to basically now make another call to get the scan status, and then we're going to look at the scan result and the idea a is that we can have a variable is s the scan complete if I come back here and kind of take a look at the. Expression that we have right here What you can see here is that we have scanned complete and once the scan gets complete, we're able to take the response and put it back. OK, now I looked at scan workspace and I kind of talked about the motivation. One more thing I wanna. Cover just 'cause I know. We're kind of at the ending time is accessing the power be I. Activity log from a flow. So. The last flow we're going to look at here. It's basically one. It's actually a set of flows that allows us to get. The data, the actual events from the Power BI event activity log. So I'm gonna take a quick pass through this just to kind of show the layout of land of how this works. Now what I wanted to kind of show here at the end is when the Canvas app can't cut it because there's a series of calls to deal with an asynchronous pattern. Now in this case right here, I'm not calling this as a service principal. But here we're just kind of using our. Power BI admin custom connector. So note that if I add an action. And then I say custom I can find d my custom connector and we can add that from anyone of these inside, so that's what we've done in our case right here where we're going to call to the get activity event log. And the idea is you have to pass a start date and end date and typically you have kind of midnight. And then a second before midnight the next day. So you gotta have a whole date range Or it can be smaller. But the idea is that you can't crossover days now. The first time we call this we e pass the start date and end date. The reason that this one is tricky is that we're going to have a do loop, and the idea here is that each time we call this might pass back a continuation token. And the idea of a continuation token is we have a paginated result. So the first time you call it, you pass start date, end date. It gives you results, set one and a continuation token. And the idea is that you have to keep calling and keep aggregating the results together until you get to the very end. And the idea is it might take 10 calls. It might take one call who o knows. But the idea is it's a scalable pattern. So as we call these right here, you know what you're gonna see here is that if I look down here into the do while loop, you can say here we basically had to go through 20 loops of you and this particular loop we call down here and we can see we got a continuation token. Great, OK, and now you s go all the way to the very last 120 and what we should be able to kind of see. In the outputs here. Now is that now it's not exactly what I wanted to say, but the idea that you there. Was no continuation token, and that's kind of why we dropped out of the loop. OK, and. What I have here is something that if I go over here into. SharePoint, I'm basically running something once a night. And the idea is that every day at 4:00 in the morning I I run something that runs this and it basically gets all the activity and basically puts it into a Jason file in SharePoint. And now I can kind of create something in power BI desktop to bring in all these JSON files, start looking at all this event activity For instance, if I come back over here. If I then kind of pull all those things in there. This gives me a way to kind of pull out activity data and unlike the activity blog, I can store this data as long as I want. I want three years worth of data. I can have that so it just kind of gives you one possible alternative. So I think we're a little bit over right here, but. If I kind of back up to the beginning of the last section here. I just kind of want to do an outro by saying calling get groups as admin is easy to call because it's synchronous call you call, you get back data but you can only get so much data back before it's not going to work. It's going to time out or you're going to have to call it more than 50 times an hour So what you can then do is move to the scan API and the idea with the scan API is that you can't call it directly from a canvas app because it's an asynchronous pattern. But the idea is you start a scan and then you have the scan ID and you can just pull it till it's done and then you're able to go back and get the data. And then we saw one other example and that was trying to get data out of the power BI activity log, and once again that's an asynchronous pattern because they give you a continuation token. And the idea is we can't give you all the data at once, 'cause there's too much to give you on one HTTP request. So if we give you back a continuation token so you can make another request. Until finally you get back a reply that doesn't have a continuation token. Now you've got all the data so once again trying to execute an API like that from a canvas app is impossible, but you can put it into a flow and then call that from the Canvas app and get the results back into the flow. So with that we're now at the end of our session. So at this point, I think since we're over we probably should go ahead and. Close up, so I'll pass back to you, Daniel would like to make any comments before we closeout. Thank you so much for everything and thanks for teaching us how to build solutions using power, automate and the Power BI rest API. I just wanted to give a quick plug to the power BI community available at Community Dot powerbi dot then also just reminder to check out our YouTube channel. You can go to AKA dot Ms Slash power by YouTube and you'll get a playlist link to all of the webinars and past Dev Camp Sessions. So yeah, thanks so much and a have a good one. We'll see you all next year. Thanks very much Daniel, and Happy Holidays to you and to all our campers. Thanks bye bye.