{"action":"created","comment":{"url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/pulls/comments/58173023","id":58173023,"diff_hunk":"@@ -0,0 +1,185 @@\n+\"\"\"Implements the HintProtocol, which generates hints for students\n+that are stuck on a coding question. The protocol uses analytics\n+to determine whether a hint should be given and then\n+obtains them from the hint generation server. Free response questions\n+are posed before and after hints are provided.\n+\"\"\"\n+\n+from client.sources.common import core\n+from client.sources.common import models as sources_models\n+from client.protocols.common import models as protocol_models\n+from client.utils import auth\n+from client.utils import format\n+\n+import json\n+import logging\n+import os\n+import pickle\n+import random\n+import re\n+import urllib.error\n+import urllib.request\n+\n+log = logging.getLogger(__name__)\n+\n+#####################\n+# Hinting Mechanism #\n+#####################\n+\n+class HintingProtocol(protocol_models.Protocol):\n+    \"\"\"A protocol that provides rubber duck debugging and hints if applicable.\n+    \"\"\"\n+\n+    HINT_SERVER = \"http://146.148.59.194:5000/\"\n+    HINT_ENDPOINT = 'api/hints'\n+\n+    def run(self, messages):\n+        \"\"\"Determine if a student is elgible to recieve a hint. Based on their\n+        state, poses reflection questions.\n+\n+        After more attempts, ask if students would like hints. If so, query\n+        the server.\n+        \"\"\"\n+        if self.args.local:\n+            return\n+\n+        if 'analytics' not in messages:\n+            log.info('Analytics Protocol is required for hint generation')\n+            return\n+        if 'file_contents' not in messages:\n+            log.info('File Contents needed to generate hints')\n+            return\n+\n+        messages['hinting'] = {}\n+        history = messages['analytics']['history']\n+        questions = history['questions']\n+        current_q = history['question']\n+\n+        for question in current_q:\n+            if question not in questions:\n+                continue\n+            stats = questions[question]\n+            messages['hinting'][question] = {'prompts': {}, 'reflection': {}}\n+            hint_info = messages['hinting'][question]\n+\n+            # Only prompt\n+            if (stats['solved'] and stats['attempts'] > 6):\n+                hint_info['elgible'] = False\n+                if self.args.question:\n+                    # Only prompt for reflection with question specified.\n+                    log.info('Giving reflection response on %s', question)\n+                    reflection = random.choice(SOLVE_SUCCESS_MSG)\n+                    if not confirm(\"Nice work! Could you answer a quick question\"\n+                                   \" about how you approached this question?\"):\n+                        hint_info['reflection']['accept'] = False\n+                    else:\n+                        hint_info['reflection']['accept'] = True\n+                    prompt_user(reflection, hint_info)\n+            elif (stats['attempts'] < 5):\n+                log.info(\"Question %s is not elgible: Attempts: %s, Solved: %s\",\n+                         question, stats['attempts'], stats['solved'])\n+                hint_info['elgible'] = False\n+            else:\n+                hint_info['elgible'] = not stats['solved']\n+\n+            if not hint_info['elgible']:\n+                continue\n+            log.info('Prompting for hint on %s', question)\n+\n+            if confirm(\"Check for hints on {}?\".format(question)):\n+                hint_info['accept'] = True\n+                print(\"Thinking... (could take upto 15 seconds)\", end='')\n+                try:\n+                    response = self.query_server(messages, question)\n+                    hint_info['response'] = response\n+\n+                    hint = response['message']\n+                    pre_prompt = response['pre-prompt']\n+                    post_prompt = response['post-prompt']\n+                    log.info(\"Hint server response: {}\".format(response))\n+                    if not hint and not pre_prompt:\n+                        print(\"\\nSorry. No hints found for {}\".format(question))\n+                        continue\n+\n+                    if pre_prompt:\n+                        print(\"\\r-- While we wait, respond to this question.\"\n+                              \" When you are done typing, press Enter.\")\n+                        if not prompt_user(pre_prompt, hint_info):\n+                            # Do not provide hint, if no response from user\n+                            continue\n+\n+                    # Provide padding for the the hint\n+                    print(\"\\n{}\\n\".format(hint))\n+\n+                    if post_prompt:\n+                        prompt_user(post_prompt, hint_info)\n+\n+                except urllib.error.URLError:\n+                    log.debug(\"Network error while fetching hint\")\n+                    hint_info['fetch_error'] = True\n+                    print(\"\\r\\nCould not get a hint.\")\n+            else:\n+                log.info('Declined Hints for %s', question)\n+                hint_info['accept'] = False\n+\n+    def query_server(self, messages, test):\n+        access_token, _, _ = auth.get_storage()\n+        user = auth.get_student_email(access_token) or access_token\n+        if user:\n+            user = hash(user)\n+        data = {\n+            'assignment': self.assignment.endpoint,\n+            'test': test,\n+            'messages': messages,\n+            'user': user\n+        }\n+\n+        serialized_data = json.dumps(data).encode(encoding='utf-8')\n+\n+        address = self.HINT_SERVER + self.HINT_ENDPOINT\n+\n+        log.info('Sending hint request to %s', address)\n+        request = urllib.request.Request(address)\n+        request.add_header(\"Content-Type\", \"application/json\")\n+\n+        response = urllib.request.urlopen(request, serialized_data, 10)\n+        return json.loads(response.read().decode('utf-8'))\n+\n+def prompt_user(query, results):\n+    try:\n+        response = None\n+        short_resps = 0\n+        while not response or response == '':\n+            response = input(\"{}\\nYour Response: \".format(query))\n+            if not response or response == '':\n+                short_resps += 1\n+                if short_resps > 2:\n+                    break\n+                print(\"Please enter at least a sentence.\")\n+        results['prompts'][query] = response\n+\n+        return response\n+    except KeyboardInterrupt:\n+        # Hack for windows:\n+        results['prompts'][query] = 'KeyboardInterrupt'\n+        try:\n+            print(\"Exiting Hint\") # Second I/O will get KeyboardInterrupt\n+            return ''\n+        except KeyboardInterrupt:\n+            return ''\n+\n+def confirm(message):\n+    response = input(\"{} [yes/no]: \".format(message))\n+    return response.lower() == \"yes\" or response.lower() == \"y\"\n+\n+","path":"client/protocols/hinting.py","position":175,"original_position":175,"commit_id":"b526084e9a63e65ae3f26de3365801fc8b304971","original_commit_id":"b526084e9a63e65ae3f26de3365801fc8b304971","user":{"login":"albert12132","id":2187524,"avatar_url":"https://avatars.githubusercontent.com/u/2187524?v=3","gravatar_id":"","url":"https://api.github.com/users/albert12132","html_url":"https://github.com/albert12132","followers_url":"https://api.github.com/users/albert12132/followers","following_url":"https://api.github.com/users/albert12132/following{/other_user}","gists_url":"https://api.github.com/users/albert12132/gists{/gist_id}","starred_url":"https://api.github.com/users/albert12132/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/albert12132/subscriptions","organizations_url":"https://api.github.com/users/albert12132/orgs","repos_url":"https://api.github.com/users/albert12132/repos","events_url":"https://api.github.com/users/albert12132/events{/privacy}","received_events_url":"https://api.github.com/users/albert12132/received_events","type":"User","site_admin":false},"body":"There should only be up to 2 blank lines following this function.","created_at":"2016-04-01T07:54:37Z","updated_at":"2016-04-01T07:54:37Z","html_url":"https://github.com/Cal-CS-61A-Staff/ok-client/pull/169#discussion_r58173023","pull_request_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/pulls/169","_links":{"self":{"href":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/pulls/comments/58173023"},"html":{"href":"https://github.com/Cal-CS-61A-Staff/ok-client/pull/169#discussion_r58173023"},"pull_request":{"href":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/pulls/169"}}},"pull_request":{"url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/pulls/169","id":64247366,"html_url":"https://github.com/Cal-CS-61A-Staff/ok-client/pull/169","diff_url":"https://github.com/Cal-CS-61A-Staff/ok-client/pull/169.diff","patch_url":"https://github.com/Cal-CS-61A-Staff/ok-client/pull/169.patch","issue_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/issues/169","number":169,"state":"open","locked":false,"title":"Hint Generation Protocol","user":{"login":"Sumukh","id":882381,"avatar_url":"https://avatars.githubusercontent.com/u/882381?v=3","gravatar_id":"","url":"https://api.github.com/users/Sumukh","html_url":"https://github.com/Sumukh","followers_url":"https://api.github.com/users/Sumukh/followers","following_url":"https://api.github.com/users/Sumukh/following{/other_user}","gists_url":"https://api.github.com/users/Sumukh/gists{/gist_id}","starred_url":"https://api.github.com/users/Sumukh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Sumukh/subscriptions","organizations_url":"https://api.github.com/users/Sumukh/orgs","repos_url":"https://api.github.com/users/Sumukh/repos","events_url":"https://api.github.com/users/Sumukh/events{/privacy}","received_events_url":"https://api.github.com/users/Sumukh/received_events","type":"User","site_admin":false},"body":"Changes to Ok:\r\n* The analytics protocol now keeps track of the number of attempts per question and overall. This info is included in the analytics messages (and stored locally as `.ok_history`) \r\n   * `analytics` should be run after the `grading` protocol for full functionality\r\n\r\nAdditions:\r\n* Hint generation protocol: It queries the server for changes and displays hints along the lines of: \r\n\r\n> The computer thinks that the conditional expression on line 4 has some errors.\r\n\r\nIt also provides rubber duck debugging prompts to help guide students to solve questions themselves. \r\n\r\nThe prompts are along the lines of:\r\n> What kinds of debugging strategies have you tried? [List of strategies]: \r\n> Could you describe what the error is for the computer?: \r\n\r\n(after hint is displayed and student corrects error) \r\n> Could you summarize for the computer what you had to change to fix the bug? \r\n> If another student had the same error you had, what advice would you give them? \r\n> How helpful was the hint that the computer provided? [1 as not helpful, 5 as very helpful]: \r\n\r\nFor code review: \r\n- I'd appreciate comments on the changes I've made to the analytics protocol. \r\n- It's likely that the hint protocol won't be used in this form for long (the plan is that it is used for one assignment), so maintenance of that protocol isn't too big of a concern)","created_at":"2016-03-26T19:57:20Z","updated_at":"2016-04-01T07:54:37Z","closed_at":null,"merged_at":null,"merge_commit_sha":"c1c6b5aa3b099a0080d27c0d609dc27be8c60e38","assignee":{"login":"albert12132","id":2187524,"avatar_url":"https://avatars.githubusercontent.com/u/2187524?v=3","gravatar_id":"","url":"https://api.github.com/users/albert12132","html_url":"https://github.com/albert12132","followers_url":"https://api.github.com/users/albert12132/followers","following_url":"https://api.github.com/users/albert12132/following{/other_user}","gists_url":"https://api.github.com/users/albert12132/gists{/gist_id}","starred_url":"https://api.github.com/users/albert12132/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/albert12132/subscriptions","organizations_url":"https://api.github.com/users/albert12132/orgs","repos_url":"https://api.github.com/users/albert12132/repos","events_url":"https://api.github.com/users/albert12132/events{/privacy}","received_events_url":"https://api.github.com/users/albert12132/received_events","type":"User","site_admin":false},"milestone":null,"commits_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/pulls/169/commits","review_comments_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/pulls/169/comments","review_comment_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/pulls/comments{/number}","comments_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/issues/169/comments","statuses_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/statuses/b526084e9a63e65ae3f26de3365801fc8b304971","head":{"label":"Cal-CS-61A-Staff:enhancement/sumukh/hintgeneration","ref":"enhancement/sumukh/hintgeneration","sha":"b526084e9a63e65ae3f26de3365801fc8b304971","user":{"login":"Cal-CS-61A-Staff","id":7565272,"avatar_url":"https://avatars.githubusercontent.com/u/7565272?v=3","gravatar_id":"","url":"https://api.github.com/users/Cal-CS-61A-Staff","html_url":"https://github.com/Cal-CS-61A-Staff","followers_url":"https://api.github.com/users/Cal-CS-61A-Staff/followers","following_url":"https://api.github.com/users/Cal-CS-61A-Staff/following{/other_user}","gists_url":"https://api.github.com/users/Cal-CS-61A-Staff/gists{/gist_id}","starred_url":"https://api.github.com/users/Cal-CS-61A-Staff/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Cal-CS-61A-Staff/subscriptions","organizations_url":"https://api.github.com/users/Cal-CS-61A-Staff/orgs","repos_url":"https://api.github.com/users/Cal-CS-61A-Staff/repos","events_url":"https://api.github.com/users/Cal-CS-61A-Staff/events{/privacy}","received_events_url":"https://api.github.com/users/Cal-CS-61A-Staff/received_events","type":"Organization","site_admin":false},"repo":{"id":29032660,"name":"ok-client","full_name":"Cal-CS-61A-Staff/ok-client","owner":{"login":"Cal-CS-61A-Staff","id":7565272,"avatar_url":"https://avatars.githubusercontent.com/u/7565272?v=3","gravatar_id":"","url":"https://api.github.com/users/Cal-CS-61A-Staff","html_url":"https://github.com/Cal-CS-61A-Staff","followers_url":"https://api.github.com/users/Cal-CS-61A-Staff/followers","following_url":"https://api.github.com/users/Cal-CS-61A-Staff/following{/other_user}","gists_url":"https://api.github.com/users/Cal-CS-61A-Staff/gists{/gist_id}","starred_url":"https://api.github.com/users/Cal-CS-61A-Staff/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Cal-CS-61A-Staff/subscriptions","organizations_url":"https://api.github.com/users/Cal-CS-61A-Staff/orgs","repos_url":"https://api.github.com/users/Cal-CS-61A-Staff/repos","events_url":"https://api.github.com/users/Cal-CS-61A-Staff/events{/privacy}","received_events_url":"https://api.github.com/users/Cal-CS-61A-Staff/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Cal-CS-61A-Staff/ok-client","description":"A Python client for the OK autograding system","fork":false,"url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client","forks_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/forks","keys_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/teams","hooks_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/hooks","issue_events_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/issues/events{/number}","events_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/events","assignees_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/assignees{/user}","branches_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/branches{/branch}","tags_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/tags","blobs_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/git/refs{/sha}","trees_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/statuses/{sha}","languages_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/languages","stargazers_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/stargazers","contributors_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/contributors","subscribers_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/subscribers","subscription_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/subscription","commits_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/commits{/sha}","git_commits_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/git/commits{/sha}","comments_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/comments{/number}","issue_comment_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/issues/comments{/number}","contents_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/contents/{+path}","compare_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/merges","archive_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/downloads","issues_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/issues{/number}","pulls_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/pulls{/number}","milestones_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/milestones{/number}","notifications_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/labels{/name}","releases_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/releases{/id}","deployments_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/deployments","created_at":"2015-01-09T19:53:07Z","updated_at":"2016-01-25T00:48:46Z","pushed_at":"2016-04-01T04:05:07Z","git_url":"git://github.com/Cal-CS-61A-Staff/ok-client.git","ssh_url":"git@github.com:Cal-CS-61A-Staff/ok-client.git","clone_url":"https://github.com/Cal-CS-61A-Staff/ok-client.git","svn_url":"https://github.com/Cal-CS-61A-Staff/ok-client","homepage":"https://okpy.org/","size":581,"stargazers_count":8,"watchers_count":8,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":4,"mirror_url":null,"open_issues_count":21,"forks":4,"open_issues":21,"watchers":8,"default_branch":"master"}},"base":{"label":"Cal-CS-61A-Staff:master","ref":"master","sha":"7500e3900667e8db24a91164f4836684c1483b0a","user":{"login":"Cal-CS-61A-Staff","id":7565272,"avatar_url":"https://avatars.githubusercontent.com/u/7565272?v=3","gravatar_id":"","url":"https://api.github.com/users/Cal-CS-61A-Staff","html_url":"https://github.com/Cal-CS-61A-Staff","followers_url":"https://api.github.com/users/Cal-CS-61A-Staff/followers","following_url":"https://api.github.com/users/Cal-CS-61A-Staff/following{/other_user}","gists_url":"https://api.github.com/users/Cal-CS-61A-Staff/gists{/gist_id}","starred_url":"https://api.github.com/users/Cal-CS-61A-Staff/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Cal-CS-61A-Staff/subscriptions","organizations_url":"https://api.github.com/users/Cal-CS-61A-Staff/orgs","repos_url":"https://api.github.com/users/Cal-CS-61A-Staff/repos","events_url":"https://api.github.com/users/Cal-CS-61A-Staff/events{/privacy}","received_events_url":"https://api.github.com/users/Cal-CS-61A-Staff/received_events","type":"Organization","site_admin":false},"repo":{"id":29032660,"name":"ok-client","full_name":"Cal-CS-61A-Staff/ok-client","owner":{"login":"Cal-CS-61A-Staff","id":7565272,"avatar_url":"https://avatars.githubusercontent.com/u/7565272?v=3","gravatar_id":"","url":"https://api.github.com/users/Cal-CS-61A-Staff","html_url":"https://github.com/Cal-CS-61A-Staff","followers_url":"https://api.github.com/users/Cal-CS-61A-Staff/followers","following_url":"https://api.github.com/users/Cal-CS-61A-Staff/following{/other_user}","gists_url":"https://api.github.com/users/Cal-CS-61A-Staff/gists{/gist_id}","starred_url":"https://api.github.com/users/Cal-CS-61A-Staff/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Cal-CS-61A-Staff/subscriptions","organizations_url":"https://api.github.com/users/Cal-CS-61A-Staff/orgs","repos_url":"https://api.github.com/users/Cal-CS-61A-Staff/repos","events_url":"https://api.github.com/users/Cal-CS-61A-Staff/events{/privacy}","received_events_url":"https://api.github.com/users/Cal-CS-61A-Staff/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Cal-CS-61A-Staff/ok-client","description":"A Python client for the OK autograding system","fork":false,"url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client","forks_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/forks","keys_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/teams","hooks_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/hooks","issue_events_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/issues/events{/number}","events_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/events","assignees_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/assignees{/user}","branches_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/branches{/branch}","tags_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/tags","blobs_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/git/refs{/sha}","trees_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/statuses/{sha}","languages_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/languages","stargazers_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/stargazers","contributors_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/contributors","subscribers_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/subscribers","subscription_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/subscription","commits_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/commits{/sha}","git_commits_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/git/commits{/sha}","comments_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/comments{/number}","issue_comment_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/issues/comments{/number}","contents_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/contents/{+path}","compare_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/merges","archive_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/downloads","issues_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/issues{/number}","pulls_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/pulls{/number}","milestones_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/milestones{/number}","notifications_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/labels{/name}","releases_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/releases{/id}","deployments_url":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/deployments","created_at":"2015-01-09T19:53:07Z","updated_at":"2016-01-25T00:48:46Z","pushed_at":"2016-04-01T04:05:07Z","git_url":"git://github.com/Cal-CS-61A-Staff/ok-client.git","ssh_url":"git@github.com:Cal-CS-61A-Staff/ok-client.git","clone_url":"https://github.com/Cal-CS-61A-Staff/ok-client.git","svn_url":"https://github.com/Cal-CS-61A-Staff/ok-client","homepage":"https://okpy.org/","size":581,"stargazers_count":8,"watchers_count":8,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":4,"mirror_url":null,"open_issues_count":21,"forks":4,"open_issues":21,"watchers":8,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/pulls/169"},"html":{"href":"https://github.com/Cal-CS-61A-Staff/ok-client/pull/169"},"issue":{"href":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/issues/169"},"comments":{"href":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/issues/169/comments"},"review_comments":{"href":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/pulls/169/comments"},"review_comment":{"href":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/pulls/169/commits"},"statuses":{"href":"https://api.github.com/repos/Cal-CS-61A-Staff/ok-client/statuses/b526084e9a63e65ae3f26de3365801fc8b304971"}}}}