How to Auto-Grade People on Github

Having fun with Github

(note: if your repo is set to private, you will have to go through the authentication process)

Github API docs

The base endpoint is:

To get a single user's data (in this case, the user blahs555:

If you visit that URL, you'll see it returns a JSON file that helpfully lists all the other endpoints.

To get a list of that user's repos:

User events endpoints

Or even the list of the user's latest activity (handy for calculating if you've been committing to Github on a regular basis):

Get a list of last 100 events:

import requests
from datetime import datetime
username = 'blahs555'
url = '' % username
eventdata = requests.get(url).json()
mylist = []
for event in eventdata:
    d = {}
    d['type'] = event['type'] 
    d['repo'] = event['repo']['name']
    d['url'] = event['repo']['url']
    d['timestamp'] = datetime.strptime(event['created_at'], '%Y-%m-%dT%H:%M:%SZ')
    d['days_ago'] = ( - d['timestamp']).days
    if event['payload'].get('commits'):
        d['messages'] = ', '.join([ev.get('message') for ev in event['payload']['commits']])
        d['messages'] = ""


print("\t".join(['type', 'repo', 'days_ago', 'messages']))
for event in mylist:
    print("\t".join([event['type'], event['repo'], str(event['days_ago']), event['messages']]))

How to grade like a bot

But I don't even really need to know the API if all I need to know is: does user X have file Z inside of their repo Y?

For example, if I expect user blahs555 to have a file named json-quiz/ inside of their compjour-hw repo, this is the direct URL which I can visit via web browser:

And with Python, maybe the first thing I check is whether a file even exists:

import requests
url = ''
resp = requests.get(url)
if resp.status_code == 200:
  print("Nice job!")

And so if I have a list of files/folders that I know should exist, then here's an easy auto-grader:

(one key takeaway: notice how if you have any kind of typo in the filename, my grading bot will assume the homework wasn't done. Think about it…)

import requests
REPO_NAME = 'compjour-hw'

def is_assignment_done(url):      
      resp = requests.head(url)
      return resp.status_code == 200 or resp.status_code == 301

def is_passing(username):
    fails = 0
    for f in FILES:
        url = BASEURL % (username, f)
        if is_assignment_done(url) == False:
            print("    FAILED:", f)
            fails += 1
    return fails == 0

for username in ['blahs555', 'dannguyen', 'Stanford']:
    print("Testing user", username)
    x = is_passing(username)
    if x:
        print("  * A:", username)
        print("  * F:", username)