Microsoft Fabric Updates Blog

Build a python app with Fabric API for GraphQL

Fabric API for GraphQL brings GraphQL experience within Fabric to securely and efficiently access the data in Fabric SQL Database, Warehouse or more.  GraphQL is an open-source query language for APIs and a runtime for fulfilling those queries with your existing data. It provides a complete and understandable description of the data in your API with a strongly typed system, giving clients the power to ask for exactly what they need and nothing more.

In this blog post, we will cover how to build a Python application using Flask framework to connect to Fabric SQL Database and query data.

Prerequisites

  1. You need a Microsoft Fabric account, if you don’t have one, sign up for free.
  2. Create Fabric SQL Database and add sample data.
  3. Create an API for GraphQL and connect to SQL database.
  4. Enable Service principal name for API for GraphQL.

Setting up the development environment

You can use the IDE of your choice, but for this blog post we will use Visual Studio Code.

  1. Create a folder for your project ‘myproject’.
  2. Download VS Code.
  3. Download Python latest version.
  4. Install the Python extension.
  5. Open this folder in VS Code.

Building the App

  1. Create Python virtual environment in this folder ‘myproject’.
  2. Create ‘requirements.txt’ file to include the dependencies.
azure-core==1.32.0
azure-identity==1.19.0
requests==2.32.3
Flask == 3.1.0
  1. Create file name ‘app.py’ for the Python application. Replace the ‘TENANTID’, ‘CLIENTID’, ‘CLIENTSECRET’ and ‘FABRIC_GRAPHQL_ENDPOINT’ for your Entra ID App registration. In this example, I’m using a GraphQL query to get first 5 customers and product descriptions from a table, and a view.
from flask import Flask, request, jsonify
from azure.identity import ClientSecretCredential
import requests
import json
from flask import Flask, jsonify, render_template
import os

app = Flask(__name__)

# Azure Service Principal credentials
TENANT_ID = os.environ["TENANTID"]
CLIENT_ID = os.environ["CLIENTID"]
CLIENT_SECRET = os.environ["CLIENTSECRET"]
FABRIC_API_SCOPE = "https://analysis.windows.net/powerbi/api/.default"
FABRIC_GRAPHQL_ENDPOINT = os.environ["FABRIC_GRAPHQL_ENDPOINT"]

# Authenticate using the Service Principal
credential = ClientSecretCredential(
    tenant_id=TENANT_ID,
    client_id=CLIENT_ID,
    client_secret=CLIENT_SECRET
)



@app.route("/")
def index():
   return render_template('index.html')


@app.route("/api/gql", methods=["POST"])
def run_graphql_query():
    """Send a GraphQL query to the Microsoft Fabric API."""
    try:
        # Get an access token
        token = credential.get_token(FABRIC_API_SCOPE)
        access_token = token.token

        # Get the GraphQL query from the request
        # Define a static GraphQL query
        query = """        
         query{
            customers(first: 5) {
               items {
                  CustomerID
                  FirstName
                  LastName
                  EmailAddress         
               }
            }
            vProductAndDescriptions {
               items {
                  ProductID
                  Name
                  Description
                  ProductModel       
               }
            }            
         }
      """

  
        # Send the GraphQL query to the Fabric API
        headers = {
            "Authorization": f"Bearer {access_token}",
            "Content-Type": "application/json"
        }
        response = requests.post(
            FABRIC_GRAPHQL_ENDPOINT,
            json={'query': query},
            headers=headers
        )

        # Return the response from the Fabric API
        return response.json(), response.status_code

    except Exception as e:
        return {"error": str(e)}, 500


