Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save dgosbell/4cc2c459214961a8d308ae4a8cab7822 to your computer and use it in GitHub Desktop.
Save dgosbell/4cc2c459214961a8d308ae4a8cab7822 to your computer and use it in GitHub Desktop.
Update Tabular Model Descriptions from ChatGPT with rate limiting logic
#r "System.Net.Http"
using System.Net.Http;
using System.Text;
using Newtonsoft.Json.Linq;
// You need to signin to https://platform.openai.com/ and create an API key for your profile then paste that key
// into the apiKey constant below
const string apiKey = "<YOUR API KEY HERE>";
const string uri = "https://api.openai.com/v1/completions";
const string question = "Explain the following calculation in a few sentences in simple business terms without using DAX function names:\n\n";
const int oneMinute = 60000; // the number of milliseconds in a minute
const int apiLimit = 20; // a free account is limited to 20 calls per minute, change this if you have a paid account
const bool dontOverwrite = true; // this prevents existing descriptions from being overwritten
using (var client = new HttpClient()) {
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + apiKey);
int callCount = 0;
// if any measures are currently selected add those
// to our collection
List<Measure> myMeasures = new List<Measure>();
myMeasures.AddRange( Selected.Measures );
// if no measures were selected grab all of the
// measures in the model
if ( myMeasures.Count == 0)
{
myMeasures.AddRange(Model.Tables.Where(t => t.Measures.Count() > 0).SelectMany(t => t.Measures));
}
foreach ( var m in myMeasures)
{
// if we are not overwriting existing descriptions then skip to the
// next measure if this one is not an empty string
if (dontOverwrite && !string.IsNullOrEmpty(m.Description)) {continue; }
// Only uncomment the following when running from the command line or the script will
// show a popup after each measure
//Info("Processing " + m.DaxObjectFullName)
//var body = new requestBody() { prompt = question + m.Expression };
var body =
"{ \"prompt\": " + JsonConvert.SerializeObject(question + m.Expression ) +
",\"model\": \"gpt-3.5-turbo-instruct\" " +
",\"temperature\": 1 " +
",\"max_tokens\": 2048 " +
",\"stop\": \".\" }";
var res = client.PostAsync(uri, new StringContent(body, Encoding.UTF8,"application/json"));
res.Result.EnsureSuccessStatusCode();
var result = res.Result.Content.ReadAsStringAsync().Result;
var obj = JObject.Parse(result);
var desc = obj["choices"][0]["text"].ToString().Trim();
m.Description = desc + "\n=====\n" + m.Expression;
callCount++; // increment the call count
if ( callCount % apiLimit == 0) System.Threading.Thread.Sleep( oneMinute );
}
}
@dgosbell
Copy link
Author

dgosbell commented Mar 1, 2023

@chris1642 - I'm not sure if you can suggest changes to a gist like this one. But I've extended my script now to look for Selected.Measures and use those if any are selected, but if there are no measures selected it falls back to using all the measures in the model.

In theory this script should work with large numbers of measures, but it's really just a proof of concept, I have not done extensive testing on it. It really depends on what the errors are. If they are 500 server error or 429 too many requests, then that could be an OpenAI issue (since the script should be throttling itself to avoid 429 errors). If you have some extremely large measures, then you could possibly hit the token limit on the API. I think the 2048 tokens limit relates to the number of tokens (words and punctuation) in BOTH the request and response. If you hit the token limit I don't think there is much we can do as 2048 is the maximum the API currently allows. I know that Azure has also just released and Azure OpenAI offering, I have not looked into whether that has different limits in this area.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment