{"action":"created","comment":{"url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/pulls/comments/73224882","id":73224882,"diff_hunk":"@@ -0,0 +1,502 @@\n+# Copyright 2016 Google Inc. All rights reserved.\n+#\n+# Licensed under the Apache License, Version 2.0 (the \"License\");\n+# you may not use this file except in compliance with the License.\n+# You may obtain a copy of the License at\n+#\n+#     http://www.apache.org/licenses/LICENSE-2.0\n+#\n+# Unless required by applicable law or agreed to in writing, software\n+# distributed under the License is distributed on an \"AS IS\" BASIS,\n+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n+# See the License for the specific language governing permissions and\n+# limitations under the License.\n+\n+\"\"\"Groups for the `Google Stackdriver Monitoring API (V3)`_.\n+\n+.. _Google Stackdriver Monitoring API (V3):\n+    https://cloud.google.com/monitoring/api/ref_v3/rest/v3/\\\n+    projects.groups\n+\"\"\"\n+\n+import re\n+\n+from gcloud._helpers import _name_from_project_path\n+from gcloud.exceptions import NotFound\n+from gcloud.monitoring._helpers import _format_timestamp\n+from gcloud.monitoring.resource import Resource\n+\n+\n+_GROUP_TEMPLATE = re.compile(r\"\"\"\n+    projects/            # static prefix\n+    (?P<project>[^/]+)   # initial letter, wordchars + hyphen\n+    /groups/             # static midfix\n+    (?P<name>[^/]+)      # initial letter, wordchars + allowed punc\n+\"\"\", re.VERBOSE)\n+\n+\n+def group_id_from_name(path, project=None):\n+    \"\"\"Validate a group URI path and get the group ID.\n+\n+    :type path: string\n+    :param path: URI path for a group API request.\n+\n+    :type project: string or None\n+    :param project: The project associated with the request. It is\n+                    included for validation purposes.\n+\n+    :rtype: string\n+    :returns: Group ID parsed from ``path``.\n+    :raises: :class:`ValueError` if the ``path`` is ill-formed or if\n+             the project from the ``path`` does not agree with the\n+             ``project`` passed in.\n+    \"\"\"\n+    return _name_from_project_path(path, project, _GROUP_TEMPLATE)\n+\n+\n+def group_name_from_id(project, group_id):\n+    \"\"\"Build the group name given the project and group ID.\n+\n+    :type project: string\n+    :param project: The project associated with the group.\n+\n+    :type group_id: string\n+    :param group_id: The group ID.\n+\n+    :rtype: string\n+    :returns: The fully qualified name of the group.\n+    \"\"\"\n+    return 'projects/{project}/groups/{group_id}'.format(\n+        project=project, group_id=group_id)\n+\n+\n+class Group(object):\n+    \"\"\"A dynamic collection of monitored resources.\n+\n+    :type client: :class:`gcloud.monitoring.client.Client`\n+    :param client: A client for operating on the metric descriptor.\n+\n+    :type group_id: string or None\n+    :param group_id: The ID of the group.\n+\n+    :type display_name: string or None\n+    :param display_name:\n+        A user-assigned name for this group, used only for display purposes.\n+\n+    :type parent_id: string or None\n+    :param parent_id:\n+        The ID of the group's parent, if it has one.\n+\n+    :type filter_string: string or None\n+    :param filter_string:\n+        The filter string used to determine which monitored resources belong to\n+        this group.\n+\n+    :type is_cluster: boolean\n+    :param is_cluster:\n+        If true, the members of this group are considered to be a cluster. The\n+        system can perform additional analysis on groups that are clusters.\n+    \"\"\"\n+    def __init__(self, client, group_id=None, display_name=None,\n+                 parent_id=None, filter_string=None, is_cluster=False):\n+        self.client = client\n+        self._id = group_id\n+        self.display_name = display_name\n+        self.parent_id = parent_id\n+        self.filter = filter_string\n+        self.is_cluster = is_cluster\n+\n+        if group_id:\n+            self._name = group_name_from_id(client.project, group_id)\n+        else:\n+            self._name = None\n+\n+    @property\n+    def id(self):\n+        \"\"\"Returns the group ID.\n+\n+        :rtype: str or None\n+        :returns: the ID of the group based on it's name.\n+        \"\"\"\n+        return self._id\n+\n+    @property\n+    def name(self):\n+        \"\"\"Returns the fully qualified name of the group.\n+\n+        :rtype: str or None\n+        :returns:\n+            The fully qualified name of the group in the format\n+            \"projects/<project>/groups/<id>\".\n+        \"\"\"\n+        return self._name\n+\n+    @property\n+    def parent_name(self):\n+        \"\"\"Returns the fully qualified name of the parent group.\n+\n+        :rtype: str or None\n+        :returns:\n+            The fully qualified name of the parent group.\n+        \"\"\"\n+        if not self.parent_id:\n+            return None\n+        return group_name_from_id(self.client.project, self.parent_id)\n+\n+    @property\n+    def path(self):\n+        \"\"\"URL path to this group.\n+\n+        :rtype: str\n+        :returns: the path based on project and group name.\n+\n+        :raises: :exc:`ValueError` if :attr:`name` is not specified.\n+        \"\"\"\n+        if not self.id:\n+            raise ValueError('Cannot determine path without group ID.')\n+        return '/' + self.name\n+\n+    def create(self):\n+        \"\"\"Create a new group based on this object via a ``POST`` request.\n+\n+        Example::\n+\n+            >>> group = client.group(\n+            ...     display_name='My group',\n+            ...     filter_string='resource.type = \"gce_instance\"',\n+            ...     parent_id='5678',\n+            ...     is_cluster=True)\n+            >>> group.create()\n+\n+        The ``name`` attribute is ignored in preparing the creation request.\n+        All attributes are overwritten by the values received in the response\n+        (normally affecting only ``name``).\n+        \"\"\"\n+        path = self.path_helper(self.client.project)\n+        info = self.client.connection.api_request(\n+            method='POST', path=path, data=self._to_dict())\n+        self._init_from_dict(info)\n+\n+    def exists(self):\n+        \"\"\"Test for the existence of the group via a ``GET`` request.\n+\n+        :rtype: bool\n+        :returns: Boolean indicating existence of the group.\n+        \"\"\"\n+        try:\n+            self.client.connection.api_request(method='GET', path=self.path)\n+        except NotFound:\n+            return False\n+        else:\n+            return True\n+\n+    def reload(self):\n+        \"\"\"Sync local group information via a ``GET`` request.\n+\n+        .. warning::\n+\n+            This will overwrite any local changes you've made and not saved\n+            via :meth:`update`.\n+        \"\"\"\n+        info = self.client.connection.api_request(method='GET', path=self.path)\n+        self._init_from_dict(info)\n+\n+    def update(self):\n+        \"\"\"Update the group via a ``PUT`` request.\"\"\"\n+        info = self.client.connection.api_request(\n+            method='PUT', path=self.path, data=self._to_dict())\n+        self._init_from_dict(info)\n+\n+    def delete(self):\n+        \"\"\"Delete the group via a ``DELETE`` request.\n+\n+        Example::\n+\n+            >>> group = client.group('1234')\n+            >>> group.delete()\n+\n+        Only the ``client`` and ``name`` attributes are used.\n+\n+        .. warning::\n+\n+            This method will fail for groups that have one or more children\n+            groups.\n+        \"\"\"\n+        self.client.connection.api_request(method='DELETE', path=self.path)\n+\n+    def parent(self):\n+        \"\"\"Returns the parent group of this group via a ``GET`` request.\n+\n+        :rtype: :class:`Group` or None\n+        :returns: The parent of the group.\n+        \"\"\"\n+        if not self.parent_id:\n+            return None\n+        return self._fetch(self.client, self.parent_id)\n+\n+    def children(self):\n+        \"\"\"Lists all children of this group via a ``GET`` request.\n+\n+        Returns groups whose parent_name field contains the group name. If no\n+        groups have this parent, the results are empty.\n+\n+        :rtype: list of :class:`~gcloud.monitoring.group.Group`\n+        :returns: A list of group instances.\n+        \"\"\"\n+        return self._list(self.client, children_of_group=self.name)\n+\n+    def ancestors(self):\n+        \"\"\"Lists all ancestors of this group via a ``GET`` request.\n+\n+        The groups are returned in order, starting with the immediate parent\n+        and ending with the most distant ancestor. If the specified group has\n+        no immediate parent, the results are empty.\n+\n+        :rtype: list of :class:`~gcloud.monitoring.group.Group`\n+        :returns: A list of group instances.\n+        \"\"\"\n+        return self._list(self.client, ancestors_of_group=self.name)\n+\n+    def descendants(self):\n+        \"\"\"Lists all descendants of this group via a ``GET`` request.\n+\n+        This returns a superset of the results returned by the :meth:`children`\n+        method, and includes children-of-children, and so forth.\n+\n+        :rtype: list of :class:`~gcloud.monitoring.group.Group`\n+        :returns: A list of group instances.\n+        \"\"\"\n+        return self._list(self.client, descendants_of_group=self.name)\n+\n+    def members(self, filter_string=None, end_time=None, start_time=None):\n+        \"\"\"Lists all members of this group via a ``GET`` request.\n+\n+        If no end_time and start_time is provided then the group membership\n+        over the last minute is returned.\n+\n+        Examples::\n+\n+            To get current members that are Compute Engine VM instances:\n+\n+                group.members('resource.type = \"gce_instance\"')\n+\n+            To get historical members that existed between 4 and 5 hours ago:\n+\n+                import datetime\n+                t1 = datetime.datetime.utcnow() - datetime.timedelta(hours=4)\n+                t0 = t1 - datetime.timedelta(hours=1)\n+                group.members(end_time=t1, start_time=t0)\n+\n+\n+        :type filter_string: string or None\n+        :param filter_string:\n+            An optional list filter describing the members to be returned. The\n+            filter may reference the type, labels, and metadata of monitored\n+            resources that comprise the group. See the `filter documentation`_.\n+\n+        :type end_time: :class:`datetime.datetime` or None\n+        :param end_time:\n+            The end time (inclusive) of the time interval for which results\n+            should be returned, as a datetime object.\n+\n+        :type start_time: :class:`datetime.datetime` or None\n+        :param start_time:\n+            The start time (exclusive) of the time interval for which results\n+            should be returned, as a datetime object.  If not specified, the\n+            interval is a point in time.\n+\n+        :rtype: list of :class:`~gcloud.monitoring.resource.Resource`\n+        :returns: A list of resource instances.\n+\n+        :raises:\n+            :exc:`ValueError` if the ``start_time`` is specified, but the\n+            ``end_time`` is missing.\n+\n+        .. _filter documentation:\n+            https://cloud.google.com/monitoring/api/v3/filters#group-filter\n+        \"\"\"\n+        if start_time is not None and end_time is None:\n+            raise ValueError('If \"start_time\" is specified, \"end_time\" must '\n+                             'also be specified')\n+\n+        path = '%s/members' % self.path\n+        resources = []\n+        page_token = None\n+\n+        while True:\n+            params = {}\n+\n+            if filter_string is not None:\n+                params['filter'] = filter_string\n+\n+            if end_time is not None:\n+                params['interval.endTime'] = _format_timestamp(end_time)\n+\n+            if start_time is not None:\n+                params['interval.startTime'] = _format_timestamp(start_time)\n+\n+            if page_token is not None:\n+                params['pageToken'] = page_token\n+\n+            response = self.client.connection.api_request(\n+                method='GET', path=path, query_params=params)\n+            for info in response.get('members', []):\n+                resources.append(Resource._from_dict(info))\n+\n+            page_token = response.get('nextPageToken')\n+            if not page_token:\n+                break\n+\n+        return resources\n+\n+    @staticmethod\n+    def path_helper(project, group_id=''):\n+        \"\"\"Returns the path to the group API.\n+\n+        :type project: string\n+        :param project: The project ID or number to use.\n+\n+        :type group_id: string\n+        :param group_id: The group ID.\n+\n+        :rtype: string\n+        :returns: The relative URL path for the specific group.\n+        \"\"\"\n+        return '/' + group_name_from_id(project, group_id)\n+\n+    @classmethod\n+    def _fetch(cls, client, group_id):\n+        \"\"\"Fetch a group from the API based on it's ID.\n+\n+        :type client: :class:`gcloud.monitoring.client.Client`\n+        :param client: The client to use.\n+\n+        :type group_id: string\n+        :param group_id: The group ID.\n+\n+        :rtype: :class:`Group`\n+        :returns: The group instance.\n+\n+        :raises: :class:`gcloud.exceptions.NotFound` if the group\n+            is not found.\n+        \"\"\"\n+        new_group = cls(client, group_id)\n+        new_group.reload()\n+        return new_group\n+\n+    @classmethod\n+    def _list(cls, client, children_of_group=None, ancestors_of_group=None,\n+              descendants_of_group=None):\n+        \"\"\"Lists all groups in the project.\n+\n+        :type client: :class:`gcloud.monitoring.client.Client`\n+        :param client: The client to use.\n+\n+        :type children_of_group: string or None\n+        :param children_of_group:\n+            Returns groups whose parent_name field contains the group name. If\n+            no groups have this parent, the results are empty.\n+\n+        :type ancestors_of_group: string or None\n+        :param ancestors_of_group:\n+            Returns groups that are ancestors of the specified group. If the\n+            specified group has no immediate parent, the results are empty.\n+\n+        :type descendants_of_group: string or None\n+        :param descendants_of_group:\n+            Returns the descendants of the specified group. This is a superset\n+            of the results returned by the children_of_group filter, and\n+            includes children-of-children, and so forth.\n+\n+        :rtype: list of :class:`~gcloud.monitoring.group.Group`\n+        :returns: A list of group instances.\n+        \"\"\"\n+        path = cls.path_helper(client.project)\n+        groups = []\n+        page_token = None\n+\n+        while True:\n+            params = {}\n+\n+            if children_of_group is not None:\n+                params['childrenOfGroup'] = children_of_group\n+\n+            if ancestors_of_group is not None:\n+                params['ancestorsOfGroup'] = ancestors_of_group\n+\n+            if descendants_of_group is not None:\n+                params['descendantsOfGroup'] = descendants_of_group\n+\n+            if page_token is not None:\n+                params['pageToken'] = page_token\n+\n+            response = client.connection.api_request(\n+                method='GET', path=path, query_params=params)\n+            for info in response.get('group', []):\n+                groups.append(cls._from_dict(client, info))\n+\n+            page_token = response.get('nextPageToken')\n+            if not page_token:\n+                break\n+\n+        return groups\n+\n+    @classmethod\n+    def _from_dict(cls, client, info):\n+        \"\"\"Constructs a Group instance from the parsed JSON representation.\n+\n+        :type client: :class:`gcloud.monitoring.client.Client`\n+        :param client: A client to be included in the returned object.\n+\n+        :type info: dict\n+        :param info:\n+            A ``dict`` parsed from the JSON wire-format representation.\n+\n+        :rtype: :class:`Group`\n+        :returns: A group.\n+        \"\"\"\n+        group = cls(client)\n+        group._init_from_dict(info)\n+        return group\n+\n+    def _init_from_dict(self, info):\n+        \"\"\"Initialize attributes from the parsed JSON representation.\n+\n+        :type info: dict\n+        :param info:\n+            A ``dict`` parsed from the JSON wire-format representation.\n+        \"\"\"\n+        self._name = info['name']\n+        self._id = group_id_from_name(info['name'])\n+        self.display_name = info['displayName']\n+        parent_name = info.get('parentName', '')\n+        self.filter = info['filter']\n+        self.is_cluster = info.get('isCluster', False)\n+\n+        if not parent_name:\n+            self.parent_id = None\n+        else:\n+            self.parent_id = group_id_from_name(parent_name)\n+\n+    def _to_dict(self):\n+        \"\"\"Build a dictionary ready to be serialized to the JSON wire format.\n+\n+        :rtype: dict\n+        :returns: A dictionary.\n+        \"\"\"\n+        info = {\n+            'filter': self.filter,\n+            'displayName': self.display_name,\n+            'isCluster': self.is_cluster,\n+        }\n+\n+        if self.name:\n+            info['name'] = self.name\n+        if self.parent_id:\n+            info['parentName'] = group_name_from_id(\n+                self.client.project, self.parent_id)\n+\n+        return info\n+\n+    def __repr__(self):\n+        return '<Group: %s>' % self.name","path":"gcloud/monitoring/group.py","position":504,"original_position":502,"commit_id":"462b1139689297b61a83f4fa8ef4201e0ded7341","original_commit_id":"f1a533fc41877fce9b7289be83a46a5d6a234769","user":{"login":"supriyagarg","id":11726936,"avatar_url":"https://avatars.githubusercontent.com/u/11726936?v=3","gravatar_id":"","url":"https://api.github.com/users/supriyagarg","html_url":"https://github.com/supriyagarg","followers_url":"https://api.github.com/users/supriyagarg/followers","following_url":"https://api.github.com/users/supriyagarg/following{/other_user}","gists_url":"https://api.github.com/users/supriyagarg/gists{/gist_id}","starred_url":"https://api.github.com/users/supriyagarg/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/supriyagarg/subscriptions","organizations_url":"https://api.github.com/users/supriyagarg/orgs","repos_url":"https://api.github.com/users/supriyagarg/repos","events_url":"https://api.github.com/users/supriyagarg/events{/privacy}","received_events_url":"https://api.github.com/users/supriyagarg/received_events","type":"User","site_admin":false},"body":"Done.","created_at":"2016-08-02T19:53:10Z","updated_at":"2016-08-02T19:53:10Z","html_url":"https://github.com/GoogleCloudPlatform/gcloud-python/pull/2035#discussion_r73224882","pull_request_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/pulls/2035","_links":{"self":{"href":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/pulls/comments/73224882"},"html":{"href":"https://github.com/GoogleCloudPlatform/gcloud-python/pull/2035#discussion_r73224882"},"pull_request":{"href":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/pulls/2035"}}},"pull_request":{"url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/pulls/2035","id":79431262,"html_url":"https://github.com/GoogleCloudPlatform/gcloud-python/pull/2035","diff_url":"https://github.com/GoogleCloudPlatform/gcloud-python/pull/2035.diff","patch_url":"https://github.com/GoogleCloudPlatform/gcloud-python/pull/2035.patch","issue_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/issues/2035","number":2035,"state":"open","locked":false,"title":"Add Group support to the Monitoring API","user":{"login":"supriyagarg","id":11726936,"avatar_url":"https://avatars.githubusercontent.com/u/11726936?v=3","gravatar_id":"","url":"https://api.github.com/users/supriyagarg","html_url":"https://github.com/supriyagarg","followers_url":"https://api.github.com/users/supriyagarg/followers","following_url":"https://api.github.com/users/supriyagarg/following{/other_user}","gists_url":"https://api.github.com/users/supriyagarg/gists{/gist_id}","starred_url":"https://api.github.com/users/supriyagarg/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/supriyagarg/subscriptions","organizations_url":"https://api.github.com/users/supriyagarg/orgs","repos_url":"https://api.github.com/users/supriyagarg/repos","events_url":"https://api.github.com/users/supriyagarg/events{/privacy}","received_events_url":"https://api.github.com/users/supriyagarg/received_events","type":"User","site_admin":false},"body":"This change allows users to both read and write Stackdriver groups. It allows users to:\r\n\r\n* fetch groups\r\n* list groups\r\n* list a group's ancestors, descendants, and children groups\r\n* create, update, and delete groups.\r\n* list a group's members\r\n","created_at":"2016-07-29T22:02:41Z","updated_at":"2016-08-02T19:53:10Z","closed_at":null,"merged_at":null,"merge_commit_sha":"0e61381b79f5c4da9bbc5b5b180251ce8534695e","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/pulls/2035/commits","review_comments_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/pulls/2035/comments","review_comment_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/pulls/comments{/number}","comments_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/issues/2035/comments","statuses_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/statuses/462b1139689297b61a83f4fa8ef4201e0ded7341","head":{"label":"supriyagarg:monitoring-api","ref":"monitoring-api","sha":"462b1139689297b61a83f4fa8ef4201e0ded7341","user":{"login":"supriyagarg","id":11726936,"avatar_url":"https://avatars.githubusercontent.com/u/11726936?v=3","gravatar_id":"","url":"https://api.github.com/users/supriyagarg","html_url":"https://github.com/supriyagarg","followers_url":"https://api.github.com/users/supriyagarg/followers","following_url":"https://api.github.com/users/supriyagarg/following{/other_user}","gists_url":"https://api.github.com/users/supriyagarg/gists{/gist_id}","starred_url":"https://api.github.com/users/supriyagarg/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/supriyagarg/subscriptions","organizations_url":"https://api.github.com/users/supriyagarg/orgs","repos_url":"https://api.github.com/users/supriyagarg/repos","events_url":"https://api.github.com/users/supriyagarg/events{/privacy}","received_events_url":"https://api.github.com/users/supriyagarg/received_events","type":"User","site_admin":false},"repo":{"id":64252930,"name":"gcloud-python","full_name":"supriyagarg/gcloud-python","owner":{"login":"supriyagarg","id":11726936,"avatar_url":"https://avatars.githubusercontent.com/u/11726936?v=3","gravatar_id":"","url":"https://api.github.com/users/supriyagarg","html_url":"https://github.com/supriyagarg","followers_url":"https://api.github.com/users/supriyagarg/followers","following_url":"https://api.github.com/users/supriyagarg/following{/other_user}","gists_url":"https://api.github.com/users/supriyagarg/gists{/gist_id}","starred_url":"https://api.github.com/users/supriyagarg/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/supriyagarg/subscriptions","organizations_url":"https://api.github.com/users/supriyagarg/orgs","repos_url":"https://api.github.com/users/supriyagarg/repos","events_url":"https://api.github.com/users/supriyagarg/events{/privacy}","received_events_url":"https://api.github.com/users/supriyagarg/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/supriyagarg/gcloud-python","description":"Google Cloud Client Library for Python","fork":true,"url":"https://api.github.com/repos/supriyagarg/gcloud-python","forks_url":"https://api.github.com/repos/supriyagarg/gcloud-python/forks","keys_url":"https://api.github.com/repos/supriyagarg/gcloud-python/keys{/key_id}","collaborators_url":"https://api.github.com/repos/supriyagarg/gcloud-python/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/supriyagarg/gcloud-python/teams","hooks_url":"https://api.github.com/repos/supriyagarg/gcloud-python/hooks","issue_events_url":"https://api.github.com/repos/supriyagarg/gcloud-python/issues/events{/number}","events_url":"https://api.github.com/repos/supriyagarg/gcloud-python/events","assignees_url":"https://api.github.com/repos/supriyagarg/gcloud-python/assignees{/user}","branches_url":"https://api.github.com/repos/supriyagarg/gcloud-python/branches{/branch}","tags_url":"https://api.github.com/repos/supriyagarg/gcloud-python/tags","blobs_url":"https://api.github.com/repos/supriyagarg/gcloud-python/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/supriyagarg/gcloud-python/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/supriyagarg/gcloud-python/git/refs{/sha}","trees_url":"https://api.github.com/repos/supriyagarg/gcloud-python/git/trees{/sha}","statuses_url":"https://api.github.com/repos/supriyagarg/gcloud-python/statuses/{sha}","languages_url":"https://api.github.com/repos/supriyagarg/gcloud-python/languages","stargazers_url":"https://api.github.com/repos/supriyagarg/gcloud-python/stargazers","contributors_url":"https://api.github.com/repos/supriyagarg/gcloud-python/contributors","subscribers_url":"https://api.github.com/repos/supriyagarg/gcloud-python/subscribers","subscription_url":"https://api.github.com/repos/supriyagarg/gcloud-python/subscription","commits_url":"https://api.github.com/repos/supriyagarg/gcloud-python/commits{/sha}","git_commits_url":"https://api.github.com/repos/supriyagarg/gcloud-python/git/commits{/sha}","comments_url":"https://api.github.com/repos/supriyagarg/gcloud-python/comments{/number}","issue_comment_url":"https://api.github.com/repos/supriyagarg/gcloud-python/issues/comments{/number}","contents_url":"https://api.github.com/repos/supriyagarg/gcloud-python/contents/{+path}","compare_url":"https://api.github.com/repos/supriyagarg/gcloud-python/compare/{base}...{head}","merges_url":"https://api.github.com/repos/supriyagarg/gcloud-python/merges","archive_url":"https://api.github.com/repos/supriyagarg/gcloud-python/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/supriyagarg/gcloud-python/downloads","issues_url":"https://api.github.com/repos/supriyagarg/gcloud-python/issues{/number}","pulls_url":"https://api.github.com/repos/supriyagarg/gcloud-python/pulls{/number}","milestones_url":"https://api.github.com/repos/supriyagarg/gcloud-python/milestones{/number}","notifications_url":"https://api.github.com/repos/supriyagarg/gcloud-python/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/supriyagarg/gcloud-python/labels{/name}","releases_url":"https://api.github.com/repos/supriyagarg/gcloud-python/releases{/id}","deployments_url":"https://api.github.com/repos/supriyagarg/gcloud-python/deployments","created_at":"2016-07-26T20:38:58Z","updated_at":"2016-07-26T20:39:02Z","pushed_at":"2016-08-02T00:26:46Z","git_url":"git://github.com/supriyagarg/gcloud-python.git","ssh_url":"git@github.com:supriyagarg/gcloud-python.git","clone_url":"https://github.com/supriyagarg/gcloud-python.git","svn_url":"https://github.com/supriyagarg/gcloud-python","homepage":"https://googlecloudplatform.github.io/gcloud-python/","size":68313,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"GoogleCloudPlatform:master","ref":"master","sha":"5a6ba14fda655761d7104f3c8ef14d88d881de24","user":{"login":"GoogleCloudPlatform","id":2810941,"avatar_url":"https://avatars.githubusercontent.com/u/2810941?v=3","gravatar_id":"","url":"https://api.github.com/users/GoogleCloudPlatform","html_url":"https://github.com/GoogleCloudPlatform","followers_url":"https://api.github.com/users/GoogleCloudPlatform/followers","following_url":"https://api.github.com/users/GoogleCloudPlatform/following{/other_user}","gists_url":"https://api.github.com/users/GoogleCloudPlatform/gists{/gist_id}","starred_url":"https://api.github.com/users/GoogleCloudPlatform/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/GoogleCloudPlatform/subscriptions","organizations_url":"https://api.github.com/users/GoogleCloudPlatform/orgs","repos_url":"https://api.github.com/users/GoogleCloudPlatform/repos","events_url":"https://api.github.com/users/GoogleCloudPlatform/events{/privacy}","received_events_url":"https://api.github.com/users/GoogleCloudPlatform/received_events","type":"Organization","site_admin":false},"repo":{"id":16316451,"name":"gcloud-python","full_name":"GoogleCloudPlatform/gcloud-python","owner":{"login":"GoogleCloudPlatform","id":2810941,"avatar_url":"https://avatars.githubusercontent.com/u/2810941?v=3","gravatar_id":"","url":"https://api.github.com/users/GoogleCloudPlatform","html_url":"https://github.com/GoogleCloudPlatform","followers_url":"https://api.github.com/users/GoogleCloudPlatform/followers","following_url":"https://api.github.com/users/GoogleCloudPlatform/following{/other_user}","gists_url":"https://api.github.com/users/GoogleCloudPlatform/gists{/gist_id}","starred_url":"https://api.github.com/users/GoogleCloudPlatform/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/GoogleCloudPlatform/subscriptions","organizations_url":"https://api.github.com/users/GoogleCloudPlatform/orgs","repos_url":"https://api.github.com/users/GoogleCloudPlatform/repos","events_url":"https://api.github.com/users/GoogleCloudPlatform/events{/privacy}","received_events_url":"https://api.github.com/users/GoogleCloudPlatform/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/GoogleCloudPlatform/gcloud-python","description":"Google Cloud Client Library for Python","fork":false,"url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python","forks_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/forks","keys_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/keys{/key_id}","collaborators_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/teams","hooks_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/hooks","issue_events_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/issues/events{/number}","events_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/events","assignees_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/assignees{/user}","branches_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/branches{/branch}","tags_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/tags","blobs_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/git/refs{/sha}","trees_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/git/trees{/sha}","statuses_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/statuses/{sha}","languages_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/languages","stargazers_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/stargazers","contributors_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/contributors","subscribers_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/subscribers","subscription_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/subscription","commits_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/commits{/sha}","git_commits_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/git/commits{/sha}","comments_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/comments{/number}","issue_comment_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/issues/comments{/number}","contents_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/contents/{+path}","compare_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/compare/{base}...{head}","merges_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/merges","archive_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/downloads","issues_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/issues{/number}","pulls_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/pulls{/number}","milestones_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/milestones{/number}","notifications_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/labels{/name}","releases_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/releases{/id}","deployments_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/deployments","created_at":"2014-01-28T15:51:47Z","updated_at":"2016-07-29T13:25:42Z","pushed_at":"2016-08-02T19:47:12Z","git_url":"git://github.com/GoogleCloudPlatform/gcloud-python.git","ssh_url":"git@github.com:GoogleCloudPlatform/gcloud-python.git","clone_url":"https://github.com/GoogleCloudPlatform/gcloud-python.git","svn_url":"https://github.com/GoogleCloudPlatform/gcloud-python","homepage":"https://googlecloudplatform.github.io/gcloud-python/","size":70842,"stargazers_count":361,"watchers_count":361,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":186,"mirror_url":null,"open_issues_count":160,"forks":186,"open_issues":160,"watchers":361,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/pulls/2035"},"html":{"href":"https://github.com/GoogleCloudPlatform/gcloud-python/pull/2035"},"issue":{"href":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/issues/2035"},"comments":{"href":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/issues/2035/comments"},"review_comments":{"href":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/pulls/2035/comments"},"review_comment":{"href":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/pulls/2035/commits"},"statuses":{"href":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/statuses/462b1139689297b61a83f4fa8ef4201e0ded7341"}}}}
{"actor":{"display_login":"supriyagarg"}}