{"id":91314,"date":"2021-06-14T19:55:05","date_gmt":"2021-06-14T19:55:05","guid":{"rendered":"https:\/\/www.red-gate.com\/simple-talk\/?p=91314"},"modified":"2024-09-03T20:15:20","modified_gmt":"2024-09-03T20:15:20","slug":"power-bi-jupyter-notebooks","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/databases\/sql-server\/bi-sql-server\/power-bi-jupyter-notebooks\/","title":{"rendered":"Embed Power BI in Jupyter Notebooks"},"content":{"rendered":"<p>Microsoft recently announced the ability to include <strong>Power BI<\/strong> reports inside <strong>Jupyter<\/strong> notebooks. After overcoming the dazzle of this exciting feature, what comes to my mind is: \u201cWhy do we need this?\u201d<\/p>\n<p>I\u2019m far from being a <strong>Jupyter<\/strong> notebook expert, but as far as I know, they are used for interactive analysis. Why, in the middle of an interactive analysis, would I need to get a <strong>Power BI Report<\/strong>?<\/p>\n<p>Even if the <strong>Power BI Report<\/strong> is not exactly what I need, I could continue the analysis in <strong>Power BI. <\/strong>Why should I move it to <strong>Jupyter<\/strong> and make this kind of integration with an existing report?<\/p>\n<p>I decided to look for more opinions and asked this question on Twitter. This was the result:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-91315\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/06\/word-image-22.png\" alt=\"Tweet from Dennes asking why you would want to embed Power Bi in Jupyter notebook\" width=\"598\" height=\"105\" \/><\/p>\n<p>The question has one <em>\u201cLove\u201d<\/em>, three retweets (it was not from my mom; she is still learning about Twitter). This probably means there are more people with the same question but no reply. Others have the same question, and no one has the answer yet.<\/p>\n<p>The best way to discover what we can be done with it is to investigate the feature.<\/p>\n<h2>Choosing the tool<\/h2>\n<p>As I explained, I\u2019m not a <strong>Jupyter<\/strong> expert. Where could I create a <strong>Jupyter<\/strong> notebook?<\/p>\n<p>I chose to use <strong>Visual Studio Code<\/strong> to create the <strong>Jupyter<\/strong> notebook. Experts in <strong>Jupyter<\/strong> notebooks might use other tools, so I\u2019m unsure if <strong>VS Code<\/strong> is the best tool to deal with data, but it works.<\/p>\n<p>Once deciding to use Visual Studio Code, the <strong>Jupyter<\/strong> extension must be installed. It\u2019s easy to find the Extensions on the left toolbar and check for <strong>Jupyter<\/strong>.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-91316\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/06\/word-image-23.png\" alt=\"Jupyter Notebook extension for VS Code\" width=\"782\" height=\"83\" \/><\/p>\n<p>Once the extension is installed, you can use the Command Pallet to create a new empty <strong>Jupyter<\/strong> notebook:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-91317\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/06\/word-image-24.png\" alt=\"The command palette\" width=\"375\" height=\"93\" \/><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-91318\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/06\/word-image-25.png\" alt=\"Create a new jupyter notebook\" width=\"784\" height=\"122\" \/><\/p>\n<p>This <strong>Jupyter<\/strong> extension in <strong>VS Code<\/strong> was released in April of this year and was demonstrated during the great <a href=\"https:\/\/www.youtube.com\/watch?v=EWYYgEkGJfs\">Scott Hanselman keynote<\/a> at <em>Build<\/em>. You can <a href=\"https:\/\/devblogs.microsoft.com\/python\/jupyter-in-visual-studio-code-april-2021-release\/?WT.mc_id=DP-MVP-4014132\">read more about the extension<\/a> as well.<\/p>\n<h2>Installing the client<\/h2>\n<p>This feature is enabled by a new <strong>PyPI<\/strong> library called <strong>Power BI Client<\/strong>. It\u2019s very easily installed using PIP, and the Visual Studio Code terminal supports PIP.<\/p>\n<p>Navigate to <em>View-&gt;Terminal<\/em> or <em>Terminal -&gt; New<\/em> Terminal in the <strong>VS Code<\/strong> menu to open the terminal and use PIP.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-91319\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/06\/word-image-26.png\" alt=\"install the Power BI Client from command line\" width=\"436\" height=\"101\" \/><\/p>\n<p>The <strong>Power BI Client<\/strong> is an <a href=\"https:\/\/github.com\/microsoft\/powerbi-jupyter\">open-source library<\/a>. This is very helpful, because the source code provides a reference to use the <strong>Power BI<\/strong> api, and you could develop any feature missing from this library.<\/p>\n<h2>Building the notebook<\/h2>\n<p>Add a code block to the notebook. By adding the following code, you import the libraries used for this example. Here\u2019s the code:<\/p>\n<pre class=\"lang:none theme:none\">from\u00a0powerbiclient\u00a0import\u00a0Report,\u00a0models\r\nfrom\u00a0powerbiclient.authentication\u00a0import\u00a0DeviceCodeLoginAuthentication\r\nimport\u00a0pandas\u00a0as\u00a0pd\r\nif\u00a0sys.version_info[0]\u00a0&lt;\u00a03:\u00a0\r\n\u00a0\u00a0\u00a0\u00a0from\u00a0StringIO\u00a0import\u00a0StringIO\r\nelse:\r\n\u00a0\u00a0\u00a0\u00a0from\u00a0io\u00a0import\u00a0StringIO\r\nimport\u00a0matplotlib.pyplot\u00a0as\u00a0plt<\/pre>\n<p>Go ahead and execute the code block. The next action is to authenticate with <strong>Power BI<\/strong>. There are four authentication options, and all these options make me think this library can have many other uses than embed Power BI inside <strong>Jupyter<\/strong> notebooks.<\/p>\n<h3>Authentication options<\/h3>\n<p>Two of the four authentication options will require interactive actions by the user on the app, while the other two will not require any interactive action.<\/p>\n<p><strong>Interactive Flow:<\/strong> This one starts an interactive authentication process opening a browser window for authentication. Once the authentication is done, the notebook receives the authentication token back from the browser window.<\/p>\n<p><strong>Device Flow:<\/strong> This is the one to use for this example. It starts an interactive authentication process, but the process keeps no relation between the notebook and the browser window. In the notebook, it provides a link and a code. You need to access the link in any browser window you like, input the code, and authenticate. The website will provide the authentication token back to the notebook. Only after this process, the execution can continue.<\/p>\n<p><strong>Service Principal Flow:<\/strong> This authentication method is basically an App authentication, usually used by services and applications. An <strong>App<\/strong> is registered in <strong>Azure AD<\/strong> and generates a <em>client_id<\/em> and secret for the authentication of a client app.<\/p>\n<p><strong>Master User Flow:<\/strong> In this one, you have a username and password, and you will use them for the authentication.<\/p>\n<h3>The authentication code block<\/h3>\n<p>The import needed for the authentication was already included on the first code block, so this second one has only a single statement:<\/p>\n<pre class=\"lang:none theme:none\">#\u00a0Initiate\u00a0device\u00a0authentication\r\ndevice_auth\u00a0=\u00a0DeviceCodeLoginAuthentication()<\/pre>\n<p>After the execution of this cell, you will see the URL and code needed for authentication:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-91320\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/06\/word-image-27.png\" alt=\"Interactive authentication inside the notebook\" width=\"1348\" height=\"233\" \/><\/p>\n<p>Open this URL on the browser, copy the code and complete authentication. Only after that will the execution continue.<\/p>\n<h3>Power BI object names<\/h3>\n<p>The next step is getting the report. This and the next few steps will need to use the name of the <strong>Power BI<\/strong> objects. The problem is that the name of the objects is not as apparent as one would expect and may be more difficult to find.<\/p>\n<p>Let\u2019s start with the workspace name and the report name, because we need to use both to retrieve the report.<\/p>\n<h3>Workspace name<\/h3>\n<p>Navigate to Power BI online found at <a href=\"https:\/\/app.powerbi.com\">https:\/\/app.powerbi.com<\/a>. Navigate to one of your workspaces. Once accessing the workspace, the name is the GUID in the <em>URL<\/em>. The workspace is also called \u201cGroup\u201d. It\u2019s important to keep this in mind this so you can recognize the code.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-91321\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/06\/word-image-28.png\" alt=\"Navigate to your Power BI reports\" width=\"602\" height=\"141\" \/><\/p>\n<h3>Report Name<\/h3>\n<p>In the same way as the workspace, the <em>report\u2019s GUID<\/em> appears in the <em>URL<\/em> when launching a report.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"602\" height=\"45\" class=\"wp-image-91322\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/06\/word-image-29.png\" \/><\/p>\n<h3>Variables cell<\/h3>\n<p>Now create a cell to set these values in variables, so they can be used again whenever needed:<\/p>\n<pre class=\"lang:none theme:none\">group_id=\"af793584-24cf-4df0-bb78-cd5dd118bb8d\"\r\nreport_id=\"c059c83d-41ee-4f11-9aaa-4c1ef8bdbf14\"<\/pre>\n<h3>Embedding the report<\/h3>\n<p>After finding the name of the workspace and the report, our next code cell can already embed the report.<\/p>\n<p>First, we recover the report object. Many methods are available over the report object, but if our objective is only to embed it, we can just let the object do the work:<\/p>\n<pre class=\"lang:none theme:none\">report\u00a0=\u00a0Report(group_id=group_id,\u00a0report_id=report_id,\u00a0auth=device_auth)\r\nreport<\/pre>\n<p>The image below is a very simple report embedded in a <strong>Jupyter<\/strong> notebook.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-91323\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/06\/word-image-30.png\" alt=\"A simple report from Power BI embedded in a Jupyter Notebook\" width=\"1762\" height=\"771\" \/><\/p>\n<h2>Beyond the report<\/h2>\n<p>The question remains: Why do you need a PBI report inside a <strong>Jupyter<\/strong> notebook?<\/p>\n<p>If you can have access to the data, on the other hand, everything changes. You could retrieve the data from <strong>Power BI<\/strong> and do customized work with it, allowing <strong>Power BI<\/strong> analysts and <strong>Jupyter<\/strong> analysts to work on the same set of data. It would be way better to have direct access to a <strong>Power BI<\/strong> <strong>Dataset<\/strong> or <strong>Dataflow<\/strong>. However, what you can do with the <strong>Power BI Client<\/strong> is access the visuals and then get the underlying data from the visual as I\u2019ll demonstrate in the subsequent sections.<\/p>\n<p>If the purpose is to get the data, access a report, report page and visual to get the underlying data and be able to make further analysis with the data is a considerable work-around for this task. IMHO, I consider the word work-around very soft for these situations, that\u2019s why we, Brazilians, are introducing into Europe the word \u201cGambiarra\u201d.<\/p>\n<h3>Page and visual name<\/h3>\n<p>Once again, discovering the page and visual name can be a challenge. This time, it\u2019s even a bigger challenge than before, because these two the names don\u2019t appear in the <em>URL<\/em>.<\/p>\n<p>To solve this problem, the <strong>Power BI Client<\/strong> enables retrieving this information from the list of pages of the report and list of visuals in a page.<\/p>\n<p><strong>Important:<\/strong> the methods to retrieve data from the report only work if the report is embedded on the page. The last statement from the previous code cell, executing the object Report to embed the Power BI report, was really needed. This is a limitation, and I will talk more about this later.<\/p>\n<h3>Pages list and page name<\/h3>\n<p>Begin with the list of pages in a report. A new code cell is needed for that. The methods for this task are available from the report object.<\/p>\n<pre class=\"lang:none theme:none\">pages\u00a0=\u00a0report.get_pages()\r\npage_name=pages[0][\"name\"]\r\npages<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-91324\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/06\/word-image-31.png\" alt=\"code to get pages\" width=\"673\" height=\"278\" \/><\/p>\n<p>The first surprise is with the page: The name on the report is only the <em>displayName<\/em>. The real name of the page is something completely different, as you can see in the JSON returned.<\/p>\n<p>The code defines a variable with the actual page name. The display of the page list is only for interactive view.<\/p>\n<h3>Visuals list and name<\/h3>\n<p>Now that you have the page name, you can retrieve the list of visuals in the page.<\/p>\n<pre class=\"lang:none theme:none\">visuals\u00a0=\u00a0report.visuals_on_page(page_name)\r\nvisual_name=visuals[0][\"name\"]\r\nvisuals<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-91325\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/06\/word-image-32.png\" alt=\"code to get visuals\" width=\"539\" height=\"375\" \/><\/p>\n<p>The name of the visual is even more unpredictable than the name of the page. Once again, the script defines a variable to contain the name of the visual<\/p>\n<h3>Finally, the data<\/h3>\n<p>Joining the report, page and visual, now you can retrieve the data and transform it into a <strong>Pandas<\/strong> <strong>dataframe<\/strong>.<\/p>\n<p>The data returns as a big comma-separated string. The <strong>Read_CSV<\/strong> method requires a file or a buffer to transform a <strong>CSV<\/strong> in a <strong>dataframe<\/strong>. The <strong>STRINGIO<\/strong> method creates a buffer for a simple string, allowing conversion of the string to a <strong>dataframe<\/strong>.<\/p>\n<p>The code cell will be this:<\/p>\n<pre class=\"lang:none theme:none\">exported_data\u00a0=\u00a0report.export_visual_data(page_name,\u00a0visual_name,\u00a0rows=1000,\u00a0export_data_type=models.ExportDataType.UNDERLYING.value)\r\nexported_data=StringIO(exported_data)\r\ndf=pd.read_csv(exported_data,sep=\",\")\r\ndisplay(df)<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-91326\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/06\/word-image-33.png\" alt=\"data behind the report\" width=\"1383\" height=\"708\" \/><\/p>\n<p>Besides the parameters we already know, there are two additional ones:<\/p>\n<h3>Rows<\/h3>\n<p>This parameter defines the number of rows to be recovered. That\u2019s not good at all. The parameter is optional, but the default value is 10. This means we will need to know how many records there are in the underlying data, and that\u2019s impossible.<\/p>\n<p>Although it\u2019s possible to recover the data and make transformations on the data, this parameter makes the feature very limited.<\/p>\n<h3>Export_Data_Type<\/h3>\n<p>This parameter supports two values:<\/p>\n<p><strong>ExportDataType.SUMMARIZED:<\/strong> Returns the data summarized by the visual according to the visual work.<\/p>\n<p><strong>ExportDataType.UNDERLYING:<\/strong> Returns the underlying data in relation to the visual.<\/p>\n<h3>Transforming the data<\/h3>\n<p>From this point and forward, you can transform the data using function on <strong>Python<\/strong>, <strong>Pandas<\/strong> or other libraries. I made some examples of these possible transformations:<\/p>\n<pre class=\"lang:none theme:none\">df[\"Year\"]=\u00a0pd.DatetimeIndex(df['OrderDate']).year\r\ndf[\"Month\"]=pd.DatetimeIndex(df['OrderDate']).month\r\ndf2=df.groupby('Year')[\"SalesAmount\"].sum()\r\ndf3=\u00a0df[df.Year==2013].groupby('Month')[\"SalesAmount\"].sum()\r\ndf3<\/pre>\n<p>This code cell makes two different transformations:<\/p>\n<ul>\n<li>Group the data by <em>Year<\/em>, totalizing the <em>SalesAmount<\/em><\/li>\n<li>Filter the data by <em>Year<\/em> 2013, group by Month and totalize by <em>SalesAmount<\/em><\/li>\n<\/ul>\n<p>Two new columns were created in the <strong>dataframe<\/strong>, <em>Year<\/em> and <em>Month<\/em>, calculated from the <em>OrderDate<\/em> field.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-91327\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/06\/word-image-34.png\" alt=\"data aggregation\" width=\"714\" height=\"401\" \/><\/p>\n<p>From these two new <strong>dataframes, <\/strong>you can plot new graphics to analyze the data.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-91328\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/06\/word-image-35.png\" alt=\"analyze the data\" width=\"541\" height=\"476\" \/><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-91329\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/06\/word-image-36.png\" alt=\"analyze the data over the months\" width=\"670\" height=\"481\" \/><\/p>\n<h2>What comes next?<\/h2>\n<p>The questions persist: Why do we need <strong>Power BI<\/strong> inside <strong>Jupyter<\/strong> notebooks? How should we use this? If you have additional ideas about how to use this feature, I woutld love to hear about it. Let\u2019s talk; use the comment box on this blog.<\/p>\n<p>Now it\u2019s time to provide my guess. I made some correct guesses before; let\u2019s see if it works now.<\/p>\n<h2>My guess<\/h2>\n<p>This feature was intended for other purposes. It\u2019s being introduced in <strong>Jupyter<\/strong> notebooks because it\u2019s easy, and it\u2019s \u201cpop\u201d. However, we are struggling to understand how useful the feature is.<\/p>\n<p>It would be great to have access to datasets and dataflows, creating teamwork between <strong>Jupyter<\/strong> analysts and <strong>Power BI<\/strong> analysts. However, even retrieving data from the reports is not enough to retrieve the data and make further analysis.<\/p>\n<p>Let\u2019s support these two guesses.<\/p>\n<h3>The features are not enough to analyze data<\/h3>\n<p>Retrieving the data from the report visuals instead of datasets or dataflows is a considerable work-around or gambiarra.<\/p>\n<p>It\u2019s not possible to retrieve the data without embedding the report. This means the analysis of data more limited.<\/p>\n<p>The rows parameter makes any data analysis incomplete since you would need to guess the number of rows available.<\/p>\n<h3>Power BI Client has other purposes<\/h3>\n<ul>\n<li>The tool can add or remove filters to the report<\/li>\n<li>The tool can manage bookmarks<\/li>\n<li>Register callbacks on the report events, allowing an interaction between the report interactivity and whatever is around the embedded report<\/li>\n<\/ul>\n<p><strong>In Summary<\/strong>: These features are the beginning of great interactivity between the embedded report and any application where the report is embedded. Would this tool be handy for the creation of embedded reports on other kinds of Python applications? Do you have any idea about this? Please, let\u2019s talk more; use the comments to provide additional ideas.<\/p>\n<h2>Power BI in Jupyter Notebooks<\/h2>\n<p>The tool works, and it\u2019s very interesting, but after the dazzle, the result is the question: How should we use this tool in real scenarios?<\/p>\n<p>Besides that, the tool is open source. Could we adapt the tool to work the way we would like?<\/p>\n<h2>Reference Links<\/h2>\n<p><strong>Feature Announcement:<\/strong> <a href=\"https:\/\/powerbi.microsoft.com\/en-us\/blog\/announcing-power-bi-in-jupyter-notebooks\/?WT.mc_id=DP-MVP-4014132\">https:\/\/powerbi.microsoft.com\/en-us\/blog\/announcing-power-bi-in-jupyter-notebooks\/?WT.mc_id=DP-MVP-4014132<\/a><\/p>\n<p><strong>Github Documentation:<\/strong> <a href=\"https:\/\/github.com\/microsoft\/powerbi-jupyter\/wiki#Export-the-data-of-a-given-visual-of-the-report\">https:\/\/github.com\/microsoft\/powerbi-jupyter\/wiki#Export-the-data-of-a-given-visual-of-the-report<\/a><\/p>\n<p><strong>GitHub Open Code Repo:<\/strong> <a href=\"https:\/\/github.com\/microsoft\/powerbi-jupyter\">https:\/\/github.com\/microsoft\/powerbi-<strong>Jupyter<\/strong><\/a><\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Power BI and Jupyter Notebooks are popular tools, but you may have never thought about using them together. Dennes Torres demonstrates how to do that and also asks why.&hellip;<\/p>\n","protected":false},"author":50808,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[143528,159166],"tags":[143568,101611,5134],"coauthors":[6810],"class_list":["post-91314","post","type-post","status-publish","format-standard","hentry","category-bi-sql-server","category-powerbi","tag-jupyter-notebooks","tag-power-bi","tag-sql-prompt"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/91314","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/50808"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=91314"}],"version-history":[{"count":4,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/91314\/revisions"}],"predecessor-version":[{"id":91331,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/91314\/revisions\/91331"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=91314"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=91314"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=91314"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=91314"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}