backup LUIS applications
This commit is contained in:
Родитель
704517e583
Коммит
708682b11a
|
@ -0,0 +1 @@
|
|||
node_modules
|
|
@ -0,0 +1,234 @@
|
|||
// This file takes a programmatic key and returns all information for all
|
||||
// applications associated with that key except for querylog.
|
||||
//
|
||||
|
||||
const request = require("requestretry");
|
||||
const async = require('async');
|
||||
const fs = require('fs-extra');
|
||||
const moment = require('moment');
|
||||
const path = require("path");
|
||||
|
||||
// Change to your programmatic key
|
||||
const programmaticKey = "PROGRAMMATIC KEY";
|
||||
|
||||
// time delay between requests
|
||||
const delayMS = 500;
|
||||
|
||||
// retry recount
|
||||
const retry = 5;
|
||||
|
||||
// retry reqeust if error or 429 received
|
||||
var retryStrategy = function (err, response, body) {
|
||||
let shouldRetry = err || (response.statusCode === 429);
|
||||
if (shouldRetry) console.log("retry");
|
||||
return shouldRetry;
|
||||
}
|
||||
|
||||
// HTTP REQUEST - get list of apps associated with programmatic key
|
||||
var appListRequest = function (done) {
|
||||
|
||||
let requestOptions = {
|
||||
method: "GET",
|
||||
url: "https://westus.api.cognitive.microsoft.com/luis/api/v2.0/apps?take=500",
|
||||
headers: {
|
||||
"Ocp-Apim-Subscription-Key": programmaticKey
|
||||
},
|
||||
maxAttempts: retry,
|
||||
retryDelay: delayMS,
|
||||
retryStrategy: retryStrategy
|
||||
};
|
||||
|
||||
request(requestOptions, function (err, response, body) {
|
||||
if (err || response.statusCode != 200) done();
|
||||
done({ apps: JSON.parse(response.body) });
|
||||
});
|
||||
}
|
||||
|
||||
// build HTTP URL list
|
||||
// get list of all app infos for all apps in appList
|
||||
// NOT organized by app, that will be done in fixAppList
|
||||
var appListInfosUrls = (appList, done) => {
|
||||
var urls = [];
|
||||
|
||||
appList.apps.forEach(app => {
|
||||
|
||||
console.log("app " + app.name);
|
||||
|
||||
urls.push({ name: app.name, appId: app.id, "Ocp-Apim-Subscription-Key": programmaticKey, route: "appInfo", url: ("https://westus.api.cognitive.microsoft.com/luis/api/v2.0/apps/" + app.id) });
|
||||
urls.push({ name: app.name, appId: app.id, "Ocp-Apim-Subscription-Key": programmaticKey, route: "versions", url: ("https://westus.api.cognitive.microsoft.com/luis/api/v2.0/apps/" + app.id + "/versions?take=500") });
|
||||
urls.push({ name: app.name, appId: app.id, "Ocp-Apim-Subscription-Key": programmaticKey, route: "settings", url: ("https://westus.api.cognitive.microsoft.com/luis/api/v2.0/apps/" + app.id + "/settings") });
|
||||
urls.push({ name: app.name, appId: app.id, "Ocp-Apim-Subscription-Key": programmaticKey, route: "endpoints", url: ("https://westus.api.cognitive.microsoft.com/luis/api/v2.0/apps/" + app.id + "/endpoints") });
|
||||
});
|
||||
done(urls);
|
||||
}
|
||||
|
||||
// HTTP Request - get app info such as settings or endpoints
|
||||
// result is put back into 'eachUrlObj'
|
||||
var appInfoRequest = function (eachUrlObj, done) {
|
||||
|
||||
console.log("request app " + eachUrlObj.url + ' ' + new moment().format("HH:mm:ss"));
|
||||
|
||||
let requestOptions = {
|
||||
method: "GET",
|
||||
url: eachUrlObj.url,
|
||||
headers: {
|
||||
"Ocp-Apim-Subscription-Key": programmaticKey
|
||||
},
|
||||
maxAttempts: retry,
|
||||
retryDelay: delayMS,
|
||||
retryStrategy: retryStrategy
|
||||
};
|
||||
request(requestOptions, function (error, response, body) {
|
||||
|
||||
if (error || response.statusCode != 200) done();
|
||||
console.log("response app " + response.request.href + " " + response.statusCode);
|
||||
|
||||
let json = JSON.parse(body);
|
||||
let route = response.request.href.substr(response.request.href.lastIndexOf('/') + 1).replace('?take=500', '');
|
||||
|
||||
let myresponse = {
|
||||
appId: eachUrlObj.appId,
|
||||
route: route,
|
||||
name: eachUrlObj.name,
|
||||
url: response.request.href,
|
||||
status: response.statusCode,
|
||||
body: json
|
||||
};
|
||||
|
||||
// put response back into object
|
||||
eachUrlObj[route] = {
|
||||
response: myresponse,
|
||||
status: response.statusCode
|
||||
};
|
||||
|
||||
// not returning anything because response is inside eachUrlObj now
|
||||
done();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
// HTTP Request - get app version info for each version in app
|
||||
// result is put back into 'eachUrlObj'
|
||||
var appInfoVersionRequest = function (eachUrlObj, done) {
|
||||
|
||||
console.log("request version " + eachUrlObj.version + ' ' + new moment().format("HH:mm:ss"));
|
||||
|
||||
let requestOptions = {
|
||||
method: "GET",
|
||||
url: eachUrlObj.url,
|
||||
headers: {
|
||||
"Ocp-Apim-Subscription-Key": eachUrlObj["Ocp-Apim-Subscription-Key"]
|
||||
},
|
||||
maxAttempts: retry,
|
||||
retryDelay: delayMS,
|
||||
retryStrategy: retryStrategy
|
||||
};
|
||||
request(requestOptions, function (error, response, body) {
|
||||
|
||||
console.log("response version " + response.request.href + " " + response.statusCode);
|
||||
|
||||
// not returning anything because response is inside eachUrlObj now
|
||||
eachUrlObj.response = JSON.parse(body);
|
||||
eachUrlObj.responseStatus = response.statusCode;
|
||||
done();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
// build HTTP URL list to get all version infos for app
|
||||
let getVersionUrlsForThisApp = (progKey, appName, appId, versionList, done) => {
|
||||
let versionUrls = []
|
||||
versionList.forEach(version => {
|
||||
versionUrls.push({ "Ocp-Apim-Subscription-Key": progKey, name: appName, id: appId, version: version.version, info: JSON.parse(JSON.stringify(version)), url: `https://westus.api.cognitive.microsoft.com/luis/api/v2.0/apps/${appId}/versions/${version.version}/export` });
|
||||
});
|
||||
done(versionUrls);
|
||||
}
|
||||
|
||||
// http request - in series
|
||||
// don't call done until they are all returned
|
||||
let getVersionInfos = (appUrls, versionUrls, done) => {
|
||||
async.eachSeries(versionUrls, appInfoVersionRequest, (versionsResponse) => {
|
||||
done(versionsResponse);
|
||||
});
|
||||
}
|
||||
|
||||
// put app infos children into main JSON object in right spot
|
||||
var fixAppList = (appList, children) => {
|
||||
|
||||
appList.forEach(app => {
|
||||
var properties = children.filter(x => x.appId === app.id);
|
||||
var bodies = properties.map(x => {
|
||||
let info = {};
|
||||
if (x.route === "appInfo") {
|
||||
info = { route: "appInfo", values: x[x.appId].response.body };
|
||||
} else {
|
||||
info = { route: x.route, values: x[x.route].response.body };
|
||||
}
|
||||
return info;
|
||||
});
|
||||
app.properties = bodies;
|
||||
});
|
||||
}
|
||||
|
||||
// put version infos children into main JSON object in right spot
|
||||
var fixVersionList = (appList, children) => {
|
||||
appList.forEach(app => {
|
||||
var versionsList = children.filter(x => x.id === app.id);
|
||||
var bodies = versionsList.map(x => x.response);
|
||||
app.properties.push({ route: "versionExports", values: bodies });
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
// main function
|
||||
// appUrls is the final JSON that is tweaked as the program progresses
|
||||
appListRequest((appUrls) => {
|
||||
|
||||
// build app info url array
|
||||
appListInfosUrls(appUrls, (appInfoUrls) => {
|
||||
|
||||
// request all app infos, when all returned and done, then proceed
|
||||
async.eachSeries(appInfoUrls, appInfoRequest, (response) => {
|
||||
|
||||
// each info is in array but not organized by app
|
||||
var appChildrenRoutes = JSON.parse(JSON.stringify(appInfoUrls));
|
||||
|
||||
// get each app's infos
|
||||
var appVersionInfoResponses = appChildrenRoutes.filter(x => x.route === "versions");
|
||||
|
||||
// organize app infos back into app's spot in final JSON
|
||||
fixAppList(appUrls.apps, appChildrenRoutes);
|
||||
|
||||
// get version infos, an app can have more than one version
|
||||
// this array will have all version info urls, not organized by app
|
||||
// that organizatio will be done in fixVersionList
|
||||
let versionUrls = [];
|
||||
appVersionInfoResponses.forEach(app => {
|
||||
let listOfVersionsForThisApp = app.versions.response.body;
|
||||
getVersionUrlsForThisApp(programmaticKey, app.name, app.appId, listOfVersionsForThisApp, (appVersionUrls) => {
|
||||
versionUrls.push(...appVersionUrls);
|
||||
});
|
||||
});
|
||||
|
||||
// request all version infos, when all returned and done, then proceed
|
||||
getVersionInfos(appUrls, versionUrls, (versionsResponse) => {
|
||||
|
||||
// organize version infos back into app's spot in final JSON
|
||||
fixVersionList(appUrls.apps, versionUrls);
|
||||
|
||||
// write to file including programmatic key at top of JSON
|
||||
fs.writeFile(path.join(__dirname, "backup.json"), JSON.stringify({ programmaticKey: programmaticKey, apps: appUrls.apps }), "utf-8")
|
||||
.then(() => {
|
||||
console.log("done");
|
||||
}).catch(err => { console.log(err); });
|
||||
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"name": "LUIS-backup",
|
||||
"version": "1.0.0",
|
||||
"description": "Backup all LUIS applications for given programmatic key",
|
||||
"main": "backup.js",
|
||||
"scripts": {
|
||||
"start": "node backup.js"
|
||||
},
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"async": "^2.5.0",
|
||||
"fs-extra": "^4.0.2",
|
||||
"moment": "^2.19.1",
|
||||
"request": "^2.83.0",
|
||||
"requestretry": "^1.12.2",
|
||||
"underscore": "^1.8.3"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
# Backup all apps
|
||||
This Node.js file backups up all your LUIS apps:
|
||||
- settings
|
||||
- endpoints
|
||||
- versions
|
||||
|
||||
## Prerequisites
|
||||
- Lastest version of Node.js.
|
||||
- Install dependencies from package.json with `npm install`
|
||||
- In the backup.js file, change to programmaticKey to your own key.
|
||||
|
||||
## Run backup
|
||||
- From command line, `npm start' or 'node backup.js'
|
||||
|
||||
## Review backup
|
||||
**backup.json** is a json tree structure of each app with the information about each app.
|
Загрузка…
Ссылка в новой задаче