Introdução
Use o Pontos de extremidade da API REST para as métricas do Copilot para ver tendências de como os usuários estão adotando o GitHub Copilot. Durante uma distribuição do GitHub Copilot, é útil exibir essas tendências para verificar se as pessoas estão usando as respectivas licenças atribuídas, ver quais recursos as pessoas estão usando e entender o efeito do plano de habilitação da sua empresa para os desenvolvedores.
A API inclui:
- Dados dos últimos 28 dias
- Número de usuários ativos e usuários envolvidos
- Detalhamentos por linguagem e IDE
- A opção de exibir métricas de uma empresa, organização ou equipe
Se você usa o Pontos de extremidade da API REST para métricas de uso do GitHub Copilot, recomendamos migrar para o Pontos de extremidade da API REST para as métricas do Copilot o quanto antes.
Este guia demonstra como consultar a API, armazenar dados e analisar uma tendência de alterações no número de usuários por semana. Os exemplos neste guia usam o ponto de extremidade de uma organização, mas você pode adaptá-los para atender às suas necessidades.
Sobre a disponibilidade de pontos de extremidade
Pontos de extremidade ficam disponíveis para a obtenção de dados para uma empresa, organização, equipe da organização ou equipe empresarial.
- Se você tem uma assinatura do GitHub Copilot Business ou GitHub Copilot Enterprise como parte de uma organização ou empresa regular, pode usar os pontos de extremidade para uma empresa, uma organização ou uma equipe da organização. Você não tem acesso a equipes empresariais, a menos que esteja registrado em uma versão prévia.
- Se você usa uma empresa dedicada para o GitHub Copilot Business — uma conta empresarial sem a capacidade de criar organizações —, pode usar os pontos de extremidade para uma empresa ou uma equipe empresarial.
Pré-requisitos
- A política de acesso à API de métricas do Copilot deve ser habilitada para sua empresa ou organização. Confira Gerenciar políticas do Copilot na sua organização ou Gerenciando políticas e recursos do Copilot em sua empresa.
- A organização, a empresa ou a equipe que você está consultando precisa ter usuários ativos suficientes do Copilot. A API só retornará os resultados de um determinado dia se houver cinco ou mais membros com licenças ativas do Copilot para esse dia.
- Neste exemplo, criaremos um script JavaScript para consultar e analisar os dados. Para executar esse script localmente, você precisa instalar o Node.js e, em seguida, instalar o SDK do Octokit.js com
npm install -g octokit
.
1. Criar um personal access token
Para nosso exemplo, para obter métricas para uma organização, criaremos um personal access token (classic) com o escopo manage_billing:copilot
. Confira Gerenciar seus tokens de acesso pessoal.
Se você estiver usando outro ponto de extremidade, talvez precise de escopos diferentes. Confira Pontos de extremidade da API REST para as métricas do Copilot.
2. Conectar-se à API
Chamaremos a API de um script e salvaremos a resposta como uma variável. Em seguida, podemos armazenar os dados externamente e analisar tendências neles.
O exemplo a seguir usa o cliente Octokit para JavaScript. Você pode usar outros métodos para chamar a API, como cURL ou GitHub CLI.
Exemplo
Neste exemplo:
- Substituir YOUR_TOKEN por personal access token.
- Substituir YOUR_ORG pelo nome de sua organização, como
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();
Executar o script localmente
Para testar o script localmente, salve o arquivo como copilot.mjs
e execute node copilot.mjs
.
Important
O tipo de arquivo .mjs é importante. A instrução import { Octokit }
pode não funcionar com um arquivo .js
comum.
Em seu terminal, você deverá ver uma saída com uma matriz JSON semelhante à seguinte.
[
{
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. Armazenar os dados
Para analisar tendências ao longo de mais de 28 dias, você precisará:
- Chamar a API diariamente, usando um trabalho cron ou um fluxo de trabalho agendado do GitHub Actions.
- Armazenar dados localmente ou com um serviço de banco de dados como MySQL.
- Consultar os dados para identificar tendências ao longo do tempo.
Exemplo
Neste exemplo, salvaremos os dados em um arquivo .json
local. Para fazer isso, importaremos alguns módulos para trabalhar com arquivos e atualizaremos a função orgMetrics
para salvar os dados de resposta.
A função salva novos dados que são retornados a cada dia, sem substituir dados antigos no arquivo.
Novas etapas são anotadas em negrito.
// 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();
Executar o script localmente
Depois de executar o script com node copilot.mjs
, você deve ter um novo arquivo em seu diretório chamado copilotMetricsData.json
. O arquivo deve conter dados da resposta da API.
Se você executar o script novamente amanhã, ele deverá salvar apenas dados de um novo dia no arquivo.
4. Analisar tendências
Você pode trabalhar com os dados da API para identificar tendências ao longo dos últimos 28 dias ou, se tiver armazenado dados de chamadas à API anteriores, por um período mais longo.
Exemplo
No exemplo a seguir, atualizamos a função orgMetrics
para extrair o número total e médio de usuários ativos e engajados por semana. Em seguida, podemos usar esses dados para controlar alterações ao longo do tempo. Este exemplo usa os dados retornados diretamente da API e não requer dados armazenados.
Novas etapas são anotadas em negrito.
// 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);
}
Executar o script localmente
Depois de executar o script com node copilot.mjs
, você deverá ver a saída no terminal da maneira indicada a seguir.
{
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'
}
}