Skip to content

Instantly share code, notes, and snippets.

@bjulius
Created September 28, 2024 00:24
Show Gist options
  • Save bjulius/77eaf15909c1050a6da7d9fb5c2351cf to your computer and use it in GitHub Desktop.
Save bjulius/77eaf15909c1050a6da7d9fb5c2351cf to your computer and use it in GitHub Desktop.
C# TE3 script to add measure name, measure description/purpose, and DAX code to the measure tooltip for each measure in a selected table
// C# TE3 script to add measure name, measure description/purpose, and DAX code to the measure tooltip for each measure in a selected table
// developed by Brian Julius, Sep 27, 2024
string apiKey = System.Environment.GetEnvironmentVariable("OPEN_AI_TE3_API_KEY");
if (string.IsNullOrEmpty(apiKey))
{
Error("API key not found in environment variable 'OPEN_AI_TE3_API_KEY'.");
return;
}
var selectedTable = Selected.Table;
if (selectedTable == null)
{
Error("Please select a table.");
return;
}
var client = new System.Net.Http.HttpClient();
client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", apiKey);
client.BaseAddress = new Uri("https://api.openai.com/");
foreach (var measure in selectedTable.Measures)
{
// Build the prompt
string prompt = $@"
Analyze the following DAX measure and provide its purpose.
Keep the total response under 100 tokens.
DAX Measure:
{measure.Name} =
{measure.Expression}
Provide the output in the following format:
Purpose: <Brief purpose of the measure>
";
// Build the request body
var requestBody = new
{
model = "gpt-4o-mini",
messages = new[]
{
new { role = "system", content = "You are an expert in DAX measures and Power BI." },
new { role = "user", content = prompt }
},
max_tokens = 100,
temperature = 0.3
};
// Serialize the request body to JSON
string jsonBody = Newtonsoft.Json.JsonConvert.SerializeObject(requestBody);
// Create the content
var content = new System.Net.Http.StringContent(jsonBody, System.Text.Encoding.UTF8, "application/json");
try
{
// Send the POST request
var response = client.PostAsync("/v1/chat/completions", content).Result;
if (response.IsSuccessStatusCode)
{
// Read the response content
var responseContent = response.Content.ReadAsStringAsync().Result;
// Parse the JSON response
var responseJson = Newtonsoft.Json.Linq.JObject.Parse(responseContent);
// Extract the generated text
var generatedText = responseJson["choices"][0]["message"]["content"].ToString().Trim();
// Construct the Description metadata with blank lines
string descriptionText = $@"
Name of Measure: {measure.Name}
{generatedText}
Code:
{measure.Expression}
";
// Set the measure's description
measure.Description = descriptionText.Trim();
Output($"Description set for measure: {measure.Name}");
}
else
{
// Handle error
Output($"Failed to get description for measure: {measure.Name}. Status Code: {response.StatusCode}");
var errorContent = response.Content.ReadAsStringAsync().Result;
Output($"Error: {errorContent}");
}
}
catch (Exception ex)
{
Output($"Exception occurred for measure: {measure.Name}. Error: {ex.Message}");
}
// Optional: Delay between requests to respect rate limits
System.Threading.Thread.Sleep(1000); // Sleep for 1 second
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment