{"action":"created","comment":{"url":"https://api.github.com/repos/wgwz/canvas-lms-tools/pulls/comments/203160570","pull_request_review_id":137996833,"id":203160570,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIwMzE2MDU3MA==","diff_hunk":"@@ -0,0 +1,178 @@\n+import logging\n+import requests\n+from requests import Response\n+from typing import Any, Dict, Iterator, Optional\n+from urllib.parse import urljoin\n+\n+from evalkit_api_client.errors import APIPaginationException\n+from evalkit_api_client.interface import EvalKitAPIClient\n+from evalkit_api_client.types import RequestHeaders, RequestParams\n+\n+logger = logging.getLogger()\n+\n+\n+class EvalKitAPIv1(EvalKitAPIClient):\n+    \"\"\"\n+    Evalkit v1 API Client.\n+\n+    This client can be used to make requests to the v1 Evalkit API.\n+\n+    Create separate clients for other versions of the Evalkit API.\n+    \"\"\"\n+\n+    def __init__(self,\n+                 api_url: str,\n+                 api_token: Optional[str] = None) -> None:\n+        \"\"\"\n+        Creates a evalkit API client given a base URL for the API, an optional\n+        API token, and an optional requests library.\n+\n+        The optional requests library should be either the python HTTP requests\n+        library or the equivalent (e.g. a Requests-OAuthlib session object).\n+        \"\"\"\n+        self._api_url = api_url\n+        self._api_token = api_token\n+\n+    def _get_url(self, endpoint: str) -> str:\n+        \"\"\"\n+        Formats a EvalKit API URL from a given endpoint.\n+        \"\"\"\n+        return urljoin(self._api_url, endpoint)\n+\n+    def _add_bearer_token(self, headers: Dict[str, Any]):\n+        \"\"\"\n+        Adds the authentication bearer token. Only run this if the token\n+        exists.\n+        \"\"\"\n+        headers.update({'AuthToken': self._api_token})\n+\n+    def _send_request(self,\n+                      callback,\n+                      url: str,\n+                      exit_on_error: bool = True,\n+                      headers: RequestHeaders = None,\n+                      params: RequestParams = None,\n+                      **kwargs) -> Response:\n+        \"\"\"\n+        Sends an API call to the Evalkit server via callback method.\n+\n+        The callback should be a requests.<func> function or the equivalent.\n+\n+        Note: since raise_for_status() will raise an exception for error\n+        codes, the user is responsible for catching `HTTPError`\n+        exceptions unless they run with the exit_on_error set to False.\n+        \"\"\"\n+        if headers is None:\n+            headers = {}\n+        if params is None:\n+            params = {}\n+\n+        if self._api_token is not None:\n+            self._add_bearer_token(headers)\n+\n+        response = callback(url, headers=headers, params=params, **kwargs)\n+        if not response.ok:\n+            logger.debug('Error status code for url \"{}\"'.format(response.url))\n+        if exit_on_error:\n+            response.raise_for_status()\n+\n+        return response\n+\n+    def _get(self, *args, **kwargs) -> Response:\n+        \"\"\"\n+        Sends a GET request to the API.\n+        \"\"\"\n+        return self._send_request(\n+            requests.get, *args, **kwargs)  # type: ignore\n+\n+    def _delete(self, *args, **kwargs) -> Response:\n+        \"\"\"\n+        Sends a DELETE request to the API.\n+        \"\"\"\n+        return self._send_request(\n+            requests.delete, *args, **kwargs)  # type: ignore\n+\n+    def _post(self, *args, **kwargs) -> Response:\n+        \"\"\"\n+        Sends a POST request to the API.\n+        \"\"\"\n+        return self._send_request(\n+            requests.post, *args, **kwargs)  # type: ignore\n+\n+    def _put(self, *args, **kwargs) -> Response:\n+        \"\"\"\n+        Sends a PUT request to the API.\n+        \"\"\"\n+        return self._send_request(\n+            requests.put, *args, **kwargs)  # type: ignore\n+\n+    def _get_validated_page_json(self,\n+                       url: str,\n+                       headers: RequestHeaders = None,\n+                       params: RequestParams = None) -> Dict:\n+        response = self._get(url, headers=headers, params=params)\n+\n+        resp_json = response.json()\n+        try:\n+            page = resp_json['page']\n+            page_size = resp_json['pageSize']\n+            result_list = resp_json['resultList']\n+        except KeyError:\n+            raise APIPaginationException(\n+                'Pagination is not available for this endpoint')\n+\n+        return resp_json\n+\n+    def _get_paginated(self,\n+                       url: str,\n+                       headers: RequestHeaders = None,\n+                       params: RequestParams = None) -> Iterator[Dict]:\n+        \"\"\"\n+        Send an API call to the evalkit server with pagination.\n+\n+        Returns a generator of dictionary objects.\n+\n+        TODO: Evalkit's pagination is broken, but this logic works the way","path":"evalkit_api_client/evalkit_api_client/v1_client.py","position":null,"original_position":135,"commit_id":"7c2263d2fa9ae2ebead77d676f4fd0a6f78e0262","original_commit_id":"d7b3a981858acf74d9fbc58d273923ca1a323f4f","user":{"login":"grvsmth","id":6883981,"node_id":"MDQ6VXNlcjY4ODM5ODE=","avatar_url":"https://avatars1.githubusercontent.com/u/6883981?v=4","gravatar_id":"","url":"https://api.github.com/users/grvsmth","html_url":"https://github.com/grvsmth","followers_url":"https://api.github.com/users/grvsmth/followers","following_url":"https://api.github.com/users/grvsmth/following{/other_user}","gists_url":"https://api.github.com/users/grvsmth/gists{/gist_id}","starred_url":"https://api.github.com/users/grvsmth/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/grvsmth/subscriptions","organizations_url":"https://api.github.com/users/grvsmth/orgs","repos_url":"https://api.github.com/users/grvsmth/repos","events_url":"https://api.github.com/users/grvsmth/events{/privacy}","received_events_url":"https://api.github.com/users/grvsmth/received_events","type":"User","site_admin":false},"body":"Is this still the case?","created_at":"2018-07-17T20:06:52Z","updated_at":"2018-07-17T20:06:53Z","html_url":"https://github.com/wgwz/canvas-lms-tools/pull/22#discussion_r203160570","pull_request_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/pulls/22","author_association":"COLLABORATOR","_links":{"self":{"href":"https://api.github.com/repos/wgwz/canvas-lms-tools/pulls/comments/203160570"},"html":{"href":"https://github.com/wgwz/canvas-lms-tools/pull/22#discussion_r203160570"},"pull_request":{"href":"https://api.github.com/repos/wgwz/canvas-lms-tools/pulls/22"}}},"pull_request":{"url":"https://api.github.com/repos/wgwz/canvas-lms-tools/pulls/22","id":196274332,"node_id":"MDExOlB1bGxSZXF1ZXN0MTk2Mjc0MzMy","html_url":"https://github.com/wgwz/canvas-lms-tools/pull/22","diff_url":"https://github.com/wgwz/canvas-lms-tools/pull/22.diff","patch_url":"https://github.com/wgwz/canvas-lms-tools/pull/22.patch","issue_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/issues/22","number":22,"state":"open","locked":false,"title":"minimal setup for evalkit","user":{"login":"wgwz","id":10120306,"node_id":"MDQ6VXNlcjEwMTIwMzA2","avatar_url":"https://avatars2.githubusercontent.com/u/10120306?v=4","gravatar_id":"","url":"https://api.github.com/users/wgwz","html_url":"https://github.com/wgwz","followers_url":"https://api.github.com/users/wgwz/followers","following_url":"https://api.github.com/users/wgwz/following{/other_user}","gists_url":"https://api.github.com/users/wgwz/gists{/gist_id}","starred_url":"https://api.github.com/users/wgwz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wgwz/subscriptions","organizations_url":"https://api.github.com/users/wgwz/orgs","repos_url":"https://api.github.com/users/wgwz/repos","events_url":"https://api.github.com/users/wgwz/events{/privacy}","received_events_url":"https://api.github.com/users/wgwz/received_events","type":"User","site_admin":false},"body":"- [x] test","created_at":"2018-06-20T21:14:44Z","updated_at":"2018-07-17T20:06:53Z","closed_at":null,"merged_at":null,"merge_commit_sha":"5bde9e7a092ab2dd5ff6eb8a63549ac26dbe79c8","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/pulls/22/commits","review_comments_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/pulls/22/comments","review_comment_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/pulls/comments{/number}","comments_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/issues/22/comments","statuses_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/statuses/7c2263d2fa9ae2ebead77d676f4fd0a6f78e0262","head":{"label":"wgwz:kl3020/evalkit","ref":"kl3020/evalkit","sha":"7c2263d2fa9ae2ebead77d676f4fd0a6f78e0262","user":{"login":"wgwz","id":10120306,"node_id":"MDQ6VXNlcjEwMTIwMzA2","avatar_url":"https://avatars2.githubusercontent.com/u/10120306?v=4","gravatar_id":"","url":"https://api.github.com/users/wgwz","html_url":"https://github.com/wgwz","followers_url":"https://api.github.com/users/wgwz/followers","following_url":"https://api.github.com/users/wgwz/following{/other_user}","gists_url":"https://api.github.com/users/wgwz/gists{/gist_id}","starred_url":"https://api.github.com/users/wgwz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wgwz/subscriptions","organizations_url":"https://api.github.com/users/wgwz/orgs","repos_url":"https://api.github.com/users/wgwz/repos","events_url":"https://api.github.com/users/wgwz/events{/privacy}","received_events_url":"https://api.github.com/users/wgwz/received_events","type":"User","site_admin":false},"repo":{"id":118639165,"node_id":"MDEwOlJlcG9zaXRvcnkxMTg2MzkxNjU=","name":"canvas-lms-tools","full_name":"wgwz/canvas-lms-tools","owner":{"login":"wgwz","id":10120306,"node_id":"MDQ6VXNlcjEwMTIwMzA2","avatar_url":"https://avatars2.githubusercontent.com/u/10120306?v=4","gravatar_id":"","url":"https://api.github.com/users/wgwz","html_url":"https://github.com/wgwz","followers_url":"https://api.github.com/users/wgwz/followers","following_url":"https://api.github.com/users/wgwz/following{/other_user}","gists_url":"https://api.github.com/users/wgwz/gists{/gist_id}","starred_url":"https://api.github.com/users/wgwz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wgwz/subscriptions","organizations_url":"https://api.github.com/users/wgwz/orgs","repos_url":"https://api.github.com/users/wgwz/repos","events_url":"https://api.github.com/users/wgwz/events{/privacy}","received_events_url":"https://api.github.com/users/wgwz/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/wgwz/canvas-lms-tools","description":"Tools and Libraries for Canvas LMS Integration","fork":false,"url":"https://api.github.com/repos/wgwz/canvas-lms-tools","forks_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/forks","keys_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/keys{/key_id}","collaborators_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/teams","hooks_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/hooks","issue_events_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/issues/events{/number}","events_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/events","assignees_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/assignees{/user}","branches_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/branches{/branch}","tags_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/tags","blobs_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/git/refs{/sha}","trees_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/git/trees{/sha}","statuses_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/statuses/{sha}","languages_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/languages","stargazers_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/stargazers","contributors_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/contributors","subscribers_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/subscribers","subscription_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/subscription","commits_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/commits{/sha}","git_commits_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/git/commits{/sha}","comments_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/comments{/number}","issue_comment_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/issues/comments{/number}","contents_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/contents/{+path}","compare_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/compare/{base}...{head}","merges_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/merges","archive_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/downloads","issues_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/issues{/number}","pulls_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/pulls{/number}","milestones_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/milestones{/number}","notifications_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/labels{/name}","releases_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/releases{/id}","deployments_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/deployments","created_at":"2018-01-23T16:44:30Z","updated_at":"2018-07-05T14:59:23Z","pushed_at":"2018-07-17T16:02:57Z","git_url":"git://github.com/wgwz/canvas-lms-tools.git","ssh_url":"git@github.com:wgwz/canvas-lms-tools.git","clone_url":"https://github.com/wgwz/canvas-lms-tools.git","svn_url":"https://github.com/wgwz/canvas-lms-tools","homepage":null,"size":2444,"stargazers_count":3,"watchers_count":3,"language":"Python","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":1,"mirror_url":null,"archived":false,"open_issues_count":3,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0","node_id":"MDc6TGljZW5zZTI="},"forks":1,"open_issues":3,"watchers":3,"default_branch":"master"}},"base":{"label":"wgwz:master","ref":"master","sha":"adf6cfe907f0e3ec2128ddd13c4a797168c74013","user":{"login":"wgwz","id":10120306,"node_id":"MDQ6VXNlcjEwMTIwMzA2","avatar_url":"https://avatars2.githubusercontent.com/u/10120306?v=4","gravatar_id":"","url":"https://api.github.com/users/wgwz","html_url":"https://github.com/wgwz","followers_url":"https://api.github.com/users/wgwz/followers","following_url":"https://api.github.com/users/wgwz/following{/other_user}","gists_url":"https://api.github.com/users/wgwz/gists{/gist_id}","starred_url":"https://api.github.com/users/wgwz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wgwz/subscriptions","organizations_url":"https://api.github.com/users/wgwz/orgs","repos_url":"https://api.github.com/users/wgwz/repos","events_url":"https://api.github.com/users/wgwz/events{/privacy}","received_events_url":"https://api.github.com/users/wgwz/received_events","type":"User","site_admin":false},"repo":{"id":118639165,"node_id":"MDEwOlJlcG9zaXRvcnkxMTg2MzkxNjU=","name":"canvas-lms-tools","full_name":"wgwz/canvas-lms-tools","owner":{"login":"wgwz","id":10120306,"node_id":"MDQ6VXNlcjEwMTIwMzA2","avatar_url":"https://avatars2.githubusercontent.com/u/10120306?v=4","gravatar_id":"","url":"https://api.github.com/users/wgwz","html_url":"https://github.com/wgwz","followers_url":"https://api.github.com/users/wgwz/followers","following_url":"https://api.github.com/users/wgwz/following{/other_user}","gists_url":"https://api.github.com/users/wgwz/gists{/gist_id}","starred_url":"https://api.github.com/users/wgwz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wgwz/subscriptions","organizations_url":"https://api.github.com/users/wgwz/orgs","repos_url":"https://api.github.com/users/wgwz/repos","events_url":"https://api.github.com/users/wgwz/events{/privacy}","received_events_url":"https://api.github.com/users/wgwz/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/wgwz/canvas-lms-tools","description":"Tools and Libraries for Canvas LMS Integration","fork":false,"url":"https://api.github.com/repos/wgwz/canvas-lms-tools","forks_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/forks","keys_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/keys{/key_id}","collaborators_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/teams","hooks_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/hooks","issue_events_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/issues/events{/number}","events_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/events","assignees_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/assignees{/user}","branches_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/branches{/branch}","tags_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/tags","blobs_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/git/refs{/sha}","trees_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/git/trees{/sha}","statuses_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/statuses/{sha}","languages_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/languages","stargazers_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/stargazers","contributors_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/contributors","subscribers_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/subscribers","subscription_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/subscription","commits_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/commits{/sha}","git_commits_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/git/commits{/sha}","comments_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/comments{/number}","issue_comment_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/issues/comments{/number}","contents_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/contents/{+path}","compare_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/compare/{base}...{head}","merges_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/merges","archive_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/downloads","issues_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/issues{/number}","pulls_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/pulls{/number}","milestones_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/milestones{/number}","notifications_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/labels{/name}","releases_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/releases{/id}","deployments_url":"https://api.github.com/repos/wgwz/canvas-lms-tools/deployments","created_at":"2018-01-23T16:44:30Z","updated_at":"2018-07-05T14:59:23Z","pushed_at":"2018-07-17T16:02:57Z","git_url":"git://github.com/wgwz/canvas-lms-tools.git","ssh_url":"git@github.com:wgwz/canvas-lms-tools.git","clone_url":"https://github.com/wgwz/canvas-lms-tools.git","svn_url":"https://github.com/wgwz/canvas-lms-tools","homepage":null,"size":2444,"stargazers_count":3,"watchers_count":3,"language":"Python","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":1,"mirror_url":null,"archived":false,"open_issues_count":3,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0","node_id":"MDc6TGljZW5zZTI="},"forks":1,"open_issues":3,"watchers":3,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/wgwz/canvas-lms-tools/pulls/22"},"html":{"href":"https://github.com/wgwz/canvas-lms-tools/pull/22"},"issue":{"href":"https://api.github.com/repos/wgwz/canvas-lms-tools/issues/22"},"comments":{"href":"https://api.github.com/repos/wgwz/canvas-lms-tools/issues/22/comments"},"review_comments":{"href":"https://api.github.com/repos/wgwz/canvas-lms-tools/pulls/22/comments"},"review_comment":{"href":"https://api.github.com/repos/wgwz/canvas-lms-tools/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/wgwz/canvas-lms-tools/pulls/22/commits"},"statuses":{"href":"https://api.github.com/repos/wgwz/canvas-lms-tools/statuses/7c2263d2fa9ae2ebead77d676f4fd0a6f78e0262"}},"author_association":"OWNER"}}
{"actor":{"display_login":"grvsmth"}}