mirror of
https://github.com/microsoft/vscode.git
synced 2026-08-20 16:23:02 +01:00
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
13 KiB
13 KiB
In [ ]:
import os
import requests
import json
import pandas as pd
import plotly.express as px
import plotly.graph_objects as go
import ipywidgets as widgets
from IPython.display import display, HTML
from IPython.display import clear_outputIn [ ]:
GITHUB_TOKEN = os.getenv('GITHUB_TOKEN')
GITHUB_TOKEN = input("Enter Github Token") if GITHUB_TOKEN is None else GITHUB_TOKEN
os.environ['GITHUB_TOKEN'] = GITHUB_TOKEN
if GITHUB_TOKEN is None or GITHUB_TOKEN == '':
raise ValueError("Please set your GITHUB_TOKEN")
REPO = 'microsoft/vscode-jupyter' # Replace with your repository
pd.set_option('display.max_rows', 100)
pd.set_option('display.min_rows', 100)
pd.set_option("display.max_rows", 100, "display.max_columns", 100)
In [ ]:
url = 'https://api.github.com/graphql'
headers = {'Authorization': f'bearer {GITHUB_TOKEN}'}
query = '''
query ($repo_owner: String!, $repo_name: String!, $cursor: String) {
repository(owner: $repo_owner, name: $repo_name) {
issues(first: 100, after: $cursor, states: OPEN) {
pageInfo {
endCursor
hasNextPage
}
nodes {
number
title
createdAt
author {
avatarUrl
login
}
reactions{
totalCount
}
labels(first: 10) {
nodes {
name
}
}
assignees(first: 4) {
nodes {
avatarUrl
login
}
}
comments(last:1) {
nodes {
author {
avatarUrl
login
}
createdAt
lastEditedAt
}
}
}
}
}
}'''
variables = {
'repo_owner': REPO.split('/')[0],
'repo_name': REPO.split('/')[1],
'cursor': None
}
all_issues = []
while True:
response = requests.post(url, headers=headers, json={'query': query, 'variables': variables})
data = response.json()
issues = data['data']['repository']['issues']['nodes']
all_issues.extend(issues)
page_info = data['data']['repository']['issues']['pageInfo']
if not page_info['hasNextPage']:
break
variables['cursor'] = page_info['endCursor']In [ ]:
def get_issue_type(labels):
if 'bug' in labels:
return 'bug'
elif 'feature-request' in labels:
return 'feature-request'
elif 'debt' in labels:
return 'debt'
else:
return 'other'
issue_details = []
for issue in all_issues:
try:
author = 'ghost' if issue['author'] is None else issue['author']['login']
authorAvatarUrl = 'https://avatars.githubusercontent.com/u/10137?v=4' if issue['author'] is None else issue['author']['avatarUrl']
issue_details.append({
'id': f'<a href="http://github.com/{REPO}/issues/{issue['number']}">{issue['number']}</a>',
'reactions': issue['reactions']['totalCount'],
'title': issue['title'],
'_': f'<a href="https://github.com/{author}"><img height="20" width="20" src="{authorAvatarUrl}"></a>',
'Author': f'<a href="https://github.com/{author}">{author}</a>',
'labels': ', '.join([label['name'] for label in issue['labels']['nodes']]),
'Created': pd.to_datetime(issue['createdAt']).strftime("%Y-%m-%d"),
'Updated': None if len(issue['comments']['nodes']) == 0 else pd.to_datetime(issue['comments']['nodes'][0]['createdAt']).strftime("%Y-%m-%d"),
'AssignedTo': ' '.join([f'<a href="https://github.com/{assignee['avatarUrl']}"><img height="20" width="20" src="{assignee['avatarUrl']}"></a>' for assignee in issue['assignees']['nodes']]),
'type': get_issue_type([label['name'] for label in issue['labels']['nodes']]),
'assignees': ', '.join([assignee['login'] for assignee in issue['assignees']['nodes']]),
'labels_list': list([label['name'] for label in issue['labels']['nodes']])
})
except Exception as e:
print(issue)
raise e
break
print(f"Total issues: {len(issue_details)}")
df = pd.DataFrame(issue_details)
In [ ]:
from itables import init_notebook_mode, show
import itables.options as opt
init_notebook_mode(all_interactive=True)
opt.showIndex = False
opt.keys = True
opt.column_filters = "footer"
opt.columnDefs = [
{
"targets": [10, 11],
"visible": False
},
{"className": "dt-left", "targets": "_all", "visible": True},
]
def highlight_cells(val):
color = 'red' if 'bug' in val else 'blue'
color = 'green' if 'feature-request' in val else color
color = 'purple' if 'debt' in val else color
return f'background-color: {color}'
def display_issue_df(df):
df = df.style.map(highlight_cells, subset=['type'])
show(df,
fixedColumns={"start": 1, "end": 2},
scrollX=True,
search={"caseInsensitive": True},
scrollCollapse=True,
scrollY="400px",
paging=False,
buttons=["copyHtml5", "csvHtml5", "excelHtml5"],
layout={"topStart": "search", "topEnd": "buttons"},
select=True
)In [ ]:
# Create a dropdown widget with unique labels
unique_labels = set(label for labels in df['labels'] for label in labels.split(', '))
unique_assignees = set(assignee for assignees in df['assignees'] for assignee in assignees.split(', '))
assignees = widgets.Dropdown(options=sorted(unique_assignees), description='Assignee:')
assignee_issues = df
out = widgets.Output()
labels = widgets.SelectMultiple(
options=sorted(list(unique_labels)),
value=sorted(list(unique_labels)),
description='Labels',
disabled=False
)
def build_labels():
issues = df
lables_list = list(set(sum(issues['labels_list'].tolist(), [])))
labels.options = lables_list
labels.value = lables_list
labels.selected_labels = lables_list
def update_pie_chart():
assignee = assignees.value
out.clear_output(wait=True)
global assignee_issues
assignee_issues = df[df['assignees'].isin([assignee])]
assignee_issues = assignee_issues[assignee_issues['labels_list'].apply(lambda x: len(list(set(x) & set(labels.value))) > 0)]
total_rows = assignee_issues.shape[0]
if total_rows == 0:
with out:
print(f"No issues found for assignee '{assignee}' with labels {labels.value}")
return
label_counts = assignee_issues['type'].value_counts()
fig = px.pie(
values=label_counts.values,
names=label_counts.index,
color=label_counts.index,
title=f'{total_rows} Issues grouped by types for "{assignee}"',
color_discrete_map={'bug':'red',
'feature-request':'green',
'debt':'purple',
'other':'blue'}
)
with out:
display(fig)
display_issue_df(assignee_issues)
def dropdown_eventhandler(change):
update_pie_chart()
def labels_eventhandler(change):
update_pie_chart()
assignees.observe(dropdown_eventhandler, names='value')
build_labels()
display(assignees)
display(out)
update_pie_chart()In [ ]:
issue_types = ["bug", "feature-request", "debt", "other"]
issue_type_dropdown = widgets.Dropdown(options=sorted(issue_types), description='Type:')
filtered_df = assignee_issues
out2 = widgets.Output()
def update_issues_pie_chart(issue_type):
out2.clear_output(wait=True)
if issue_type == 'other':
filtered_df = assignee_issues[~assignee_issues['type'].str.contains('bug|feature-request|debt')]
else:
filtered_df = assignee_issues[assignee_issues['type'].str.contains(issue_type)]
total_rows = filtered_df.shape[0]
def exclude_types(labels):
if labels is None:
return ''
value = ','.join([label for label in labels.split(', ') if label not in ['bug', 'debt', 'feature-request']])
if value is None or value == '':
return ''
return value
filtered_df.loc[:, 'labels'] = filtered_df['labels'].apply(lambda x: exclude_types(x))
label_counts = filtered_df['labels'].str.split(',').explode().value_counts()
fig = px.pie(values=label_counts.values, names=label_counts.index, title=f'{total_rows} {issue_type} grouped by labels')
with out2:
display(fig)
display_issue_df(filtered_df)
def issue_type_dropdown_eventhandler(change):
update_issues_pie_chart(change.new)
issue_type_dropdown.observe(issue_type_dropdown_eventhandler, names='value')
display(issue_type_dropdown)
display(out2)
update_issues_pie_chart(issue_type_dropdown.value)