# Cancelling Dataflow Gen2 Refresh

**Update : Mar 8, 2024**

As of March 8, you can cancel the Fabric Dataflow Gen2 refresh in service using UI:

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1709917006833/ae0cc48b-31c8-41be-8788-464644a2e0b4.png align="center")

**Programmatically cancel the refresh:**

DFg2 can be resource intensive, and if the refresh takes longer than expected, it may consume a significant amount of CUs. Thankfully, you can use the Power BI Rest API to cancel it programmatically. My friend [Alex Powers](https://itsnotaboutthecell.com/about/) already has a [PowerShell script](https://github.com/itsnotaboutthecell/PowerBI-cmdlets/blob/master/CancelDataflow.ps1) that you can use. You can also use the [Power BI VS Code extension](https://marketplace.visualstudio.com/items?itemName=GerhardBrueckl.powerbi-vscode) by Gerhard Brueckl.

But I would like to show you how you can do this using the PowerBIRestClient in the latest version of Semantic-Link (v0.5.0). The API is similar to the FabricRestClient I blogged about [in my last blog](https://fabric.guru/using-fabricrestclient-to-make-fabric-rest-api-calls). The new version has many updates I love and I will write about it soon. But in the meantime, checkout the [official documentation](https://learn.microsoft.com/en-us/python/api/semantic-link-sempy/sempy.fabric?view=semantic-link-python?wt.mc_id=MVP_335074) for the details.

In the below code:

* I first get the list of all the dataflows in a workspace using the [Get Dataflows API](https://learn.microsoft.com/en-us/rest/api/power-bi/dataflows/get-dataflows?wt.mc_id=MVP_335074). You can pass either the workspace name or id. By default, the workspace id of the workspace hosting the notebook is used.
    
* For each dataflow, get the transaction id and the status of the dataflow using [Get Dataflow Transactions API](https://learn.microsoft.com/en-us/rest/api/power-bi/dataflows/get-dataflow-transactions?wt.mc_id=MVP_335074).
    
* Cancel the refresh, using the [Cancel Dataflow Transaction API](https://learn.microsoft.com/en-us/rest/api/power-bi/dataflows/cancel-dataflow-transaction?wt.mc_id=MVP_335074)
    

Semantic Link makes calling APIs very easy. Authentication is handled automatically for you so no need to generate a token.

```python
# Install semantic-link >= 0.5.0
!pip install semantic-link --q

import pandas as pd
import sempy.fabric as fabric
from sempy.fabric.exceptions import FabricHTTPException

# Instantiate the client
client = fabric.PowerBIRestClient()

def get_dataflow_transactions(workspace_id, dataflow_id):
    try:
        response = client.get(f"v1.0/myorg/groups/{workspace_id}/dataflows/{dataflow_id}/transactions")
        
        if response.status_code != 200:
            raise FabricHTTPException(response)
            return pd.DataFrame()

        transactions = response.json().get('value', [])
        if not transactions:
            return pd.DataFrame([{'status': 'No Status', 'transaction': 'No Transaction ID', 'refreshType': 'None'}])

        first_transaction = transactions[0]
        return pd.DataFrame([{
            'status': first_transaction['status'],
            'transaction': first_transaction['id'],
            'refreshType': first_transaction['refreshType']
        }])
    except Exception as e:
        print("Error getting transactions. Check workspace, dataflow id:", e)
        return pd.DataFrame()

def get_dataflows(workspace):
    try:
        workspace_id = fabric.resolve_workspace_id(workspace)
    except Exception as e:
        print("Check workspace name/id:", e)
        return pd.DataFrame()

    try:
        response = client.get(f"v1.0/myorg/groups/{workspace_id}/dataflows")
        if response.status_code != 200:
            raise FabricHTTPException(response)
            return pd.DataFrame()

        dataflows = response.json().get('value', [])
        dataflow_df = (pd.json_normalize(dataflows, max_level=1)
                       .rename(columns={"name": "dataflowName", "objectId": "dataflowID"})
                       .dropna()
                       .reset_index(drop=True))
        result = dataflow_df.join(dataflow_df.apply(lambda x: get_dataflow_transactions(workspace_id, x['dataflowID']).iloc[0], axis=1))
        return result
    except Exception as e:
        print("Error in get_dataflows:", e)
        return pd.DataFrame()
        

def cancel_dataflow(workspace, transaction_id):
    """
    Cancel a specific dataflow transaction.
    """
    try:
        workspace_id = fabric.resolve_workspace_id(workspace)
        response = client.post(f"v1.0/myorg/groups/{workspace_id}/dataflows/transactions/{transaction_id}/cancel")
        if response.status_code != 200:
            raise FabricHTTPException(response)
            return None

        return response.json()
    except Exception as e:
        print("Error:", e)
        return None
```

**Example:**

Get dataflow transactions:

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1705001126429/97630ce9-0cf8-48cc-9224-3af913f73ad5.png align="center")

Cancel the dataflow:

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1705001240364/88907d67-0cba-4ac1-837a-6da5772d22e1.png align="center")

<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">As I mentioned in my last blog, you should use the FabricRestClient for calling the Fabric API endpoints and PowerBIRestClient for the Power BI APIs. Hopefully in the future, both will merge and only one will be needed.</div>
</div>

<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text"><strong>Tip:</strong> If you need to run a DFg2 with heavy transformations, run it in a pipeline so you can set the timeout and cancel the pipeline run instead.</div>
</div>

This was one example . You can use this client to call any Power BI Rest endpoint and make GET, POST requests. If you are new to Python, note that the actual code is just a couple of lines, majority is for error/exception handling to make it robust. I love Semantic Link, and it's becoming indispensable day by day.
