Skip to content

Instantly share code, notes, and snippets.

@mminer
Last active August 29, 2015 13:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mminer/8871352 to your computer and use it in GitHub Desktop.
Save mminer/8871352 to your computer and use it in GitHub Desktop.
Exports a GitHub repository's issues to CSV format.
#!/usr/bin/env python
"""Exports a GitHub repository's issues to CSV format."""
from __future__ import print_function
import argparse
import csv
import getpass
import requests
API_URL = 'https://api.github.com/repos/{0}/issues'
HEADER_ROW = ('ID', 'Title', 'Body', 'Created At', 'Updated At')
FIELDS = ('number', 'title', 'body', 'created_at', 'updated_at')
def export_issues(repository, username, password, state):
"""Requests issues from GitHub and exports them to CSV."""
filename = '{0}-issues.csv'.format(repository).replace('/', '-')
url = API_URL.format(repository)
auth = (username, password)
params = {'state': state}
with open(filename, 'wb') as csvfile:
writer = csv.writer(csvfile)
writer.writerow(HEADER_ROW)
export_issues_page(writer, url, auth, params)
print('Exported CSV file to', filename)
def export_issues_page(writer, url, auth, params):
"""Recursively gets pages of issues until there are no more."""
response = requests.get(url, auth=auth, params=params)
response.raise_for_status()
for issue in response.json():
row = [unicode(issue[field]).encode('utf-8') for field in FIELDS]
writer.writerow(row)
if 'next' in response.links:
export_issues_page(writer, response.links['next']['url'], auth, params)
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='GitHub issues to CSV.')
parser.add_argument('repository', help='repository in username/repo form')
parser.add_argument('--github-username', dest='username')
parser.add_argument('--github-password', dest='password')
parser.add_argument('--issues-state', dest='state', default='open')
args = parser.parse_args()
# If username and password weren't supplied, ask for them.
if not args.username:
args.username = raw_input('GitHub username: ')
if not args.password:
args.password = getpass.getpass('GitHub password: ')
export_issues(args.repository, args.username, args.password, args.state)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment