{"action":"created","comment":{"url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/pulls/comments/137083672","pull_request_review_id":60705441,"id":137083672,"diff_hunk":"@@ -0,0 +1,154 @@\n+#!/usr/bin/env python\n+#\n+#\n+# Collects CI artifacts from S3 storage, downloading them\n+# to a local directory.\n+#\n+# The artifacts' folder in the S3 bucket must have the following token\n+# format:\n+#  <token>-[<value>]__   (repeat)\n+#\n+# Recognized tokens (unrecognized tokens are ignored):\n+#  p       - project (e.g., \"confluent-kafka-python\")\n+#  bld     - builder (e.g., \"travis\")\n+#  plat    - platform (\"osx\", \"linux\", ..)\n+#  tag     - git tag\n+#  sha     - git sha\n+#  bid     - builder's build-id\n+#\n+# Example:\n+#   p-confluent-kafka-python__bld-travis__plat-linux__tag-__sha-112130ce297656ea1c39e7c94c99286f95133a24__bid-271588764__/confluent_kafka-0.11.0-cp35-cp35m-manylinux1_x86_64.whl\n+\n+\n+import re\n+import os\n+import argparse\n+\n+import boto3\n+\n+s3_bucket = 'librdkafka-ci-packages'\n+dry_run = False\n+\n+\n+class Artifact (object):\n+    def __init__(self, arts, path, info=None):\n+        self.path = path\n+        # Remove unexpanded AppVeyor $(..) tokens from filename\n+        self.fname = re.sub(r'\\$\\([^\\)]+\\)', '', os.path.basename(path))\n+        self.lpath = os.path.join(arts.dlpath, self.fname)\n+        self.info = info\n+        self.arts = arts\n+        arts.artifacts.append(self)\n+\n+    def __repr__(self):\n+        return self.path\n+\n+    def download(self, dirpath):\n+        \"\"\" Download artifact from S3 and store in dirpath directory.\n+            If the artifact is already downloaded nothing is done. \"\"\"\n+        if os.path.isfile(self.lpath) and os.path.getsize(self.lpath) > 0:\n+            return\n+        print('Downloading %s -> %s' % (self.path, self.lpath))\n+        if dry_run:\n+            return\n+        self.arts.s3_bucket.download_file(self.path, self.lpath)\n+\n+\n+class Artifacts (object):\n+    def __init__(self, gitref, dlpath):\n+        super(Artifacts, self).__init__()\n+        self.gitref = gitref\n+        self.artifacts = list()\n+        # Download directory\n+        self.dlpath = dlpath\n+        if not os.path.isdir(self.dlpath):\n+            if not dry_run:\n+                os.makedirs(self.dlpath, 0o755)\n+\n+    def collect_single_s3(self, path):\n+        \"\"\" Collect single S3 artifact\n+         :param: path string: S3 path\n+        \"\"\"\n+\n+        # The S3 folder contains the tokens needed to perform\n+        # matching of project, gitref, etc.\n+        folder = os.path.dirname(path)\n+\n+        rinfo = re.findall(r'(?P<tag>[^-]+)-(?P<val>.*?)__', folder)\n+        if rinfo is None or len(rinfo) == 0:\n+            # print('Incorrect folder/file name format for %s' % folder)\n+            return None\n+\n+        info = dict(rinfo)\n+\n+        # Ignore AppVeyor Debug builds\n+        if info.get('bldtype', '').lower() == 'debug':\n+            print('Ignoring debug artifact %s' % folder)\n+            return None\n+\n+        tag = info.get('tag', None)\n+        if tag is not None and (len(tag) == 0 or tag.startswith('$(')):\n+            # AppVeyor doesn't substite $(APPVEYOR_REPO_TAG_NAME)\n+            # with an empty value when not set, it leaves that token\n+            # in the string - so translate that to no tag.\n+            tag = None\n+\n+        sha = info.get('sha', None)\n+\n+        # Match tag or sha to gitref\n+        if (tag is not None and tag == self.gitref) or (sha is not None and sha.startswith(self.gitref)):\n+            return Artifact(self, path, info)\n+\n+        return None\n+\n+    def collect_s3(self):\n+        \"\"\" Collect and download build-artifacts from S3 based on git reference \"\"\"\n+        print('Collecting artifacts matching tag/sha %s from S3 bucket %s' % (self.gitref, s3_bucket))\n+        self.s3 = boto3.resource('s3')\n+        self.s3_bucket = self.s3.Bucket(s3_bucket)\n+        self.s3.meta.client.head_bucket(Bucket=s3_bucket)\n+        for key in self.s3_bucket.objects.all():","path":"tools/download-s3.py","position":110,"original_position":110,"commit_id":"dcc0a91195382e6d1b7d735d97f302e6aced7ee2","original_commit_id":"1d97baae8c33d97933740c6c427b92f711ba843e","user":{"login":"edenhill","id":524990,"avatar_url":"https://avatars0.githubusercontent.com/u/524990?v=4","gravatar_id":"","url":"https://api.github.com/users/edenhill","html_url":"https://github.com/edenhill","followers_url":"https://api.github.com/users/edenhill/followers","following_url":"https://api.github.com/users/edenhill/following{/other_user}","gists_url":"https://api.github.com/users/edenhill/gists{/gist_id}","starred_url":"https://api.github.com/users/edenhill/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/edenhill/subscriptions","organizations_url":"https://api.github.com/users/edenhill/orgs","repos_url":"https://api.github.com/users/edenhill/repos","events_url":"https://api.github.com/users/edenhill/events{/privacy}","received_events_url":"https://api.github.com/users/edenhill/received_events","type":"User","site_admin":false},"body":"It will be limited to just tagged builds, but with 3-4 client repositories your point still stands (and it is already kind of slow..).\r\n\r\nFrom a matching perspective we look for two things: the project (confluent-kafka-python, which is already a top-level directory) and the git ref (tag or sha) which is currently included in the sub-directory.\r\nMultiple CI services may provide artifacts for the same git ref, and even multiple artifacts from the same service (e.g., travis-osx, travis-linux, windows-x64, windows-x86, ..).\r\n\r\nIt is not possible to conditionally change the deploy path based on whether a tag is present or not, so the best we can do is:\r\n`confluent-kafka-python/<TAG>-<SHA>/<ci>-<variant>...`\r\n\r\nAnd since we might not be confident that we know both the sha and tag at the same time we would still need to enumerate on confluent-kafka-python/*.\r\n\r\nWe could use just the tag, `confluent-kafka-python/<TAG>/`, but there is no guarantee that it will be unique if the tag is later moved and artifacts rebuilt, which would result in conflicting artifacts under that tag using different SHAs.\r\n\r\nI don't know what's best.\r\n\r\n","created_at":"2017-09-05T18:55:18Z","updated_at":"2017-09-05T18:55:18Z","html_url":"https://github.com/confluentinc/confluent-kafka-python/pull/243#discussion_r137083672","pull_request_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/pulls/243","author_association":"MEMBER","_links":{"self":{"href":"https://api.github.com/repos/confluentinc/confluent-kafka-python/pulls/comments/137083672"},"html":{"href":"https://github.com/confluentinc/confluent-kafka-python/pull/243#discussion_r137083672"},"pull_request":{"href":"https://api.github.com/repos/confluentinc/confluent-kafka-python/pulls/243"}},"in_reply_to_id":137024337},"pull_request":{"url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/pulls/243","id":139200535,"html_url":"https://github.com/confluentinc/confluent-kafka-python/pull/243","diff_url":"https://github.com/confluentinc/confluent-kafka-python/pull/243.diff","patch_url":"https://github.com/confluentinc/confluent-kafka-python/pull/243.patch","issue_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/issues/243","number":243,"state":"open","locked":false,"title":"Build autonomous binary wheels for Linux and OSX","user":{"login":"edenhill","id":524990,"avatar_url":"https://avatars0.githubusercontent.com/u/524990?v=4","gravatar_id":"","url":"https://api.github.com/users/edenhill","html_url":"https://github.com/edenhill","followers_url":"https://api.github.com/users/edenhill/followers","following_url":"https://api.github.com/users/edenhill/following{/other_user}","gists_url":"https://api.github.com/users/edenhill/gists{/gist_id}","starred_url":"https://api.github.com/users/edenhill/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/edenhill/subscriptions","organizations_url":"https://api.github.com/users/edenhill/orgs","repos_url":"https://api.github.com/users/edenhill/repos","events_url":"https://api.github.com/users/edenhill/events{/privacy}","received_events_url":"https://api.github.com/users/edenhill/received_events","type":"User","site_admin":false},"body":"There's a bunch of stuff going on and not going on here:\r\n * Uses [cibuildwheel](https://github.com/joerick/cibuildwheel) to build manylinux and osx wheels on Travis\r\n * The wheels are uploaded from Travis to S3.\r\n * Disabled support for the same on AppVeyor due to messed up Python/C toolchain, will be tended to in the future.\r\n * Some scripts to build and test manylinux locally using docker, these can be used for later use in packaging.\r\n * The .travis.yml file is rewritten to only cater to wheel building, before the merge it will be adjusted to do what it does on master (mainly code verification across Python versions) and the new wheel building stuff when a tag is available.\r\n * There's a script in tools/download-s3.py that fetches the wheels from S3 by tag or git sha. This is used to collect the wheels to publish to PyPi.\r\n * Some corresponding README changes.\r\n\r\nProof-of-concept packages are published to test.pypiy.org as confluent-kafka version 0.11.0.1rc1. Please try them out using the following little snippet:\r\n```\r\nvirtualenv /tmp/pyenv      # Create a throw-away virtualenv\r\nsource /tmp/pyenv/bin/activate\r\npip install -i https://test.pypi.org/simple confluent-kafka==0.11.0.1rc1\r\npython -c 'from confluent_kafka import libversion; assert libversion() == (\"0.11.0\", 0xb00ff), libversion()'\r\ndeactivate\r\n ```\r\n","created_at":"2017-09-04T18:49:13Z","updated_at":"2017-09-05T18:55:18Z","closed_at":null,"merged_at":null,"merge_commit_sha":"cedc0760fbcd0bf443ef6a3263d690a0133a85b8","assignee":null,"assignees":[],"requested_reviewers":[],"milestone":null,"commits_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/pulls/243/commits","review_comments_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/pulls/243/comments","review_comment_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/pulls/comments{/number}","comments_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/issues/243/comments","statuses_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/statuses/dcc0a91195382e6d1b7d735d97f302e6aced7ee2","head":{"label":"confluentinc:manylinux_test","ref":"manylinux_test","sha":"dcc0a91195382e6d1b7d735d97f302e6aced7ee2","user":{"login":"confluentinc","id":9439498,"avatar_url":"https://avatars0.githubusercontent.com/u/9439498?v=4","gravatar_id":"","url":"https://api.github.com/users/confluentinc","html_url":"https://github.com/confluentinc","followers_url":"https://api.github.com/users/confluentinc/followers","following_url":"https://api.github.com/users/confluentinc/following{/other_user}","gists_url":"https://api.github.com/users/confluentinc/gists{/gist_id}","starred_url":"https://api.github.com/users/confluentinc/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/confluentinc/subscriptions","organizations_url":"https://api.github.com/users/confluentinc/orgs","repos_url":"https://api.github.com/users/confluentinc/repos","events_url":"https://api.github.com/users/confluentinc/events{/privacy}","received_events_url":"https://api.github.com/users/confluentinc/received_events","type":"Organization","site_admin":false},"repo":{"id":56217288,"name":"confluent-kafka-python","full_name":"confluentinc/confluent-kafka-python","owner":{"login":"confluentinc","id":9439498,"avatar_url":"https://avatars0.githubusercontent.com/u/9439498?v=4","gravatar_id":"","url":"https://api.github.com/users/confluentinc","html_url":"https://github.com/confluentinc","followers_url":"https://api.github.com/users/confluentinc/followers","following_url":"https://api.github.com/users/confluentinc/following{/other_user}","gists_url":"https://api.github.com/users/confluentinc/gists{/gist_id}","starred_url":"https://api.github.com/users/confluentinc/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/confluentinc/subscriptions","organizations_url":"https://api.github.com/users/confluentinc/orgs","repos_url":"https://api.github.com/users/confluentinc/repos","events_url":"https://api.github.com/users/confluentinc/events{/privacy}","received_events_url":"https://api.github.com/users/confluentinc/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/confluentinc/confluent-kafka-python","description":"Confluent's Apache Kafka Python client","fork":false,"url":"https://api.github.com/repos/confluentinc/confluent-kafka-python","forks_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/forks","keys_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/keys{/key_id}","collaborators_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/teams","hooks_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/hooks","issue_events_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/issues/events{/number}","events_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/events","assignees_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/assignees{/user}","branches_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/branches{/branch}","tags_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/tags","blobs_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/git/refs{/sha}","trees_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/git/trees{/sha}","statuses_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/statuses/{sha}","languages_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/languages","stargazers_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/stargazers","contributors_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/contributors","subscribers_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/subscribers","subscription_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/subscription","commits_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/commits{/sha}","git_commits_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/git/commits{/sha}","comments_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/comments{/number}","issue_comment_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/issues/comments{/number}","contents_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/contents/{+path}","compare_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/compare/{base}...{head}","merges_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/merges","archive_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/downloads","issues_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/issues{/number}","pulls_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/pulls{/number}","milestones_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/milestones{/number}","notifications_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/labels{/name}","releases_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/releases{/id}","deployments_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/deployments","created_at":"2016-04-14T07:40:41Z","updated_at":"2017-09-04T17:30:18Z","pushed_at":"2017-09-05T16:19:27Z","git_url":"git://github.com/confluentinc/confluent-kafka-python.git","ssh_url":"git@github.com:confluentinc/confluent-kafka-python.git","clone_url":"https://github.com/confluentinc/confluent-kafka-python.git","svn_url":"https://github.com/confluentinc/confluent-kafka-python","homepage":"http://docs.confluent.io/current/clients/confluent-kafka-python","size":246,"stargazers_count":360,"watchers_count":360,"language":"Python","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":94,"mirror_url":null,"open_issues_count":36,"forks":94,"open_issues":36,"watchers":360,"default_branch":"master"}},"base":{"label":"confluentinc:master","ref":"master","sha":"960e455fcb3ba5bd4858f3c59d91e0a5aeb2e996","user":{"login":"confluentinc","id":9439498,"avatar_url":"https://avatars0.githubusercontent.com/u/9439498?v=4","gravatar_id":"","url":"https://api.github.com/users/confluentinc","html_url":"https://github.com/confluentinc","followers_url":"https://api.github.com/users/confluentinc/followers","following_url":"https://api.github.com/users/confluentinc/following{/other_user}","gists_url":"https://api.github.com/users/confluentinc/gists{/gist_id}","starred_url":"https://api.github.com/users/confluentinc/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/confluentinc/subscriptions","organizations_url":"https://api.github.com/users/confluentinc/orgs","repos_url":"https://api.github.com/users/confluentinc/repos","events_url":"https://api.github.com/users/confluentinc/events{/privacy}","received_events_url":"https://api.github.com/users/confluentinc/received_events","type":"Organization","site_admin":false},"repo":{"id":56217288,"name":"confluent-kafka-python","full_name":"confluentinc/confluent-kafka-python","owner":{"login":"confluentinc","id":9439498,"avatar_url":"https://avatars0.githubusercontent.com/u/9439498?v=4","gravatar_id":"","url":"https://api.github.com/users/confluentinc","html_url":"https://github.com/confluentinc","followers_url":"https://api.github.com/users/confluentinc/followers","following_url":"https://api.github.com/users/confluentinc/following{/other_user}","gists_url":"https://api.github.com/users/confluentinc/gists{/gist_id}","starred_url":"https://api.github.com/users/confluentinc/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/confluentinc/subscriptions","organizations_url":"https://api.github.com/users/confluentinc/orgs","repos_url":"https://api.github.com/users/confluentinc/repos","events_url":"https://api.github.com/users/confluentinc/events{/privacy}","received_events_url":"https://api.github.com/users/confluentinc/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/confluentinc/confluent-kafka-python","description":"Confluent's Apache Kafka Python client","fork":false,"url":"https://api.github.com/repos/confluentinc/confluent-kafka-python","forks_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/forks","keys_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/keys{/key_id}","collaborators_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/teams","hooks_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/hooks","issue_events_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/issues/events{/number}","events_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/events","assignees_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/assignees{/user}","branches_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/branches{/branch}","tags_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/tags","blobs_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/git/refs{/sha}","trees_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/git/trees{/sha}","statuses_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/statuses/{sha}","languages_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/languages","stargazers_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/stargazers","contributors_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/contributors","subscribers_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/subscribers","subscription_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/subscription","commits_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/commits{/sha}","git_commits_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/git/commits{/sha}","comments_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/comments{/number}","issue_comment_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/issues/comments{/number}","contents_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/contents/{+path}","compare_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/compare/{base}...{head}","merges_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/merges","archive_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/downloads","issues_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/issues{/number}","pulls_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/pulls{/number}","milestones_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/milestones{/number}","notifications_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/labels{/name}","releases_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/releases{/id}","deployments_url":"https://api.github.com/repos/confluentinc/confluent-kafka-python/deployments","created_at":"2016-04-14T07:40:41Z","updated_at":"2017-09-04T17:30:18Z","pushed_at":"2017-09-05T16:19:27Z","git_url":"git://github.com/confluentinc/confluent-kafka-python.git","ssh_url":"git@github.com:confluentinc/confluent-kafka-python.git","clone_url":"https://github.com/confluentinc/confluent-kafka-python.git","svn_url":"https://github.com/confluentinc/confluent-kafka-python","homepage":"http://docs.confluent.io/current/clients/confluent-kafka-python","size":246,"stargazers_count":360,"watchers_count":360,"language":"Python","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":94,"mirror_url":null,"open_issues_count":36,"forks":94,"open_issues":36,"watchers":360,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/confluentinc/confluent-kafka-python/pulls/243"},"html":{"href":"https://github.com/confluentinc/confluent-kafka-python/pull/243"},"issue":{"href":"https://api.github.com/repos/confluentinc/confluent-kafka-python/issues/243"},"comments":{"href":"https://api.github.com/repos/confluentinc/confluent-kafka-python/issues/243/comments"},"review_comments":{"href":"https://api.github.com/repos/confluentinc/confluent-kafka-python/pulls/243/comments"},"review_comment":{"href":"https://api.github.com/repos/confluentinc/confluent-kafka-python/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/confluentinc/confluent-kafka-python/pulls/243/commits"},"statuses":{"href":"https://api.github.com/repos/confluentinc/confluent-kafka-python/statuses/dcc0a91195382e6d1b7d735d97f302e6aced7ee2"}},"author_association":"MEMBER"}}
{"actor":{"display_login":"edenhill"}}