Package: pbipy
pbipypbipyis a Python Library for interacting with the Power BI Rest API. It aims to simplyify working with the Power BI Rest API and support programatic administration of Power BI in Python.pbipysupports operations for Apps, Dataflows, Datasets, Reports, and Workspaces (Groups), allowing users to perform actions on their PowerBI instance using Python.Installationpip install pbipyOr to install the latest development code:pip install git+https://github.com/andrewvillazon/pbipyGetting Started: AuthenticationTo usepbipyyou'll first need to acquire abearer_token.How do I get abearer_token?To acquire abearer_tokenyou'll need to authenticate against yourRegistered Azure Power BI App. Registering is the first step in turning on the Power BI Rest API, so from here on it's assumed your Power BI Rest API is up and running.To authenticate against the Registered App, Microsoft provides theMSALandazure-identitypython libraries. These libraries support different ways of acquiring abearer_tokenand which to use will depend on how your cloud/tenant is configured.Because there are multiple ways to acquire the token,pbipyleaves it up to the user do this in the way that suits, rather than directly handling authentication (of course, this might change in future).ThisREADMEdoesn't cover authentication in detail, however, these are some helpful resources that look at acquiring abearer_tokenin the context of Power BI:Power BI REST API with Python and MSAL. Part II.Power BI REST API with Python Part III, azure-identityMonitoring Power BI using REST APIs from PythonThe example below uses themsallibrary to to get a bearer_token.importmsal#  msal auth setupdefacquire_bearer_token(username,password,azure_tenant_id,client_id,scopes):app=msal.PublicClientApplication(client_id,authority=azure_tenant_id)result=app.acquire_token_by_username_password(username,password,scopes)returnresult["access_token"]bearer_token=acquire_bearer_token(username="your-username",password="your-password",azure_tenant_id="https://login.microsoftonline.com/your-azure-tenant-id",client_id="your-pbi-client-id",scopes=["https://analysis.windows.net/powerbi/api/.default"],)The code that follows assumes you've authenticated and acquired yourbearer_token.UseageStart by creating thePowerBI()client. Interactions with the Power BI Rest API go through this object.frompbipyimportPowerBIpbi=PowerBI(bearer_token)To interact with the API, simply call the relevant method from the client.# Grab the datasets from a workspacepbi.datasets(group="f089354e-8366-4e18-aea3-4cb4a3a50b48")pbipyconverts API responses into regular Python objects, with snake case included! 🐍🐍sales=pbi.dataset("cfafbeb1-8037-4d0c-896e-a46fb27ff229")print(type(sales))print(hasattr(sales,"configured_by"))# <class 'pbipy.resources.Dataset'># TrueMost methods take in an object id...dataset=pbi.dataset(id="cfafbeb1-8037-4d0c-896e-a46fb27ff229",group="a2f89923-421a-464e-bf4c-25eab39bb09f")... or just pass in the object itself.group=pbi.group("a2f89923-421a-464e-bf4c-25eab39bb09f")dataset=pbi.dataset("cfafbeb1-8037-4d0c-896e-a46fb27ff229",group=group)If you need to access the raw json representation, this is supported to.sales=pbi.dataset("cfafbeb1-8037-4d0c-896e-a46fb27ff229")print(sales.raw)# {#   "id": "cfafbeb1-8037-4d0c-896e-a46fb27ff229",#   "name": "SalesMarketing",#   "addRowsAPIEnabled": False,#   "configuredBy": "john@contoso.com",#   ...# }Example: Working with DatasetsLet's see howpbipyworks by performing some operations on a Dataset.First, we initialize our client.frompbipyimportPowerBIpbi=PowerBI(bearer_token)Now that we've got a client, we can load a Dataset from the API. To load a Dataset, we call thedataset()method with anidandgroupargument. In the Power BI Rest API, aGroupandWorkspaceare synonymous and used interchangeably.sales=pbi.dataset(id="cfafbeb1-8037-4d0c-896e-a46fb27ff229",group="f089354e-8366-4e18-aea3-4cb4a3a50b48",)print(sales)# <Dataset id='cfafbeb1-8037-4d0c-896e-a46fb27ff229', name='SalesMarketing', ...>Dataset not updating? Let's look at the Refresh History.We call therefresh_history()method on our Dataset. Easy.refresh_history=sales.refresh_history()forentryinrefresh_history:print(entry)# {"refreshType":"ViaApi", "startTime":"2017-06-13T09:25:43.153Z", "status": "Completed" ...}Need to kick off a refresh? That's easy too.sales.refresh()How about adding some user permissions to our Dataset? Just call theadd_user()method with the User's details and permissions.# Give John 'Read' access on the datasetsales.add_user("john@contoso.com","User","Read")Lastly, if we're feeling adventurous, we can execute DAX against a Dataset and use the results in Python.dxq_result=sales.execute_queries("EVALUATE VALUES(MyTable)")print(dxq_result)# {#   "results": [#     {#       "tables": [#         {#           "rows": [#             {#               "MyTable[Year]": 2010,#               "MyTable[Quarter]": "Q1"#             },# ...# }Example: Working with the Admin objectpbypialso supportsAdministrator Operations, specialized operations available to users with Power BI Admin rights. Let's see how we can use these.First, we need to initialize our client. Then we call theadminmethod and initialize anAdminobject.frompbipyimportPowerBIpbi=PowerBI(bearer_token)admin=pbi.admin()Need to review some access on some reports? We can call thereport_usersmethod.users=admin.report_users("5b218778-e7a5-4d73-8187-f10824047715")print(users[0])# {"displayName": "John Nick", "emailAddress": "john@contoso.com", ...}What about understanding User activity on your Power BI tenant?fromdatetimeimportdatetimestart_dtm=datetime(2019,8,31,0,0,0)end_dtm=datetime(2019,8,31,23,59,59)activity_events=admin.activity_events(start_dtm,end_dtm)print(activity_events)# [#   {#       "Id": "41ce06d1",#       "CreationTime": "2019-08-13T07:55:15",#       "Operation": "ViewReport",#       ...#   },#   {#       "Id": "c632aa64",#       "CreationTime": "2019-08-13T07:55:10",#       "Operation": "GetSnapshots",#       ...#   }# ]More examplesDatasets in a Workspacedatasets=pbi.datasets(group="f089354e-8366-4e18-aea3-4cb4a3a50b48")fordatasetindatasets:print(dataset)# <Dataset id='cfafbeb1-8037-4d0c-896e-a46fb27ff229', ...># <Dataset id='f7fc6510-e151-42a3-850b-d0805a391db0', ...>List Workspacesgroups=pbi.groups()forgroupingroups:print(group)# <Group id='a2f89923-421a-464e-bf4c-25eab39bb09f', name='contoso'># <Group id='3d9b93c6-7b6d-4801-a491-1738910904fd', name='marketing'>Create a Workspacegroup=pbi.create_group("contoso")print(group)# <Group id='a2f89923-421a-464e-bf4c-25eab39bb09f', name='contoso'>Users and their accessgroup=pbi.group("a2f89923-421a-464e-bf4c-25eab39bb09f")users=group.users()foruserinusers:print(user)# {"identifier": "john@contoso.com", "groupUserAccessRight": "Admin", ... }# {"identifier": "Adam@contoso.com", "groupUserAccessRight": "Member", ... }Power BI Rest API Operationspbipymethods wrap around the Operations described in the Power BI Rest API Reference:Power BI REST APIs for embedded analytics and automation - Power BI REST APIWhat's implemented?Most of the core operations on Datasets, Workspaces (Groups), Reports, Apps, and Dataflows are implemented. Given the many available endpoints, not everything is covered bypbipy, so expect a few features to be missing.If an operation is missing and you think it'd be useful, feel free to suggest it on theIssues tab.PowerBI ComponentProgressNotesDatasetsDoneGroups (Workspaces)DoneReportsDoneAppsDoneDataflowsDoneAdmin OperationsDoneImplements operations related to Datasets, Groups, Reports, Apps, and Dataflows only.DashboardsTodoEverything elseBacklogContributingpbipyis an open source project. Contributions such as bug reports, fixes, documentation or docstrings, enhancements, and ideas are welcome.pbipyuses github to host code, track issues, record feature requests, and accept pull requests.ViewCONTRIBUTING.mdto learn more about contributing.AcknowledgementsThe design of this library was heavily inspired by (basically copied) thepycontribs/jiralibrary. It also borrows elements ofcmberryay's pypowerbi wrapper.Thank You to all the contributors to these libraries for the great examples of what an API Wrapper can be.