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
- You need a Microsoft Fabric account, if you don’t have one, sign up for free.
- Create Fabric SQL Database and add sample data.
- Create an API for GraphQL and connect to SQL database.
- 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.
- Create a folder for your project ‘myproject’.
- Download VS Code.
- Download Python latest version.
- Install the Python extension.
- Open this folder in VS Code.
Building the App
- Create Python virtual environment in this folder ‘myproject’.
- 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
- 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)
- 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
- Install Azure CLI to deploy the app to azure. If you don’t have an Azure subscription, try it for free.
- Open terminal in VS Code.
- Sign in to Azure using az login.
- 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
- 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.