-
-
Save dgosbell/4cc2c459214961a8d308ae4a8cab7822 to your computer and use it in GitHub Desktop.
#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 ); | |
} | |
} |
@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.
Not 100% sure how to suggest an edit - I did a fork to see it there as well....but here is an update that gives the option to only run on selected measures and not the entire model. Ours kept giving me errors - my assumption being that the model is too large (2,000+ measures).
#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";
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);
}