if __name__ == "__main__":
    app.run(debug=True)
  1. Now it’s time to render the front end of the app. Create ‘templates’ folder, add index.html file and copy the example code.
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Customer Data</title>
</head>
<body>
    <h1>Customer Data</h1>
    <button id="send-btn">Get first 5 customers</button>
    <table id="customerTable" border="1" style="display: none;">
        <thead>
            <tr>
                <th>CustomerID</th>
                <th>FirstName</th>
                <th>LastName</th>
                <th>EmailAddress</th>
            </tr>
        </thead>
        <tbody>
            <!-- Data will be populated here -->
        </tbody>
    </table>
    <h1>Products and Descriptions</h1>
    <button id="product-btn">Get products and descriptions </button>
    <table id="productTable" border="1" style="display: none;">
        <thead>
            <tr>
                <th>ProductID</th>
                <th>Name</th>
                <th>Description</th>
                <th>ProductModel</th>
            </tr>
        </thead>
        <tbody>
            <!-- Data will be populated here -->
        </tbody>
    </table>
    
    <script>
        document.getElementById('send-btn').addEventListener('click', function()   {
            fetch('/api/gql')
                .then(response => response.json())
                .then(data => {
                    const table = document.getElementById('customerTable');
                    const tbody = table.querySelector('tbody');
                    tbody.innerHTML = ''; // Clear existing data

                    data.data.customers.items.forEach(customer => {
                        const row = document.createElement('tr');
                        row.innerHTML = `
                            <td>${customer.CustomerID}</td>
                            <td>${customer.FirstName}</td>
                            <td>${customer.LastName}</td>
                            <td>${customer.EmailAddress}</td>
                        `;
                        tbody.appendChild(row);
                    });

                    table.style.display = 'table'; // Show the table
                })
                .catch(error => console.error('Error fetching customer data:', error));
        });
        document.getElementById('product-btn').addEventListener('click', function() {
            fetch('/api/gql')
                .then(response => response.json())
                .then(data => {
                    const table = document.getElementById('productTable');
                    const tbody = table.querySelector('tbody');
                    tbody.innerHTML = ''; // Clear existing data

                    data.data.vProductAndDescriptions.items.forEach(product => {
                        const row = document.createElement('tr');
                        row.innerHTML = `
                            <td>${product.ProductID}</td>
                            <td>${product.Name}</td>
                            <td>${product.Description}</td>
                            <td>${product.ProductModel}</td>
                        `;
                        tbody.appendChild(row);
                    });

                    table.style.display = 'table'; // Show the table
                })
                .catch(error => console.error('Error fetching product data:', error));
        });
    </script>

</body>
</html>

Run the application locally. In the terminal in VS Code, run the following command ‘python app.py’. Open the link http://localhost:5000   to view in the browser.

Deploy the app

  1. Install Azure CLI to deploy the app to azure. If you don’t have an Azure subscription, try it for free.
  2. Open terminal in VS Code.
  3. Sign in to Azure using az login.
  4. Create the webapp and other resources, then deploy your code to Azure using az webapp up.
az webapp up --runtime PYTHON:3.11 --sku B1 --logsSelect the web app resource created and browse the application
  1. Use az webapp config appsettings  to configure CLIENTID, CLIENTSECRET and TENANTID and read it in the app as environment variables.
az webapp config appsettings set --name <your-webapp-name> --resource-group <your-resource-group> --settings CLIENTID=<your-client-id> CLIENTSECRET=<your-client-secret> TENANTID=<your-tenant-id> FABRIC_GRAPHQL_ENDPOINT=<your-fabric-api-for-graphql-endpoint>

Now test your application. Select any of the buttons to run the query and display the data you need. If you run into any issues, check the Application logs in diagnose and solve for your web app.

Conclusion

The blog post highlights how to get started building applications using API for GraphQL and Fabric SQL database. Although this is simple example to query data, you can build more complex applications where you need fast and secure data access with Fabric API for GraphQL APIs in your own projects. Checkout the training module for API for GraphQL as well to learn more.

Related blog posts

Build a python app with Fabric API for GraphQL

June 17, 2025 by Dan Liu

Have you ever found yourself frustrated by inconsistent item creation? Maybe you’ve struggled to select the right workspace or folder when creating a new item or ended up with a cluttered workspace due to accidental item creation. We hear you—and we’re excited to introduce the new item creation experience in Fabric! This update is designed … Continue reading “Introducing new item creation experience in Fabric”

June 12, 2025 by Ed Lima

Introduction Integrating Azure API Management (APIM) with Microsoft Fabric’s API for GraphQL can significantly enhance your API’s capabilities by providing robust scalability and security features such as identity management, rate limiting, and caching. This post will guide you through the process of setting up and configuring these features. You may not be familiar with API … Continue reading “Integrating Azure API Management with Fabric API for GraphQL”