Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save tholder/aa7650b4d2b77782a666c75a99c3c2dc to your computer and use it in GitHub Desktop.
Save tholder/aa7650b4d2b77782a666c75a99c3c2dc to your computer and use it in GitHub Desktop.
Export Issues from Github repo to CSV (API v3)
"""
Exports Issues from a specified repository to a CSV file
Uses basic authentication (Github username + password) to retrieve Issues
from a repository that username has access to. Supports Github API v3.
"""
import csv
import requests
import icu #to install CFLAGS=-I/usr/local/opt/icu4c/include LDFLAGS=-L/usr/local/opt/icu4c/lib pip install pyicu
GITHUB_USER = ''
GITHUB_PASSWORD = ''
REPO = '' # format is username/repo
ISSUES_FOR_REPO_URL = 'https://api.github.com/repos/%s/issues' % REPO
LABELS_FOR_REPO_URL = 'https://api.github.com/repos/%s/labels' % REPO
MILESTONE_FOR_REPO_URL = 'https://api.github.com/repos/%s/milestones' % REPO
AUTH = (GITHUB_USER, GITHUB_PASSWORD)
def write_issues(response, labels):
"output a list of issues to csv"
if not r.status_code == 200:
raise Exception(r.status_code)
for issue in r.json():
issueLabels = issue['labels']
issueLabelsStatus = []
for label in labels:
s = "No"
for il in issueLabels:
if il['name'] == label:
s = "Yes"
break
issueLabelsStatus.append(s)
if not 'pull_request' in issue:
row = [issue['number'],
'' if issue['assignee'] == None else issue['assignee']['login'],
issue['title'].encode('utf-8'),
issue['body'].encode('utf-8'),
'' if issue['milestone'] == None else issue['milestone']['title'],
issue['url'],
issue['created_at'],
issue['updated_at']]
csvout.writerow(row + issueLabelsStatus)
def get_labels(response):
"get labels"
labels = []
if not response.status_code == 200:
raise Exception(r.status_code)
for label in response.json():
labels.append(label['name'])
return sorted(labels)
def write_milestones(response):
"output a list of milestones to csv"
if not r.status_code == 200:
raise Exception(r.status_code)
for milestone in r.json():
row = [milestone[u'title'].encode('utf-8'),
milestone[u'state'].encode('utf-8'),
'' if milestone['due_on'] == None else milestone['due_on'],
milestone[u'description'].encode('utf-8'),
milestone[u'url'].encode('utf-8')]
csvout.writerow(row)
labels = requests.get(LABELS_FOR_REPO_URL, auth=AUTH)
labels = get_labels(labels)
r = requests.get(ISSUES_FOR_REPO_URL, auth=AUTH)
csvfile = '%s-issues.csv' % (REPO.replace('/', '-'))
csvout = csv.writer(open(csvfile, 'wb'))
headers = ['ID', 'Asignee', 'Title', 'Body', 'Milestone', 'Url', 'Created At', 'Updated At']
csvout.writerow(headers + labels)
write_issues(r, labels)
#more pages? examine the 'link' header returned
if 'link' in r.headers:
pages = dict(
[(rel[6:-1], url[url.index('<')+1:-1]) for url, rel in
[link.split(';') for link in
r.headers['link'].split(',')]])
while 'last' in pages and 'next' in pages:
r = requests.get(pages['next'], auth=AUTH)
write_issues(r, labels)
if pages['next'] == pages['last']:
break
r = requests.get(MILESTONE_FOR_REPO_URL, auth=AUTH)
csvfile = '%s-milestones.csv' % (REPO.replace('/', '-'))
csvout = csv.writer(open(csvfile, 'wb'))
headers = ['Title', 'State', 'Due On', 'Description', 'Url']
csvout.writerow(headers)
write_milestones(r)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment