Use pyquery-ql.py with files to find most recent issues

Send a graphql query to GitHub and work with files for reports.

Supports Python 3.6+

In [22]:
import csv
import json
import os
import pprint

import requests
In [23]:
# get api token and set authorization
api_token = os.environ['GITHUB_API_TOKEN']
headers = {'Authorization': f'token {api_token}'}
In [24]:
# set url to a graphql endpoint
url = 'https://api.github.com/graphql'
In [80]:
# add a json query
query = """
{
  organization(login: "jupyterhub") {
    repositories(first: 30) {
      nodes {
        name
        issueConnection(first: 4) {
          nodes {
            number
            title
            createdAt
          }
        }
      }
    }
  }
}
"""
In [81]:
# submit the request
r = requests.post(url=url, json={'query': query}, headers=headers)
In [82]:
result = r.json()
result
Out[82]:
{'data': None,
 'errors': [{'locations': [{'column': 9, 'line': 7}],
   'message': "Field 'issueConnection' doesn't exist on type 'Repository'"}]}
In [33]:
import pandas as pd
In [52]:
repos = (pd.DataFrame(result['data']['organization']['repositories']['nodes'], columns=['name','issues'])).copy()
In [53]:
repos
Out[53]:
name issues
0 jupyterhub {'nodes': [{'number': 2, 'title': 'use sqlalch...
1 configurable-http-proxy {'nodes': [{'number': 1, 'title': 'Query by la...
2 oauthenticator {'nodes': [{'number': 8, 'title': 'GithubOAuth...
3 dockerspawner {'nodes': [{'number': 2, 'title': 'Docker layo...
4 sudospawner {'nodes': [{'number': 1, 'title': 'SudoSpawner...
5 batchspawner {'nodes': [{'number': 3, 'title': 'Implement t...
6 kubespawner {'nodes': [{'number': 1, 'title': 'Add a defau...
7 ldapauthenticator {'nodes': [{'number': 1, 'title': 'Support res...
8 jupyterhub-deploy-docker {'nodes': [{'number': 6, 'title': 'Problem wit...
9 jupyterhub-deploy-teaching {'nodes': [{'number': 5, 'title': 'Update cook...
10 jupyterhub-tutorial {'nodes': [{'number': 2, 'title': 'Update and ...
11 jupyterhub-deploy-hpc {'nodes': [{'number': 2, 'title': 'Add a jetst...
12 systemdspawner {'nodes': [{'number': 1, 'title': 'Update url ...
13 wrapspawner {'nodes': [{'number': 1, 'title': 'Migrate wra...
14 jupyterlab-hub {'nodes': [{'number': 2, 'title': 'Unable to i...
15 nbserverproxy {'nodes': [{'number': 1, 'title': 'Make it a s...
16 jupyterhub-example-kerberos {'nodes': [{'number': 2, 'title': 'Detailed st...
17 hubshare {'nodes': [{'number': 6, 'title': 'implement s...
18 nbrsessionproxy {'nodes': [{'number': 1, 'title': 'Are session...
19 tmpauthenticator {'nodes': [{'number': 3, 'title': 'Update LICE...
20 zero-to-jupyterhub-k8s {'nodes': [{'number': 1, 'title': 'Add initial...
21 helm-chart {'nodes': [{'number': 1, 'title': 'Allow custo...
22 binderhub {'nodes': [{'number': 1, 'title': 'Add a READM...
23 mybinder.org-deploy {'nodes': [{'number': 2, 'title': 'What is thi...
24 binder {'nodes': [{'number': 3, 'title': 'Discuss nom...
25 nullauthenticator {'nodes': []}
26 team-compass {'nodes': [{'number': 1, 'title': 'Use this re...
In [57]:
issues = pd.DataFrame(repos, columns=['number', 'title', 'createdAt'])
In [58]:
issues
Out[58]:
number title createdAt
0 NaN NaN NaN
1 NaN NaN NaN
2 NaN NaN NaN
3 NaN NaN NaN
4 NaN NaN NaN
5 NaN NaN NaN
6 NaN NaN NaN
7 NaN NaN NaN
8 NaN NaN NaN
9 NaN NaN NaN
10 NaN NaN NaN
11 NaN NaN NaN
12 NaN NaN NaN
13 NaN NaN NaN
14 NaN NaN NaN
15 NaN NaN NaN
16 NaN NaN NaN
17 NaN NaN NaN
18 NaN NaN NaN
19 NaN NaN NaN
20 NaN NaN NaN
21 NaN NaN NaN
22 NaN NaN NaN
23 NaN NaN NaN
24 NaN NaN NaN
25 NaN NaN NaN
26 NaN NaN NaN

Make request and create json and csv files

In [15]:
# create a json file from response
with open('data.json', 'w') as f:
    json.dump(r.json(), f)
In [16]:
r.json()
Out[16]:
{'data': {'organization': {'repositories': {'nodes': [{'issues': {'nodes': [{'createdAt': '2014-08-18T18:00:47Z',
         'number': 2,
         'title': 'use sqlalchemy ORM for state'},
        {'createdAt': '2014-08-18T18:01:57Z',
         'number': 3,
         'title': 'make get_current_user async'},
        {'createdAt': '2014-08-18T18:02:32Z',
         'number': 4,
         'title': 'make process launching configurable'},
        {'createdAt': '2014-08-18T18:05:21Z',
         'number': 5,
         'title': 'make authentication configurable'}]},
      'name': 'jupyterhub'},
     {'issues': {'nodes': [{'createdAt': '2014-09-17T13:43:28Z',
         'number': 1,
         'title': 'Query by last activity API'},
        {'createdAt': '2014-10-23T23:13:22Z',
         'number': 18,
         'title': 'Sockets ballooning proportionally to the number of websockets opened by clients.'},
        {'createdAt': '2014-11-12T02:32:31Z',
         'number': 19,
         'title': '"prepend path" option doesn\'t work properly'},
        {'createdAt': '2015-04-21T16:42:29Z',
         'number': 23,
         'title': 'host routing'}]},
      'name': 'configurable-http-proxy'},
     {'issues': {'nodes': [{'createdAt': '2015-07-25T02:07:48Z',
         'number': 8,
         'title': 'GithubOAuthenticator gets 403'},
        {'createdAt': '2015-08-22T16:07:32Z',
         'number': 15,
         'title': 'Ubuntu users should use pip3 and python3'},
        {'createdAt': '2015-10-08T20:29:25Z',
         'number': 18,
         'title': 'delete CILogon staged certificate'},
        {'createdAt': '2015-11-29T21:33:52Z',
         'number': 21,
         'title': 'Add a MediawikiOAuthenticator'}]},
      'name': 'oauthenticator'},
     {'issues': {'nodes': [{'createdAt': '2014-09-27T21:08:00Z',
         'number': 2,
         'title': 'Docker layout'},
        {'createdAt': '2014-11-11T22:18:26Z',
         'number': 7,
         'title': 'jupyterhub_config.py'},
        {'createdAt': '2015-02-24T12:02:35Z',
         'number': 19,
         'title': 'Use `inspect_container` instead of `containers` for polling.'},
        {'createdAt': '2015-03-06T06:40:37Z',
         'number': 23,
         'title': '500 / 404 error on using docker spawner'}]},
      'name': 'dockerspawner'},
     {'issues': {'nodes': [{'createdAt': '2015-05-29T17:19:13Z',
         'number': 1,
         'title': "SudoSpawner & 'No JSON object could be decoded'"},
        {'createdAt': '2015-06-30T18:10:20Z',
         'number': 2,
         'title': 'Call to IPython.utils.traitlets'},
        {'createdAt': '2015-08-04T17:26:20Z',
         'number': 4,
         'title': 'Broken link in README'},
        {'createdAt': '2015-08-13T18:21:24Z',
         'number': 6,
         'title': 'User Server Will Not Restart'}]},
      'name': 'sudospawner'},
     {'issues': {'nodes': [{'createdAt': '2016-02-24T22:45:18Z',
         'number': 3,
         'title': 'Implement testing'},
        {'createdAt': '2016-07-02T18:23:41Z',
         'number': 8,
         'title': 'use new traits api'},
        {'createdAt': '2016-07-06T20:28:09Z',
         'number': 9,
         'title': 'Using sudo but preserving needed environment variables'},
        {'createdAt': '2016-07-06T20:40:14Z',
         'number': 10,
         'title': 'Specifying queue via config file'}]},
      'name': 'batchspawner'},
     {'issues': {'nodes': [{'createdAt': '2016-03-08T03:22:53Z',
         'number': 1,
         'title': 'Add a default health check for the pods'},
        {'createdAt': '2016-03-09T13:06:08Z',
         'number': 2,
         'title': 'Documentation and Contribution'},
        {'createdAt': '2016-03-11T14:47:38Z',
         'number': 3,
         'title': 'Return statement inside a generator error'},
        {'createdAt': '2016-04-05T16:26:34Z',
         'number': 5,
         'title': 'Sometimes pods spawn but wrong state returned to JupyterHub'}]},
      'name': 'kubespawner'},
     {'issues': {'nodes': [{'createdAt': '2016-01-22T02:22:31Z',
         'number': 1,
         'title': 'Support restricting login to members of certain groups only'},
        {'createdAt': '2016-01-22T02:23:04Z',
         'number': 2,
         'title': 'Set jupyterhub userid to be the same as uid from LDAP'},
        {'createdAt': '2016-01-22T02:53:19Z',
         'number': 3,
         'title': 'Validate username to protect against LDAP injection attacks'},
        {'createdAt': '2016-01-23T01:29:47Z',
         'number': 4,
         'title': 'Change username_template to bind_dn'}]},
      'name': 'ldapauthenticator'},
     {'issues': {'nodes': [{'createdAt': '2016-05-04T20:28:01Z',
         'number': 6,
         'title': 'Problem with running/authenticating on an EC2 (AWS) machine and checking right cert/key files used'},
        {'createdAt': '2016-05-30T12:10:49Z',
         'number': 15,
         'title': 'github oauth'},
        {'createdAt': '2016-07-31T01:40:33Z',
         'number': 16,
         'title': 'Starting container with HostConfig removed in Docker 1.12 - extra_start_kwargs fails'},
        {'createdAt': '2016-08-18T04:21:52Z',
         'number': 19,
         'title': 'How to spawn user container with DOCKER_NOTEBOOK_DIR '}]},
      'name': 'jupyterhub-deploy-docker'},
     {'issues': {'nodes': [{'createdAt': '2016-04-19T05:17:09Z',
         'number': 5,
         'title': 'Update cookie secret in docs'},
        {'createdAt': '2016-04-27T15:00:57Z',
         'number': 12,
         'title': 'Update docs to reflect changes in PR #10 and #11'},
        {'createdAt': '2016-06-07T02:40:51Z',
         'number': 13,
         'title': 'cannot install superviser '},
        {'createdAt': '2016-08-13T23:38:11Z',
         'number': 20,
         'title': 'Anaconda path issue'}]},
      'name': 'jupyterhub-deploy-teaching'},
     {'issues': {'nodes': [{'createdAt': '2016-05-17T14:05:30Z',
         'number': 2,
         'title': 'Update and add links for jupyterhub-tutorial notebook'},
        {'createdAt': '2016-07-16T17:58:33Z',
         'number': 4,
         'title': 'Add headings to timeline.md'},
        {'createdAt': '2016-10-21T10:45:51Z',
         'number': 10,
         'title': 'Annotate Intro in timeline.md'},
        {'createdAt': '2016-10-21T10:49:07Z',
         'number': 11,
         'title': 'Annotate Overview in timeline.md'}]},
      'name': 'jupyterhub-tutorial'},
     {'issues': {'nodes': [{'createdAt': '2017-01-16T15:48:32Z',
         'number': 2,
         'title': 'Add a jetstream instance for jupyterhub'},
        {'createdAt': '2017-07-12T19:22:28Z',
         'number': 3,
         'title': 'xsede_oauthenticator --> jupyterhub/oauthenticator ?'}]},
      'name': 'jupyterhub-deploy-hpc'},
     {'issues': {'nodes': [{'createdAt': '2016-09-22T04:34:22Z',
         'number': 1,
         'title': 'Update url in setup.py'},
        {'createdAt': '2016-09-24T08:38:47Z',
         'number': 3,
         'title': 'Add installation instructions to README'},
        {'createdAt': '2016-09-24T08:38:58Z',
         'number': 4,
         'title': 'Add configuration documentation to README'},
        {'createdAt': '2016-09-24T08:39:46Z',
         'number': 5,
         'title': 'Write a configuration checker that ensures that appropriate kernel settings are enabled'}]},
      'name': 'systemdspawner'},
     {'issues': {'nodes': [{'createdAt': '2016-09-21T21:52:28Z',
         'number': 1,
         'title': 'Migrate wrapspawner to this repo'},
        {'createdAt': '2017-08-07T21:53:23Z',
         'number': 5,
         'title': 'Question: Can I create a dynamic list of profiles?'},
        {'createdAt': '2017-08-18T08:35:33Z',
         'number': 7,
         'title': 'User-dependent list of available profiles'},
        {'createdAt': '2017-08-26T14:06:03Z',
         'number': 8,
         'title': 'Add license '}]},
      'name': 'wrapspawner'},
     {'issues': {'nodes': [{'createdAt': '2017-01-07T19:18:06Z',
         'number': 2,
         'title': 'Unable to install the package'},
        {'createdAt': '2017-01-31T20:34:23Z',
         'number': 3,
         'title': 'Is this package needed?'},
        {'createdAt': '2017-03-16T14:45:19Z',
         'number': 6,
         'title': 'doesnt work for higher versions'},
        {'createdAt': '2017-07-20T02:16:45Z',
         'number': 15,
         'title': 'jupyterlab-hub redirect problem'}]},
      'name': 'jupyterlab-hub'},
     {'issues': {'nodes': [{'createdAt': '2017-03-31T08:53:10Z',
         'number': 1,
         'title': 'Make it a standalone service'},
        {'createdAt': '2017-10-31T03:52:55Z',
         'number': 5,
         'title': 'Support all HTTP methods'},
        {'createdAt': '2017-10-31T03:53:12Z',
         'number': 6,
         'title': 'Support websockets'}]},
      'name': 'nbserverproxy'},
     {'issues': {'nodes': [{'createdAt': '2017-04-25T11:30:58Z',
         'number': 2,
         'title': 'Detailed steps ?'},
        {'createdAt': '2017-05-03T15:22:33Z',
         'number': 3,
         'title': 'sudospawner tries to open nfs mounted home folder without kerberos ticket -> fails'},
        {'createdAt': '2017-09-25T23:22:42Z',
         'number': 4,
         'title': 'hub docker image installs unversioned dependencies'},
        {'createdAt': '2017-09-26T17:02:17Z',
         'number': 6,
         'title': "Can't authenticate into the SudoSpawner hub"}]},
      'name': 'jupyterhub-example-kerberos'},
     {'issues': {'nodes': [{'createdAt': '2017-01-27T13:39:47Z',
         'number': 6,
         'title': 'implement storage API'},
        {'createdAt': '2017-01-27T13:53:42Z', 'number': 7, 'title': 'UI'},
        {'createdAt': '2017-01-27T14:04:48Z',
         'number': 8,
         'title': 'single-user server interactions'},
        {'createdAt': '2017-01-27T14:30:46Z',
         'number': 9,
         'title': 'serve nbgrader'}]},
      'name': 'hubshare'},
     {'issues': {'nodes': [{'createdAt': '2016-12-13T21:14:00Z',
         'number': 1,
         'title': 'Are sessions secure?'},
        {'createdAt': '2016-12-13T22:17:45Z',
         'number': 2,
         'title': 'proxy error when rsession startup is slow'},
        {'createdAt': '2017-04-14T01:03:21Z',
         'number': 4,
         'title': 'Document rstudio installation'},
        {'createdAt': '2017-04-19T21:02:19Z',
         'number': 6,
         'title': 'Configuration variable precedence'}]},
      'name': 'nbrsessionproxy'},
     {'issues': {'nodes': [{'createdAt': '2017-08-26T16:01:45Z',
         'number': 3,
         'title': 'Update LICENSE'},
        {'createdAt': '2017-09-05T19:20:26Z',
         'number': 5,
         'title': 'Add a MANIFEST.in file'},
        {'createdAt': '2017-11-02T17:32:10Z',
         'number': 7,
         'title': 'New release?'}]},
      'name': 'tmpauthenticator'},
     {'issues': {'nodes': [{'createdAt': '2017-04-10T21:05:33Z',
         'number': 1,
         'title': 'Add initial build for RTD'},
        {'createdAt': '2017-04-10T21:06:17Z',
         'number': 2,
         'title': 'Create a CONTRIBUTING.md'},
        {'createdAt': '2017-04-11T00:17:59Z',
         'number': 3,
         'title': 'Do a spelling consistency check for JupyterHub'},
        {'createdAt': '2017-04-11T00:20:28Z',
         'number': 4,
         'title': 'Add Jupyter structure for docs'}]},
      'name': 'zero-to-jupyterhub-k8s'},
     {'issues': {'nodes': [{'createdAt': '2017-04-18T00:04:26Z',
         'number': 1,
         'title': 'Allow customizing base images for hub, proxy and culler pods'},
        {'createdAt': '2017-04-18T00:05:17Z',
         'number': 2,
         'title': 'Allow alternate ways to specify credentials for kubernetes API access'},
        {'createdAt': '2017-04-18T00:05:47Z',
         'number': 3,
         'title': 'Add support for Mediawiki Authenticator '},
        {'createdAt': '2017-04-27T22:06:30Z',
         'number': 4,
         'title': 'Storage version mismatch in global template'}]},
      'name': 'helm-chart'},
     {'issues': {'nodes': [{'createdAt': '2017-05-06T21:19:55Z',
         'number': 1,
         'title': 'Add a README'},
        {'createdAt': '2017-05-06T21:23:04Z',
         'number': 2,
         'title': 'Separate out the provider of repositories (GitHub) from the building code'},
        {'createdAt': '2017-05-06T21:24:46Z',
         'number': 3,
         'title': 'Set limits on building Docker containers'},
        {'createdAt': '2017-05-06T21:25:46Z',
         'number': 4,
         'title': 'Support building arbitrary Dockerfiles'}]},
      'name': 'binderhub'},
     {'issues': {'nodes': [{'createdAt': '2017-09-19T15:41:58Z',
         'number': 2,
         'title': 'What is this repo for?'},
        {'createdAt': '2017-09-19T20:16:14Z',
         'number': 4,
         'title': 'Remove common.yaml in root of repo'},
        {'createdAt': '2017-09-21T01:35:01Z',
         'number': 5,
         'title': 'Stop using omgwtf.in domains'},
        {'createdAt': '2017-09-28T00:54:52Z',
         'number': 8,
         'title': 'Automated push to deployment via GitHub PRs'}]},
      'name': 'mybinder.org-deploy'},
     {'issues': {'nodes': [{'createdAt': '2017-08-18T17:57:28Z',
         'number': 3,
         'title': 'Discuss nomenclature'},
        {'createdAt': '2017-08-18T18:29:47Z',
         'number': 5,
         'title': 'Documentation 1.0'},
        {'createdAt': '2017-08-26T15:57:04Z',
         'number': 9,
         'title': 'Add LICENSE'},
        {'createdAt': '2017-09-07T15:52:57Z',
         'number': 12,
         'title': 'Binder guide to reproducibility'}]},
      'name': 'binder'},
     {'issues': {'nodes': []}, 'name': 'nullauthenticator'},
     {'issues': {'nodes': [{'createdAt': '2017-12-07T20:11:23Z',
         'number': 1,
         'title': 'Use this repo for weekly notes etc?'},
        {'createdAt': '2017-12-10T18:54:15Z',
         'number': 3,
         'title': 'Add yourself to the teams in the README.md'},
        {'createdAt': '2017-12-10T18:55:18Z',
         'number': 4,
         'title': 'Deploy to RTD'}]},
      'name': 'team-compass'}]}}}}
In [99]:
# unpack the layers of json
nodes = r.json()['data']['organization']['repositories']['nodes']

unpacked = []
for node in nodes:
    unpacked.append(node)
In [100]:
unpacked
Out[100]:
[{'issues': {'nodes': [{'createdAt': '2014-08-18T18:00:47Z',
     'number': 2,
     'title': 'use sqlalchemy ORM for state'},
    {'createdAt': '2014-08-18T18:01:57Z',
     'number': 3,
     'title': 'make get_current_user async'},
    {'createdAt': '2014-08-18T18:02:32Z',
     'number': 4,
     'title': 'make process launching configurable'},
    {'createdAt': '2014-08-18T18:05:21Z',
     'number': 5,
     'title': 'make authentication configurable'}]},
  'name': 'jupyterhub'},
 {'issues': {'nodes': [{'createdAt': '2014-09-17T13:43:28Z',
     'number': 1,
     'title': 'Query by last activity API'},
    {'createdAt': '2014-10-23T23:13:22Z',
     'number': 18,
     'title': 'Sockets ballooning proportionally to the number of websockets opened by clients.'},
    {'createdAt': '2014-11-12T02:32:31Z',
     'number': 19,
     'title': '"prepend path" option doesn\'t work properly'},
    {'createdAt': '2015-04-21T16:42:29Z',
     'number': 23,
     'title': 'host routing'}]},
  'name': 'configurable-http-proxy'},
 {'issues': {'nodes': [{'createdAt': '2015-07-25T02:07:48Z',
     'number': 8,
     'title': 'GithubOAuthenticator gets 403'},
    {'createdAt': '2015-08-22T16:07:32Z',
     'number': 15,
     'title': 'Ubuntu users should use pip3 and python3'},
    {'createdAt': '2015-10-08T20:29:25Z',
     'number': 18,
     'title': 'delete CILogon staged certificate'},
    {'createdAt': '2015-11-29T21:33:52Z',
     'number': 21,
     'title': 'Add a MediawikiOAuthenticator'}]},
  'name': 'oauthenticator'},
 {'issues': {'nodes': [{'createdAt': '2014-09-27T21:08:00Z',
     'number': 2,
     'title': 'Docker layout'},
    {'createdAt': '2014-11-11T22:18:26Z',
     'number': 7,
     'title': 'jupyterhub_config.py'},
    {'createdAt': '2015-02-24T12:02:35Z',
     'number': 19,
     'title': 'Use `inspect_container` instead of `containers` for polling.'},
    {'createdAt': '2015-03-06T06:40:37Z',
     'number': 23,
     'title': '500 / 404 error on using docker spawner'}]},
  'name': 'dockerspawner'},
 {'issues': {'nodes': [{'createdAt': '2015-05-29T17:19:13Z',
     'number': 1,
     'title': "SudoSpawner & 'No JSON object could be decoded'"},
    {'createdAt': '2015-06-30T18:10:20Z',
     'number': 2,
     'title': 'Call to IPython.utils.traitlets'},
    {'createdAt': '2015-08-04T17:26:20Z',
     'number': 4,
     'title': 'Broken link in README'},
    {'createdAt': '2015-08-13T18:21:24Z',
     'number': 6,
     'title': 'User Server Will Not Restart'}]},
  'name': 'sudospawner'},
 {'issues': {'nodes': [{'createdAt': '2016-02-24T22:45:18Z',
     'number': 3,
     'title': 'Implement testing'},
    {'createdAt': '2016-07-02T18:23:41Z',
     'number': 8,
     'title': 'use new traits api'},
    {'createdAt': '2016-07-06T20:28:09Z',
     'number': 9,
     'title': 'Using sudo but preserving needed environment variables'},
    {'createdAt': '2016-07-06T20:40:14Z',
     'number': 10,
     'title': 'Specifying queue via config file'}]},
  'name': 'batchspawner'},
 {'issues': {'nodes': [{'createdAt': '2016-03-08T03:22:53Z',
     'number': 1,
     'title': 'Add a default health check for the pods'},
    {'createdAt': '2016-03-09T13:06:08Z',
     'number': 2,
     'title': 'Documentation and Contribution'},
    {'createdAt': '2016-03-11T14:47:38Z',
     'number': 3,
     'title': 'Return statement inside a generator error'},
    {'createdAt': '2016-04-05T16:26:34Z',
     'number': 5,
     'title': 'Sometimes pods spawn but wrong state returned to JupyterHub'}]},
  'name': 'kubespawner'},
 {'issues': {'nodes': [{'createdAt': '2016-01-22T02:22:31Z',
     'number': 1,
     'title': 'Support restricting login to members of certain groups only'},
    {'createdAt': '2016-01-22T02:23:04Z',
     'number': 2,
     'title': 'Set jupyterhub userid to be the same as uid from LDAP'},
    {'createdAt': '2016-01-22T02:53:19Z',
     'number': 3,
     'title': 'Validate username to protect against LDAP injection attacks'},
    {'createdAt': '2016-01-23T01:29:47Z',
     'number': 4,
     'title': 'Change username_template to bind_dn'}]},
  'name': 'ldapauthenticator'},
 {'issues': {'nodes': [{'createdAt': '2016-05-04T20:28:01Z',
     'number': 6,
     'title': 'Problem with running/authenticating on an EC2 (AWS) machine and checking right cert/key files used'},
    {'createdAt': '2016-05-30T12:10:49Z',
     'number': 15,
     'title': 'github oauth'},
    {'createdAt': '2016-07-31T01:40:33Z',
     'number': 16,
     'title': 'Starting container with HostConfig removed in Docker 1.12 - extra_start_kwargs fails'},
    {'createdAt': '2016-08-18T04:21:52Z',
     'number': 19,
     'title': 'How to spawn user container with DOCKER_NOTEBOOK_DIR '}]},
  'name': 'jupyterhub-deploy-docker'},
 {'issues': {'nodes': [{'createdAt': '2016-04-19T05:17:09Z',
     'number': 5,
     'title': 'Update cookie secret in docs'},
    {'createdAt': '2016-04-27T15:00:57Z',
     'number': 12,
     'title': 'Update docs to reflect changes in PR #10 and #11'},
    {'createdAt': '2016-06-07T02:40:51Z',
     'number': 13,
     'title': 'cannot install superviser '},
    {'createdAt': '2016-08-13T23:38:11Z',
     'number': 20,
     'title': 'Anaconda path issue'}]},
  'name': 'jupyterhub-deploy-teaching'},
 {'issues': {'nodes': [{'createdAt': '2016-05-17T14:05:30Z',
     'number': 2,
     'title': 'Update and add links for jupyterhub-tutorial notebook'},
    {'createdAt': '2016-07-16T17:58:33Z',
     'number': 4,
     'title': 'Add headings to timeline.md'},
    {'createdAt': '2016-10-21T10:45:51Z',
     'number': 10,
     'title': 'Annotate Intro in timeline.md'},
    {'createdAt': '2016-10-21T10:49:07Z',
     'number': 11,
     'title': 'Annotate Overview in timeline.md'}]},
  'name': 'jupyterhub-tutorial'},
 {'issues': {'nodes': [{'createdAt': '2017-01-16T15:48:32Z',
     'number': 2,
     'title': 'Add a jetstream instance for jupyterhub'},
    {'createdAt': '2017-07-12T19:22:28Z',
     'number': 3,
     'title': 'xsede_oauthenticator --> jupyterhub/oauthenticator ?'}]},
  'name': 'jupyterhub-deploy-hpc'},
 {'issues': {'nodes': [{'createdAt': '2016-09-22T04:34:22Z',
     'number': 1,
     'title': 'Update url in setup.py'},
    {'createdAt': '2016-09-24T08:38:47Z',
     'number': 3,
     'title': 'Add installation instructions to README'},
    {'createdAt': '2016-09-24T08:38:58Z',
     'number': 4,
     'title': 'Add configuration documentation to README'},
    {'createdAt': '2016-09-24T08:39:46Z',
     'number': 5,
     'title': 'Write a configuration checker that ensures that appropriate kernel settings are enabled'}]},
  'name': 'systemdspawner'},
 {'issues': {'nodes': [{'createdAt': '2016-09-21T21:52:28Z',
     'number': 1,
     'title': 'Migrate wrapspawner to this repo'},
    {'createdAt': '2017-08-07T21:53:23Z',
     'number': 5,
     'title': 'Question: Can I create a dynamic list of profiles?'},
    {'createdAt': '2017-08-18T08:35:33Z',
     'number': 7,
     'title': 'User-dependent list of available profiles'},
    {'createdAt': '2017-08-26T14:06:03Z',
     'number': 8,
     'title': 'Add license '}]},
  'name': 'wrapspawner'},
 {'issues': {'nodes': [{'createdAt': '2017-01-07T19:18:06Z',
     'number': 2,
     'title': 'Unable to install the package'},
    {'createdAt': '2017-01-31T20:34:23Z',
     'number': 3,
     'title': 'Is this package needed?'},
    {'createdAt': '2017-03-16T14:45:19Z',
     'number': 6,
     'title': 'doesnt work for higher versions'},
    {'createdAt': '2017-07-20T02:16:45Z',
     'number': 15,
     'title': 'jupyterlab-hub redirect problem'}]},
  'name': 'jupyterlab-hub'},
 {'issues': {'nodes': [{'createdAt': '2017-03-31T08:53:10Z',
     'number': 1,
     'title': 'Make it a standalone service'},
    {'createdAt': '2017-10-31T03:52:55Z',
     'number': 5,
     'title': 'Support all HTTP methods'},
    {'createdAt': '2017-10-31T03:53:12Z',
     'number': 6,
     'title': 'Support websockets'}]},
  'name': 'nbserverproxy'},
 {'issues': {'nodes': [{'createdAt': '2017-04-25T11:30:58Z',
     'number': 2,
     'title': 'Detailed steps ?'},
    {'createdAt': '2017-05-03T15:22:33Z',
     'number': 3,
     'title': 'sudospawner tries to open nfs mounted home folder without kerberos ticket -> fails'},
    {'createdAt': '2017-09-25T23:22:42Z',
     'number': 4,
     'title': 'hub docker image installs unversioned dependencies'},
    {'createdAt': '2017-09-26T17:02:17Z',
     'number': 6,
     'title': "Can't authenticate into the SudoSpawner hub"}]},
  'name': 'jupyterhub-example-kerberos'},
 {'issues': {'nodes': [{'createdAt': '2017-01-27T13:39:47Z',
     'number': 6,
     'title': 'implement storage API'},
    {'createdAt': '2017-01-27T13:53:42Z', 'number': 7, 'title': 'UI'},
    {'createdAt': '2017-01-27T14:04:48Z',
     'number': 8,
     'title': 'single-user server interactions'},
    {'createdAt': '2017-01-27T14:30:46Z',
     'number': 9,
     'title': 'serve nbgrader'}]},
  'name': 'hubshare'},
 {'issues': {'nodes': [{'createdAt': '2016-12-13T21:14:00Z',
     'number': 1,
     'title': 'Are sessions secure?'},
    {'createdAt': '2016-12-13T22:17:45Z',
     'number': 2,
     'title': 'proxy error when rsession startup is slow'},
    {'createdAt': '2017-04-14T01:03:21Z',
     'number': 4,
     'title': 'Document rstudio installation'},
    {'createdAt': '2017-04-19T21:02:19Z',
     'number': 6,
     'title': 'Configuration variable precedence'}]},
  'name': 'nbrsessionproxy'},
 {'issues': {'nodes': [{'createdAt': '2017-08-26T16:01:45Z',
     'number': 3,
     'title': 'Update LICENSE'},
    {'createdAt': '2017-09-05T19:20:26Z',
     'number': 5,
     'title': 'Add a MANIFEST.in file'},
    {'createdAt': '2017-11-02T17:32:10Z',
     'number': 7,
     'title': 'New release?'}]},
  'name': 'tmpauthenticator'},
 {'issues': {'nodes': [{'createdAt': '2017-04-10T21:05:33Z',
     'number': 1,
     'title': 'Add initial build for RTD'},
    {'createdAt': '2017-04-10T21:06:17Z',
     'number': 2,
     'title': 'Create a CONTRIBUTING.md'},
    {'createdAt': '2017-04-11T00:17:59Z',
     'number': 3,
     'title': 'Do a spelling consistency check for JupyterHub'},
    {'createdAt': '2017-04-11T00:20:28Z',
     'number': 4,
     'title': 'Add Jupyter structure for docs'}]},
  'name': 'zero-to-jupyterhub-k8s'},
 {'issues': {'nodes': [{'createdAt': '2017-04-18T00:04:26Z',
     'number': 1,
     'title': 'Allow customizing base images for hub, proxy and culler pods'},
    {'createdAt': '2017-04-18T00:05:17Z',
     'number': 2,
     'title': 'Allow alternate ways to specify credentials for kubernetes API access'},
    {'createdAt': '2017-04-18T00:05:47Z',
     'number': 3,
     'title': 'Add support for Mediawiki Authenticator '},
    {'createdAt': '2017-04-27T22:06:30Z',
     'number': 4,
     'title': 'Storage version mismatch in global template'}]},
  'name': 'helm-chart'},
 {'issues': {'nodes': [{'createdAt': '2017-05-06T21:19:55Z',
     'number': 1,
     'title': 'Add a README'},
    {'createdAt': '2017-05-06T21:23:04Z',
     'number': 2,
     'title': 'Separate out the provider of repositories (GitHub) from the building code'},
    {'createdAt': '2017-05-06T21:24:46Z',
     'number': 3,
     'title': 'Set limits on building Docker containers'},
    {'createdAt': '2017-05-06T21:25:46Z',
     'number': 4,
     'title': 'Support building arbitrary Dockerfiles'}]},
  'name': 'binderhub'},
 {'issues': {'nodes': [{'createdAt': '2017-09-19T15:41:58Z',
     'number': 2,
     'title': 'What is this repo for?'},
    {'createdAt': '2017-09-19T20:16:14Z',
     'number': 4,
     'title': 'Remove common.yaml in root of repo'},
    {'createdAt': '2017-09-21T01:35:01Z',
     'number': 5,
     'title': 'Stop using omgwtf.in domains'},
    {'createdAt': '2017-09-28T00:54:52Z',
     'number': 8,
     'title': 'Automated push to deployment via GitHub PRs'}]},
  'name': 'mybinder.org-deploy'},
 {'issues': {'nodes': [{'createdAt': '2017-08-18T17:57:28Z',
     'number': 3,
     'title': 'Discuss nomenclature'},
    {'createdAt': '2017-08-18T18:29:47Z',
     'number': 5,
     'title': 'Documentation 1.0'},
    {'createdAt': '2017-08-26T15:57:04Z', 'number': 9, 'title': 'Add LICENSE'},
    {'createdAt': '2017-09-07T15:52:57Z',
     'number': 12,
     'title': 'Binder guide to reproducibility'}]},
  'name': 'binder'},
 {'issues': {'nodes': []}, 'name': 'nullauthenticator'},
 {'issues': {'nodes': [{'createdAt': '2017-12-07T20:11:23Z',
     'number': 1,
     'title': 'Use this repo for weekly notes etc?'},
    {'createdAt': '2017-12-10T18:54:15Z',
     'number': 3,
     'title': 'Add yourself to the teams in the README.md'},
    {'createdAt': '2017-12-10T18:55:18Z',
     'number': 4,
     'title': 'Deploy to RTD'}]},
  'name': 'team-compass'}]
In [101]:
headers = ['name', 'issues']

rows = []
for obj in unpacked:
    issue_list = []
    for item in obj['issues']['nodes']:
        issue_list.append({item['number'], item['title'], item['createdAt']})
    new_dict = {'name':obj['name'], 'issues':issue_list}
    rows.append(new_dict)
rows
Out[101]:
[{'issues': [{2, '2014-08-18T18:00:47Z', 'use sqlalchemy ORM for state'},
   {'2014-08-18T18:01:57Z', 3, 'make get_current_user async'},
   {'2014-08-18T18:02:32Z', 4, 'make process launching configurable'},
   {'2014-08-18T18:05:21Z', 5, 'make authentication configurable'}],
  'name': 'jupyterhub'},
 {'issues': [{1, '2014-09-17T13:43:28Z', 'Query by last activity API'},
   {18,
    '2014-10-23T23:13:22Z',
    'Sockets ballooning proportionally to the number of websockets opened by clients.'},
   {'"prepend path" option doesn\'t work properly',
    19,
    '2014-11-12T02:32:31Z'},
   {'2015-04-21T16:42:29Z', 23, 'host routing'}],
  'name': 'configurable-http-proxy'},
 {'issues': [{'2015-07-25T02:07:48Z', 8, 'GithubOAuthenticator gets 403'},
   {15, '2015-08-22T16:07:32Z', 'Ubuntu users should use pip3 and python3'},
   {18, '2015-10-08T20:29:25Z', 'delete CILogon staged certificate'},
   {'2015-11-29T21:33:52Z', 21, 'Add a MediawikiOAuthenticator'}],
  'name': 'oauthenticator'},
 {'issues': [{2, '2014-09-27T21:08:00Z', 'Docker layout'},
   {'2014-11-11T22:18:26Z', 7, 'jupyterhub_config.py'},
   {19,
    '2015-02-24T12:02:35Z',
    'Use `inspect_container` instead of `containers` for polling.'},
   {'2015-03-06T06:40:37Z', 23, '500 / 404 error on using docker spawner'}],
  'name': 'dockerspawner'},
 {'issues': [{1,
    '2015-05-29T17:19:13Z',
    "SudoSpawner & 'No JSON object could be decoded'"},
   {2, '2015-06-30T18:10:20Z', 'Call to IPython.utils.traitlets'},
   {'2015-08-04T17:26:20Z', 4, 'Broken link in README'},
   {'2015-08-13T18:21:24Z', 6, 'User Server Will Not Restart'}],
  'name': 'sudospawner'},
 {'issues': [{'2016-02-24T22:45:18Z', 3, 'Implement testing'},
   {'2016-07-02T18:23:41Z', 8, 'use new traits api'},
   {'2016-07-06T20:28:09Z',
    9,
    'Using sudo but preserving needed environment variables'},
   {10, '2016-07-06T20:40:14Z', 'Specifying queue via config file'}],
  'name': 'batchspawner'},
 {'issues': [{1,
    '2016-03-08T03:22:53Z',
    'Add a default health check for the pods'},
   {2, '2016-03-09T13:06:08Z', 'Documentation and Contribution'},
   {'2016-03-11T14:47:38Z', 3, 'Return statement inside a generator error'},
   {'2016-04-05T16:26:34Z',
    5,
    'Sometimes pods spawn but wrong state returned to JupyterHub'}],
  'name': 'kubespawner'},
 {'issues': [{1,
    '2016-01-22T02:22:31Z',
    'Support restricting login to members of certain groups only'},
   {2,
    '2016-01-22T02:23:04Z',
    'Set jupyterhub userid to be the same as uid from LDAP'},
   {'2016-01-22T02:53:19Z',
    3,
    'Validate username to protect against LDAP injection attacks'},
   {'2016-01-23T01:29:47Z', 4, 'Change username_template to bind_dn'}],
  'name': 'ldapauthenticator'},
 {'issues': [{'2016-05-04T20:28:01Z',
    6,
    'Problem with running/authenticating on an EC2 (AWS) machine and checking right cert/key files used'},
   {15, '2016-05-30T12:10:49Z', 'github oauth'},
   {16,
    '2016-07-31T01:40:33Z',
    'Starting container with HostConfig removed in Docker 1.12 - extra_start_kwargs fails'},
   {19,
    '2016-08-18T04:21:52Z',
    'How to spawn user container with DOCKER_NOTEBOOK_DIR '}],
  'name': 'jupyterhub-deploy-docker'},
 {'issues': [{'2016-04-19T05:17:09Z', 5, 'Update cookie secret in docs'},
   {12,
    '2016-04-27T15:00:57Z',
    'Update docs to reflect changes in PR #10 and #11'},
   {13, '2016-06-07T02:40:51Z', 'cannot install superviser '},
   {20, '2016-08-13T23:38:11Z', 'Anaconda path issue'}],
  'name': 'jupyterhub-deploy-teaching'},
 {'issues': [{2,
    '2016-05-17T14:05:30Z',
    'Update and add links for jupyterhub-tutorial notebook'},
   {'2016-07-16T17:58:33Z', 4, 'Add headings to timeline.md'},
   {10, '2016-10-21T10:45:51Z', 'Annotate Intro in timeline.md'},
   {11, '2016-10-21T10:49:07Z', 'Annotate Overview in timeline.md'}],
  'name': 'jupyterhub-tutorial'},
 {'issues': [{2,
    '2017-01-16T15:48:32Z',
    'Add a jetstream instance for jupyterhub'},
   {'2017-07-12T19:22:28Z',
    3,
    'xsede_oauthenticator --> jupyterhub/oauthenticator ?'}],
  'name': 'jupyterhub-deploy-hpc'},
 {'issues': [{1, '2016-09-22T04:34:22Z', 'Update url in setup.py'},
   {'2016-09-24T08:38:47Z', 3, 'Add installation instructions to README'},
   {'2016-09-24T08:38:58Z', 4, 'Add configuration documentation to README'},
   {'2016-09-24T08:39:46Z',
    5,
    'Write a configuration checker that ensures that appropriate kernel settings are enabled'}],
  'name': 'systemdspawner'},
 {'issues': [{1, '2016-09-21T21:52:28Z', 'Migrate wrapspawner to this repo'},
   {'2017-08-07T21:53:23Z',
    5,
    'Question: Can I create a dynamic list of profiles?'},
   {'2017-08-18T08:35:33Z', 7, 'User-dependent list of available profiles'},
   {'2017-08-26T14:06:03Z', 8, 'Add license '}],
  'name': 'wrapspawner'},
 {'issues': [{2, '2017-01-07T19:18:06Z', 'Unable to install the package'},
   {'2017-01-31T20:34:23Z', 3, 'Is this package needed?'},
   {'2017-03-16T14:45:19Z', 6, 'doesnt work for higher versions'},
   {15, '2017-07-20T02:16:45Z', 'jupyterlab-hub redirect problem'}],
  'name': 'jupyterlab-hub'},
 {'issues': [{1, '2017-03-31T08:53:10Z', 'Make it a standalone service'},
   {'2017-10-31T03:52:55Z', 5, 'Support all HTTP methods'},
   {'2017-10-31T03:53:12Z', 6, 'Support websockets'}],
  'name': 'nbserverproxy'},
 {'issues': [{2, '2017-04-25T11:30:58Z', 'Detailed steps ?'},
   {'2017-05-03T15:22:33Z',
    3,
    'sudospawner tries to open nfs mounted home folder without kerberos ticket -> fails'},
   {'2017-09-25T23:22:42Z',
    4,
    'hub docker image installs unversioned dependencies'},
   {'2017-09-26T17:02:17Z', 6, "Can't authenticate into the SudoSpawner hub"}],
  'name': 'jupyterhub-example-kerberos'},
 {'issues': [{'2017-01-27T13:39:47Z', 6, 'implement storage API'},
   {'2017-01-27T13:53:42Z', 7, 'UI'},
   {'2017-01-27T14:04:48Z', 8, 'single-user server interactions'},
   {'2017-01-27T14:30:46Z', 9, 'serve nbgrader'}],
  'name': 'hubshare'},
 {'issues': [{1, '2016-12-13T21:14:00Z', 'Are sessions secure?'},
   {2, '2016-12-13T22:17:45Z', 'proxy error when rsession startup is slow'},
   {'2017-04-14T01:03:21Z', 4, 'Document rstudio installation'},
   {'2017-04-19T21:02:19Z', 6, 'Configuration variable precedence'}],
  'name': 'nbrsessionproxy'},
 {'issues': [{'2017-08-26T16:01:45Z', 3, 'Update LICENSE'},
   {'2017-09-05T19:20:26Z', 5, 'Add a MANIFEST.in file'},
   {'2017-11-02T17:32:10Z', 7, 'New release?'}],
  'name': 'tmpauthenticator'},
 {'issues': [{1, '2017-04-10T21:05:33Z', 'Add initial build for RTD'},
   {2, '2017-04-10T21:06:17Z', 'Create a CONTRIBUTING.md'},
   {'2017-04-11T00:17:59Z',
    3,
    'Do a spelling consistency check for JupyterHub'},
   {'2017-04-11T00:20:28Z', 4, 'Add Jupyter structure for docs'}],
  'name': 'zero-to-jupyterhub-k8s'},
 {'issues': [{1,
    '2017-04-18T00:04:26Z',
    'Allow customizing base images for hub, proxy and culler pods'},
   {2,
    '2017-04-18T00:05:17Z',
    'Allow alternate ways to specify credentials for kubernetes API access'},
   {'2017-04-18T00:05:47Z', 3, 'Add support for Mediawiki Authenticator '},
   {'2017-04-27T22:06:30Z', 4, 'Storage version mismatch in global template'}],
  'name': 'helm-chart'},
 {'issues': [{1, '2017-05-06T21:19:55Z', 'Add a README'},
   {2,
    '2017-05-06T21:23:04Z',
    'Separate out the provider of repositories (GitHub) from the building code'},
   {'2017-05-06T21:24:46Z', 3, 'Set limits on building Docker containers'},
   {'2017-05-06T21:25:46Z', 4, 'Support building arbitrary Dockerfiles'}],
  'name': 'binderhub'},
 {'issues': [{2, '2017-09-19T15:41:58Z', 'What is this repo for?'},
   {'2017-09-19T20:16:14Z', 4, 'Remove common.yaml in root of repo'},
   {'2017-09-21T01:35:01Z', 5, 'Stop using omgwtf.in domains'},
   {'2017-09-28T00:54:52Z', 8, 'Automated push to deployment via GitHub PRs'}],
  'name': 'mybinder.org-deploy'},
 {'issues': [{'2017-08-18T17:57:28Z', 3, 'Discuss nomenclature'},
   {'2017-08-18T18:29:47Z', 5, 'Documentation 1.0'},
   {'2017-08-26T15:57:04Z', 9, 'Add LICENSE'},
   {12, '2017-09-07T15:52:57Z', 'Binder guide to reproducibility'}],
  'name': 'binder'},
 {'issues': [], 'name': 'nullauthenticator'},
 {'issues': [{1,
    '2017-12-07T20:11:23Z',
    'Use this repo for weekly notes etc?'},
   {'2017-12-10T18:54:15Z', 3, 'Add yourself to the teams in the README.md'},
   {'2017-12-10T18:55:18Z', 4, 'Deploy to RTD'}],
  'name': 'team-compass'}]
In [102]:
with open('mydata.csv', 'w') as f:
    f_csv = csv.DictWriter(f, headers)
    f_csv.writeheader()
    f_csv.writerows(rows)

Check file

In [103]:
%%bash

less mydata.csv
name,issues
jupyterhub,"[{2, 'use sqlalchemy ORM for state', '2014-08-18T18:00:47Z'}, {'make get_current_user async', 3, '2014-08-18T18:01:57Z'}, {'2014-08-18T18:02:32Z', 'make process launching configurable', 4}, {'make authentication configurable', 5, '2014-08-18T18:05:21Z'}]"
configurable-http-proxy,"[{'Query by last activity API', 1, '2014-09-17T13:43:28Z'}, {'Sockets ballooning proportionally to the number of websockets opened by clients.', 18, '2014-10-23T23:13:22Z'}, {19, '2014-11-12T02:32:31Z', '""prepend path"" option doesn\'t work properly'}, {'2015-04-21T16:42:29Z', 'host routing', 23}]"
oauthenticator,"[{8, '2015-07-25T02:07:48Z', 'GithubOAuthenticator gets 403'}, {'2015-08-22T16:07:32Z', 'Ubuntu users should use pip3 and python3', 15}, {18, 'delete CILogon staged certificate', '2015-10-08T20:29:25Z'}, {'Add a MediawikiOAuthenticator', '2015-11-29T21:33:52Z', 21}]"
dockerspawner,"[{2, '2014-09-27T21:08:00Z', 'Docker layout'}, {'jupyterhub_config.py', '2014-11-11T22:18:26Z', 7}, {'Use `inspect_container` instead of `containers` for polling.', 19, '2015-02-24T12:02:35Z'}, {'2015-03-06T06:40:37Z', '500 / 404 error on using docker spawner', 23}]"
sudospawner,"[{""SudoSpawner & 'No JSON object could be decoded'"", 1, '2015-05-29T17:19:13Z'}, {2, 'Call to IPython.utils.traitlets', '2015-06-30T18:10:20Z'}, {'2015-08-04T17:26:20Z', 4, 'Broken link in README'}, {'2015-08-13T18:21:24Z', 'User Server Will Not Restart', 6}]"
batchspawner,"[{3, 'Implement testing', '2016-02-24T22:45:18Z'}, {8, '2016-07-02T18:23:41Z', 'use new traits api'}, {'Using sudo but preserving needed environment variables', 9, '2016-07-06T20:28:09Z'}, {'Specifying queue via config file', 10, '2016-07-06T20:40:14Z'}]"
kubespawner,"[{1, 'Add a default health check for the pods', '2016-03-08T03:22:53Z'}, {'Documentation and Contribution', 2, '2016-03-09T13:06:08Z'}, {'2016-03-11T14:47:38Z', 3, 'Return statement inside a generator error'}, {'Sometimes pods spawn but wrong state returned to JupyterHub', 5, '2016-04-05T16:26:34Z'}]"
ldapauthenticator,"[{1, '2016-01-22T02:22:31Z', 'Support restricting login to members of certain groups only'}, {2, 'Set jupyterhub userid to be the same as uid from LDAP', '2016-01-22T02:23:04Z'}, {'2016-01-22T02:53:19Z', 3, 'Validate username to protect against LDAP injection attacks'}, {'2016-01-23T01:29:47Z', 4, 'Change username_template to bind_dn'}]"
jupyterhub-deploy-docker,"[{'Problem with running/authenticating on an EC2 (AWS) machine and checking right cert/key files used', '2016-05-04T20:28:01Z', 6}, {'github oauth', '2016-05-30T12:10:49Z', 15}, {16, 'Starting container with HostConfig removed in Docker 1.12 - extra_start_kwargs fails', '2016-07-31T01:40:33Z'}, {19, '2016-08-18T04:21:52Z', 'How to spawn user container with DOCKER_NOTEBOOK_DIR '}]"
jupyterhub-deploy-teaching,"[{'2016-04-19T05:17:09Z', 'Update cookie secret in docs', 5}, {'Update docs to reflect changes in PR #10 and #11', '2016-04-27T15:00:57Z', 12}, {'cannot install superviser ', 13, '2016-06-07T02:40:51Z'}, {'Anaconda path issue', '2016-08-13T23:38:11Z', 20}]"
jupyterhub-tutorial,"[{'Update and add links for jupyterhub-tutorial notebook', 2, '2016-05-17T14:05:30Z'}, {'Add headings to timeline.md', 4, '2016-07-16T17:58:33Z'}, {'2016-10-21T10:45:51Z', 10, 'Annotate Intro in timeline.md'}, {'Annotate Overview in timeline.md', 11, '2016-10-21T10:49:07Z'}]"
jupyterhub-deploy-hpc,"[{'Add a jetstream instance for jupyterhub', 2, '2017-01-16T15:48:32Z'}, {3, '2017-07-12T19:22:28Z', 'xsede_oauthenticator --> jupyterhub/oauthenticator ?'}]"
systemdspawner,"[{'2016-09-22T04:34:22Z', 1, 'Update url in setup.py'}, {'2016-09-24T08:38:47Z', 'Add installation instructions to README', 3}, {'2016-09-24T08:38:58Z', 'Add configuration documentation to README', 4}, {'Write a configuration checker that ensures that appropriate kernel settings are enabled', 5, '2016-09-24T08:39:46Z'}]"
wrapspawner,"[{1, 'Migrate wrapspawner to this repo', '2016-09-21T21:52:28Z'}, {'2017-08-07T21:53:23Z', 'Question: Can I create a dynamic list of profiles?', 5}, {'2017-08-18T08:35:33Z', 'User-dependent list of available profiles', 7}, {8, 'Add license ', '2017-08-26T14:06:03Z'}]"
jupyterlab-hub,"[{2, 'Unable to install the package', '2017-01-07T19:18:06Z'}, {3, 'Is this package needed?', '2017-01-31T20:34:23Z'}, {'2017-03-16T14:45:19Z', 'doesnt work for higher versions', 6}, {'2017-07-20T02:16:45Z', 'jupyterlab-hub redirect problem', 15}]"
nbserverproxy,"[{1, 'Make it a standalone service', '2017-03-31T08:53:10Z'}, {'Support all HTTP methods', 5, '2017-10-31T03:52:55Z'}, {'Support websockets', '2017-10-31T03:53:12Z', 6}]"
jupyterhub-example-kerberos,"[{2, 'Detailed steps ?', '2017-04-25T11:30:58Z'}, {'sudospawner tries to open nfs mounted home folder without kerberos ticket -> fails', 3, '2017-05-03T15:22:33Z'}, {'2017-09-25T23:22:42Z', 4, 'hub docker image installs unversioned dependencies'}, {""Can't authenticate into the SudoSpawner hub"", '2017-09-26T17:02:17Z', 6}]"
hubshare,"[{'2017-01-27T13:39:47Z', 'implement storage API', 6}, {'UI', '2017-01-27T13:53:42Z', 7}, {8, '2017-01-27T14:04:48Z', 'single-user server interactions'}, {9, 'serve nbgrader', '2017-01-27T14:30:46Z'}]"
nbrsessionproxy,"[{'Are sessions secure?', 1, '2016-12-13T21:14:00Z'}, {'2016-12-13T22:17:45Z', 2, 'proxy error when rsession startup is slow'}, {'2017-04-14T01:03:21Z', 'Document rstudio installation', 4}, {'Configuration variable precedence', '2017-04-19T21:02:19Z', 6}]"
tmpauthenticator,"[{'Update LICENSE', 3, '2017-08-26T16:01:45Z'}, {'Add a MANIFEST.in file', '2017-09-05T19:20:26Z', 5}, {'2017-11-02T17:32:10Z', 'New release?', 7}]"
zero-to-jupyterhub-k8s,"[{'Add initial build for RTD', 1, '2017-04-10T21:05:33Z'}, {2, 'Create a CONTRIBUTING.md', '2017-04-10T21:06:17Z'}, {'Do a spelling consistency check for JupyterHub', '2017-04-11T00:17:59Z', 3}, {'Add Jupyter structure for docs', 4, '2017-04-11T00:20:28Z'}]"
helm-chart,"[{1, '2017-04-18T00:04:26Z', 'Allow customizing base images for hub, proxy and culler pods'}, {'2017-04-18T00:05:17Z', 2, 'Allow alternate ways to specify credentials for kubernetes API access'}, {'2017-04-18T00:05:47Z', 3, 'Add support for Mediawiki Authenticator '}, {'2017-04-27T22:06:30Z', 4, 'Storage version mismatch in global template'}]"
binderhub,"[{'Add a README', 1, '2017-05-06T21:19:55Z'}, {'Separate out the provider of repositories (GitHub) from the building code', 2, '2017-05-06T21:23:04Z'}, {3, 'Set limits on building Docker containers', '2017-05-06T21:24:46Z'}, {'2017-05-06T21:25:46Z', 'Support building arbitrary Dockerfiles', 4}]"
mybinder.org-deploy,"[{'What is this repo for?', 2, '2017-09-19T15:41:58Z'}, {'2017-09-19T20:16:14Z', 4, 'Remove common.yaml in root of repo'}, {'Stop using omgwtf.in domains', 5, '2017-09-21T01:35:01Z'}, {8, '2017-09-28T00:54:52Z', 'Automated push to deployment via GitHub PRs'}]"
binder,"[{'Discuss nomenclature', 3, '2017-08-18T17:57:28Z'}, {'2017-08-18T18:29:47Z', 'Documentation 1.0', 5}, {9, '2017-08-26T15:57:04Z', 'Add LICENSE'}, {'Binder guide to reproducibility', 12, '2017-09-07T15:52:57Z'}]"
nullauthenticator,[]
team-compass,"[{1, '2017-12-07T20:11:23Z', 'Use this repo for weekly notes etc?'}, {'Add yourself to the teams in the README.md', 3, '2017-12-10T18:54:15Z'}, {'2017-12-10T18:55:18Z', 'Deploy to RTD', 4}]"

Bring into pandas

In [105]:
df = pd.read_csv('mydata.csv')
In [106]:
df.columns
Out[106]:
Index(['name', 'issues'], dtype='object')
In [107]:
# df.head()

Generate basic report of total open issues

In [108]:
# df.dtypes
In [109]:
# df.index
In [110]:
# df.values

Reports

In [111]:
# By repo name
sorted_df = df.sort_values(by=['name'])
sorted_df
Out[111]:
name issues
5 batchspawner [{3, 'Implement testing', '2016-02-24T22:45:18...
24 binder [{'Discuss nomenclature', 3, '2017-08-18T17:57...
22 binderhub [{'Add a README', 1, '2017-05-06T21:19:55Z'}, ...
1 configurable-http-proxy [{'Query by last activity API', 1, '2014-09-17...
3 dockerspawner [{2, '2014-09-27T21:08:00Z', 'Docker layout'},...
21 helm-chart [{1, '2017-04-18T00:04:26Z', 'Allow customizin...
17 hubshare [{'2017-01-27T13:39:47Z', 'implement storage A...
0 jupyterhub [{2, 'use sqlalchemy ORM for state', '2014-08-...
8 jupyterhub-deploy-docker [{'Problem with running/authenticating on an E...
11 jupyterhub-deploy-hpc [{'Add a jetstream instance for jupyterhub', 2...
9 jupyterhub-deploy-teaching [{'2016-04-19T05:17:09Z', 'Update cookie secre...
16 jupyterhub-example-kerberos [{2, 'Detailed steps ?', '2017-04-25T11:30:58Z...
10 jupyterhub-tutorial [{'Update and add links for jupyterhub-tutoria...
14 jupyterlab-hub [{2, 'Unable to install the package', '2017-01...
6 kubespawner [{1, 'Add a default health check for the pods'...
7 ldapauthenticator [{1, '2016-01-22T02:22:31Z', 'Support restrict...
23 mybinder.org-deploy [{'What is this repo for?', 2, '2017-09-19T15:...
18 nbrsessionproxy [{'Are sessions secure?', 1, '2016-12-13T21:14...
15 nbserverproxy [{1, 'Make it a standalone service', '2017-03-...
25 nullauthenticator []
2 oauthenticator [{8, '2015-07-25T02:07:48Z', 'GithubOAuthentic...
4 sudospawner [{"SudoSpawner & 'No JSON object could be deco...
12 systemdspawner [{'2016-09-22T04:34:22Z', 1, 'Update url in se...
26 team-compass [{1, '2017-12-07T20:11:23Z', 'Use this repo fo...
19 tmpauthenticator [{'Update LICENSE', 3, '2017-08-26T16:01:45Z'}...
13 wrapspawner [{1, 'Migrate wrapspawner to this repo', '2016...
20 zero-to-jupyterhub-k8s [{'Add initial build for RTD', 1, '2017-04-10T...
In [138]:
for x in sorted_df:
    name
    issues
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-138-e4a95010a8a9> in <module>()
      1 for x in sorted_df:
      2     name
----> 3     issues
      4
      5

NameError: name 'issues' is not defined
In [113]:
# by open pr count
df.sort_values(by=['prs'], ascending=False)
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
~/anaconda3/envs/pyquery/lib/python3.6/site-packages/pandas/core/indexes/base.py in get_loc(self, key, method, tolerance)
   2521             try:
-> 2522                 return self._engine.get_loc(key)
   2523             except KeyError:

pandas/_libs/index.pyx in pandas._libs.index.IndexEngine.get_loc()

pandas/_libs/index.pyx in pandas._libs.index.IndexEngine.get_loc()

pandas/_libs/hashtable_class_helper.pxi in pandas._libs.hashtable.PyObjectHashTable.get_item()

pandas/_libs/hashtable_class_helper.pxi in pandas._libs.hashtable.PyObjectHashTable.get_item()

KeyError: 'prs'

During handling of the above exception, another exception occurred:

KeyError                                  Traceback (most recent call last)
<ipython-input-113-53c6420b43b3> in <module>()
      1 # by open pr count
----> 2 df.sort_values(by=['prs'], ascending=False)

~/anaconda3/envs/pyquery/lib/python3.6/site-packages/pandas/core/frame.py in sort_values(self, by, axis, ascending, inplace, kind, na_position)
   3617
   3618             by = by[0]
-> 3619             k = self.xs(by, axis=other_axis).values
   3620             if k.ndim == 2:
   3621

~/anaconda3/envs/pyquery/lib/python3.6/site-packages/pandas/core/generic.py in xs(self, key, axis, level, drop_level)
   2333
   2334         if axis == 1:
-> 2335             return self[key]
   2336
   2337         self._consolidate_inplace()

~/anaconda3/envs/pyquery/lib/python3.6/site-packages/pandas/core/frame.py in __getitem__(self, key)
   2137             return self._getitem_multilevel(key)
   2138         else:
-> 2139             return self._getitem_column(key)
   2140
   2141     def _getitem_column(self, key):

~/anaconda3/envs/pyquery/lib/python3.6/site-packages/pandas/core/frame.py in _getitem_column(self, key)
   2144         # get column
   2145         if self.columns.is_unique:
-> 2146             return self._get_item_cache(key)
   2147
   2148         # duplicate columns & possible reduce dimensionality

~/anaconda3/envs/pyquery/lib/python3.6/site-packages/pandas/core/generic.py in _get_item_cache(self, item)
   1840         res = cache.get(item)
   1841         if res is None:
-> 1842             values = self._data.get(item)
   1843             res = self._box_item_values(item, values)
   1844             cache[item] = res

~/anaconda3/envs/pyquery/lib/python3.6/site-packages/pandas/core/internals.py in get(self, item, fastpath)
   3836
   3837             if not isna(item):
-> 3838                 loc = self.items.get_loc(item)
   3839             else:
   3840                 indexer = np.arange(len(self.items))[isna(self.items)]

~/anaconda3/envs/pyquery/lib/python3.6/site-packages/pandas/core/indexes/base.py in get_loc(self, key, method, tolerance)
   2522                 return self._engine.get_loc(key)
   2523             except KeyError:
-> 2524                 return self._engine.get_loc(self._maybe_cast_indexer(key))
   2525
   2526         indexer = self.get_indexer([key], method=method, tolerance=tolerance)

pandas/_libs/index.pyx in pandas._libs.index.IndexEngine.get_loc()

pandas/_libs/index.pyx in pandas._libs.index.IndexEngine.get_loc()

pandas/_libs/hashtable_class_helper.pxi in pandas._libs.hashtable.PyObjectHashTable.get_item()

pandas/_libs/hashtable_class_helper.pxi in pandas._libs.hashtable.PyObjectHashTable.get_item()

KeyError: 'prs'
In [ ]:
# output data to a csv
# df.to_csv('issue_report.csv')