Введение
Вы можете использовать Конечные точки REST API для метрик Copilot для просмотра тенденций в том, как пользователи принимают GitHub Copilot. Во время развертывания GitHub Copilot, полезно просмотреть эти тенденции, чтобы проверить, используют ли пользователи свои назначенные лицензии, просмотрите, какие функции используют пользователи, и понять влияние плана включения вашей компании на разработчиков.
API включает в себя следующие функции:
- Данные за последние 28 дней
- Количество активных пользователей и заинтересованных пользователей
- Разбивки по языку и интегрированной среде разработки
- Параметр просмотра метрик для предприятия, организации или команды
Если в настоящее время используется [AUTOTITLE, рекомендуется перейти в Конечные точки REST API для метрик использования GitHub Copilot](/rest/copilot/copilot-metrics) как можно скорее.
В этом руководстве показано, как запрашивать API, хранить данные и анализировать тенденцию изменения количества пользователей в неделю. Примеры в этом руководстве используют конечную точку для организации, но вы можете адаптировать примеры в соответствии с вашими потребностями.
Сведения о доступности конечных точек
Конечные точки доступны для получения данных для организации, организации, команды организации или команды предприятия на GitHub.com.
- Если у вас есть подписка GitHub Copilot Business или GitHub Copilot Enterprise в рамках обычной организации или предприятия, можно использовать конечные точки для предприятия, организации или группы организации. У вас нет доступа к корпоративным командам, если вы не зарегистрированы в предварительной версии.
- Если вы используете выделенное предприятие для GitHub Copilot Business— учетная запись предприятия без возможности создания организаций, можно использовать конечные точки для предприятия или корпоративной команды.
Note
Конечные точки метрик Copilot недоступны для GitHub Enterprise Cloud с размещением данных на GHE.com.
Необходимые компоненты
- Политика доступа к API метрик Copilot должна быть включена для вашей организации или предприятия. См[. раздел AUTOTITLE или Управление политиками для Copilot в организации](/enterprise-cloud@latest/copilot/managing-copilot/managing-copilot-for-your-enterprise/managing-policies-and-features-for-copilot-in-your-enterprise).
- У организации, предприятия или команды, за которыми запрашивают запросы, должно быть достаточно активных пользователей Copilot. API возвращает результаты только в течение заданного дня, если в этот день есть пять или более членов с активными лицензиями Copilot .
- В этом примере мы создадим скрипт JavaScript для запроса и анализа данных. Чтобы запустить этот скрипт локально, необходимо установить [Node.js, а затем установить пакет SDK Octokit.js](https://nodejs.org/en).`npm install -g octokit`
1. Создание personal access token
В нашем примере для получения метрик для организации мы создадим personal access token (classic) с областью manage_billing:copilot
. См . раздел AUTOTITLE.
Если вы используете другую конечную точку, может потребоваться другая область. См . раздел AUTOTITLE.
2. Подключение к API
Мы вызовем API из скрипта и сохраните ответ в качестве переменной. Затем мы можем хранить данные внешне и анализировать тенденции в данных.
В следующем примере используется клиент Octokit для JavaScript. Вы можете использовать другие методы для вызова API, например cURL или GitHub CLI.
Пример
В этом примере:
- Замените YOUR_TOKEN данными personal access token.
- Замените YOUR_ORG именем организации, например
octo-org
.
// Import Octokit import { Octokit } from "octokit"; // Set your token and organization const octokit = new Octokit({ auth: 'YOUR_TOKEN' }); const org = 'YOUR_ORG'; // Set other variables if required for the endpoint you're using /* const team = 'YOUR_TEAM'; const enterprise = 'YOUR_ENTERPRISE'; const entTeam = 'YOUR_ENTERPRISE_TEAM'; */ // Call the API async function orgMetrics() { const resp = await octokit.request(`GET /orgs/${org}/copilot/metrics`, { org: 'ORG', headers: { 'X-GitHub-Api-Version': '2022-11-28' } }); const copilotUsage = resp.data; console.log(copilotUsage); } // Call the function orgMetrics();
import { Octokit } from "octokit";
Import Octokit
const octokit = new Octokit({
auth: 'YOUR_TOKEN'
});
const org = 'YOUR_ORG';
Set your token and organization
/*
const team = 'YOUR_TEAM';
const enterprise = 'YOUR_ENTERPRISE';
const entTeam = 'YOUR_ENTERPRISE_TEAM';
*/
Set other variables if required for the endpoint you're using
async function orgMetrics() {
const resp = await octokit.request(`GET /orgs/${org}/copilot/metrics`, {
org: 'ORG',
headers: {
'X-GitHub-Api-Version': '2022-11-28'
}
});
const copilotUsage = resp.data;
console.log(copilotUsage);
}
Call the API
orgMetrics();
Call the function
// Import Octokit
import { Octokit } from "octokit";
// Set your token and organization
const octokit = new Octokit({
auth: 'YOUR_TOKEN'
});
const org = 'YOUR_ORG';
// Set other variables if required for the endpoint you're using
/*
const team = 'YOUR_TEAM';
const enterprise = 'YOUR_ENTERPRISE';
const entTeam = 'YOUR_ENTERPRISE_TEAM';
*/
// Call the API
async function orgMetrics() {
const resp = await octokit.request(`GET /orgs/${org}/copilot/metrics`, {
org: 'ORG',
headers: {
'X-GitHub-Api-Version': '2022-11-28'
}
});
const copilotUsage = resp.data;
console.log(copilotUsage);
}
// Call the function
orgMetrics();
Локальный запуск скрипта
Чтобы протестировать скрипт локально, сохраните файл как copilot.mjs
, а затем выполните команду node copilot.mjs
.
Important
Важный тип файла MJS . Инструкция import { Octokit }
может не работать с обычным .js
файлом.
В терминале вы увидите выходные данные с массивом JSON, как показано ниже.
[
{
date: '2024-11-07',
copilot_ide_chat: { editors: [Array], total_engaged_users: 14 },
total_active_users: 28,
copilot_dotcom_chat: { models: [Array], total_engaged_users: 4 },
total_engaged_users: 28,
copilot_dotcom_pull_requests: { total_engaged_users: 0 },
copilot_ide_code_completions: { editors: [Array], total_engaged_users: 22 }
},
...
3. Хранение данных
Чтобы проанализировать тенденции более чем за 28 дней, вам потребуется:
- Ежедневно вызывайте API с помощью задания cron или запланированного рабочего процесса GitHub Actions .
- Храните данные локально или с помощью службы базы данных, например MySQL.
- Запрос данных для определения тенденций с течением времени.
Пример
В этом примере данные будут сохранены в локальный .json
файл. Для этого мы импортируем некоторые модули для работы с файлами и обновим orgMetrics
функцию для сохранения данных ответа.
Функция сохраняет новые данные, возвращаемые каждый день, без перезаписи старых данных в файле.
Новые шаги помечены полужирным шрифтом.
// Import Octokit import { Octokit } from "octokit"; // **Import modules for working with files** import path from 'path'; import fs from 'fs'; import { fileURLToPath } from 'url'; import { dirname } from 'path'; // **Declare variables for working with files** const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); // Set your token and organization const octokit = new Octokit({ auth: 'YOUR_TOKEN' }); const org = 'YOUR_ORG'; // Call the API async function orgMetrics() { const resp = await octokit.request(`GET /orgs/${org}/copilot/metrics`, { org: 'ORG', headers: { 'X-GitHub-Api-Version': '2022-11-28' } }); const copilotUsage = resp.data; // **Define the path to the local file where data will be stored** const dataFilePath = path.join(__dirname, 'copilotMetricsData.json'); // **Read existing data from the file, if it exists** let existingData = []; if (fs.existsSync(dataFilePath)) { const fileContent = fs.readFileSync(dataFilePath, 'utf8'); existingData = JSON.parse(fileContent); } // **Filter out the new data that is not already in the existing data** const newData = copilotUsage.filter(entry => !existingData.some(existingEntry => existingEntry.date === entry.date)); // **Append new data to the existing data** if (newData.length > 0) { existingData = existingData.concat(newData); // **Save the updated data back to the file** fs.writeFileSync(dataFilePath, JSON.stringify(existingData, null, 2)); console.log(`Saved ${newData.length} new entries.`); } else { console.log('No new data to save.'); } } // Call the function orgMetrics();
import { Octokit } from "octokit";
Import Octokit
import path from 'path';
import fs from 'fs';
import { fileURLToPath } from 'url';
import { dirname } from 'path';
Import modules for working with files
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
Declare variables for working with files
const octokit = new Octokit({
auth: 'YOUR_TOKEN'
});
const org = 'YOUR_ORG';
Set your token and organization
async function orgMetrics() {
const resp = await octokit.request(`GET /orgs/${org}/copilot/metrics`, {
org: 'ORG',
headers: {
'X-GitHub-Api-Version': '2022-11-28'
}
});
const copilotUsage = resp.data;
Call the API
const dataFilePath = path.join(__dirname, 'copilotMetricsData.json');
Define the path to the local file where data will be stored
let existingData = [];
if (fs.existsSync(dataFilePath)) {
const fileContent = fs.readFileSync(dataFilePath, 'utf8');
existingData = JSON.parse(fileContent);
}
Read existing data from the file, if it exists
const newData = copilotUsage.filter(entry => !existingData.some(existingEntry => existingEntry.date === entry.date));
Filter out the new data that is not already in the existing data
if (newData.length > 0) {
existingData = existingData.concat(newData);
Append new data to the existing data
fs.writeFileSync(dataFilePath, JSON.stringify(existingData, null, 2));
console.log(`Saved ${newData.length} new entries.`);
} else {
console.log('No new data to save.');
}
}
Save the updated data back to the file
orgMetrics();
Call the function
// Import Octokit
import { Octokit } from "octokit";
// **Import modules for working with files**
import path from 'path';
import fs from 'fs';
import { fileURLToPath } from 'url';
import { dirname } from 'path';
// **Declare variables for working with files**
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
// Set your token and organization
const octokit = new Octokit({
auth: 'YOUR_TOKEN'
});
const org = 'YOUR_ORG';
// Call the API
async function orgMetrics() {
const resp = await octokit.request(`GET /orgs/${org}/copilot/metrics`, {
org: 'ORG',
headers: {
'X-GitHub-Api-Version': '2022-11-28'
}
});
const copilotUsage = resp.data;
// **Define the path to the local file where data will be stored**
const dataFilePath = path.join(__dirname, 'copilotMetricsData.json');
// **Read existing data from the file, if it exists**
let existingData = [];
if (fs.existsSync(dataFilePath)) {
const fileContent = fs.readFileSync(dataFilePath, 'utf8');
existingData = JSON.parse(fileContent);
}
// **Filter out the new data that is not already in the existing data**
const newData = copilotUsage.filter(entry => !existingData.some(existingEntry => existingEntry.date === entry.date));
// **Append new data to the existing data**
if (newData.length > 0) {
existingData = existingData.concat(newData);
// **Save the updated data back to the file**
fs.writeFileSync(dataFilePath, JSON.stringify(existingData, null, 2));
console.log(`Saved ${newData.length} new entries.`);
} else {
console.log('No new data to save.');
}
}
// Call the function
orgMetrics();
Локальный запуск скрипта
После выполнения скрипта node copilot.mjs
с именем должен быть новый файл в каталоге copilotMetricsData.json
. Файл должен содержать данные из ответа API.
При повторном запуске скрипта завтра он должен сохранять данные только для одного нового дня в файл.
4. Анализ тенденций
Вы можете работать с данными из API, чтобы определить тенденции за последние 28 дней или, если вы сохранили данные из предыдущих вызовов API за более длительный период.
Пример
В следующем примере мы обновим orgMetrics
функцию, чтобы извлечь общее и среднее количество активных и занятых пользователей в неделю. Затем мы могли бы использовать эти данные для отслеживания изменений с течением времени. В этом примере данные, возвращаемые непосредственно из API, используются и не требуются хранимые данные.
Новые шаги помечены полужирным шрифтом.
// Call the API async function orgMetrics() { const resp = await octokit.request(`GET /orgs/${org}/copilot/metrics`, { org: 'ORG', headers: { 'X-GitHub-Api-Version': '2022-11-28' } }); const copilotUsage = resp.data; // **Create an object to store data for each week** let userTrends ={ week1: { days:0, activeUsers:0, engagedUsers:0, }, week2: { days:0, activeUsers:0, engagedUsers:0, }, week3: { days:0, activeUsers:0, engagedUsers:0, }, week4: { days:0, activeUsers:0, engagedUsers:0, }, }; // **Iterate over the data** for (let i =0; i<copilotUsage.length; i++) { // **Determine the week number (1-4) based on the index** const week = Math.ceil((i+1)/7); // **Increment userTrends for the current week** userTrends[`week${week}`].days += 1; userTrends[`week${week}`].activeUsers += copilotUsage[i].total_active_users; userTrends[`week${week}`].engagedUsers += copilotUsage[i].total_engaged_users; } // **Calculate the average number of active and engaged users per day for each week, rounded to two decimal places** for (const week in userTrends) { userTrends[week].avgActiveUsers = (userTrends[week].activeUsers / userTrends[week].days).toFixed(2); userTrends[week].avgEngagedUsers = (userTrends[week].engagedUsers / userTrends[week].days).toFixed(2); } // Output to the console console.log(userTrends); }
async function orgMetrics() {
const resp = await octokit.request(`GET /orgs/${org}/copilot/metrics`, {
org: 'ORG',
headers: {
'X-GitHub-Api-Version': '2022-11-28'
}
});
const copilotUsage = resp.data;
Call the API
let userTrends ={
week1: {
days:0,
activeUsers:0,
engagedUsers:0,
},
week2: {
days:0,
activeUsers:0,
engagedUsers:0,
},
week3: {
days:0,
activeUsers:0,
engagedUsers:0,
},
week4: {
days:0,
activeUsers:0,
engagedUsers:0,
},
};
Create an object to store data for each week
for (let i =0; i<copilotUsage.length; i++) {
Iterate over the data
const week = Math.ceil((i+1)/7);
Determine the week number (1-4) based on the index
userTrends[`week${week}`].days += 1;
userTrends[`week${week}`].activeUsers += copilotUsage[i].total_active_users;
userTrends[`week${week}`].engagedUsers += copilotUsage[i].total_engaged_users;
}
Increment userTrends for the current week
for (const week in userTrends) {
userTrends[week].avgActiveUsers = (userTrends[week].activeUsers / userTrends[week].days).toFixed(2);
userTrends[week].avgEngagedUsers = (userTrends[week].engagedUsers / userTrends[week].days).toFixed(2);
}
Calculate the average number of active and engaged users per day for each week, rounded to two decimal places
console.log(userTrends);
}
Output to the console
// Call the API
async function orgMetrics() {
const resp = await octokit.request(`GET /orgs/${org}/copilot/metrics`, {
org: 'ORG',
headers: {
'X-GitHub-Api-Version': '2022-11-28'
}
});
const copilotUsage = resp.data;
// **Create an object to store data for each week**
let userTrends ={
week1: {
days:0,
activeUsers:0,
engagedUsers:0,
},
week2: {
days:0,
activeUsers:0,
engagedUsers:0,
},
week3: {
days:0,
activeUsers:0,
engagedUsers:0,
},
week4: {
days:0,
activeUsers:0,
engagedUsers:0,
},
};
// **Iterate over the data**
for (let i =0; i<copilotUsage.length; i++) {
// **Determine the week number (1-4) based on the index**
const week = Math.ceil((i+1)/7);
// **Increment userTrends for the current week**
userTrends[`week${week}`].days += 1;
userTrends[`week${week}`].activeUsers += copilotUsage[i].total_active_users;
userTrends[`week${week}`].engagedUsers += copilotUsage[i].total_engaged_users;
}
// **Calculate the average number of active and engaged users per day for each week, rounded to two decimal places**
for (const week in userTrends) {
userTrends[week].avgActiveUsers = (userTrends[week].activeUsers / userTrends[week].days).toFixed(2);
userTrends[week].avgEngagedUsers = (userTrends[week].engagedUsers / userTrends[week].days).toFixed(2);
}
// Output to the console
console.log(userTrends);
}
Локальный запуск скрипта
После выполнения скрипта node copilot.mjs
в терминале вы увидите выходные данные, как показано ниже.
{
week1: {
days: 7,
activeUsers: 174,
engagedUsers: 174,
avgActiveUsers: '24.86',
avgEngagedUsers: '24.86'
},
week2: {
days: 7,
activeUsers: 160,
engagedUsers: 151,
avgActiveUsers: '22.86',
avgEngagedUsers: '21.57'
},
week3: {
days: 7,
activeUsers: 134,
engagedUsers: 123,
avgActiveUsers: '19.14',
avgEngagedUsers: '17.57'
},
week4: {
days: 6,
activeUsers: 143,
engagedUsers: 132,
avgActiveUsers: '23.83',
avgEngagedUsers: '22.00'
}
}