{"action":"created","comment":{"url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/pulls/comments/60665106","id":60665106,"diff_hunk":"@@ -0,0 +1,114 @@\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+\"\"\"Time series as `pandas`_ dataframes.\n+\n+.. _pandas: http://pandas.pydata.org/pandas-docs/stable/\n+\"\"\"\n+\n+import itertools\n+\n+TOP_RESOURCE_LABELS = [\n+    'project_id',\n+    'aws_account',\n+    'location',\n+    'region',\n+    'zone',\n+]\n+\n+\n+def _build_dataframe(time_series_iterable,\n+                     label=None, labels=None):  # pragma: NO COVER\n+    \"\"\"Build a ``pandas`` dataframe out of time series.\n+\n+    :type time_series_iterable:\n+        iterable over :class:`~gcloud.monitoring.timeseries.TimeSeries`\n+    :param time_series_iterable:\n+        An iterable (e.g., a query object) yielding time series.\n+\n+    :type label: string or None\n+    :param label:\n+        The label name to use for the dataframe header. This can be the name\n+        of a resource label or metric label (e.g., ``\"instance_name\"``), or\n+        the string ``\"resource_type\"``.\n+\n+    :type labels: list of strings, or None\n+    :param labels:\n+        A list or tuple of label names to use for the dataframe header.\n+        If more than one label name is provided, the resulting dataframe\n+        will have a multi-level column header.\n+\n+        Specifying neither ``label`` or ``labels`` results in a dataframe\n+        with a multi-level column header including the resource type and\n+        all available resource and metric labels.\n+\n+        Specifying both ``label`` and ``labels`` is an error.\n+\n+    :rtype: :class:`pandas.DataFrame`\n+    :returns: A dataframe where each column represents one time series.\n+    \"\"\"\n+    import pandas   # pylint: disable=import-error\n+\n+    if label is not None and labels is not None:\n+        raise ValueError('Cannot specify both \"label\" and \"labels\".')\n+    elif not (labels or labels is None):\n+        raise ValueError('\"labels\" must be non-empty or None.')\n+\n+    columns = []\n+    headers = []\n+    for time_series in time_series_iterable:\n+        pandas_series = pandas.Series(\n+            data=[p.value for p in time_series.points],\n+            index=[p.end_time for p in time_series.points],\n+        )\n+        columns.append(pandas_series)\n+        headers.append(time_series.header())\n+\n+    # Implement a smart default of using all available labels.\n+    if label is None and labels is None:\n+        resource_labels = set(itertools.chain.from_iterable(\n+            header.resource.labels for header in headers))\n+        metric_labels = set(itertools.chain.from_iterable(\n+            header.metric.labels for header in headers))\n+        labels = (['resource_type'] +\n+                  _sorted_resource_labels(resource_labels) +\n+                  sorted(metric_labels))\n+\n+    # Assemble the columns into a DataFrame.\n+    dataframe = pandas.DataFrame(columns).T\n+\n+    # Convert the timestamp strings into a DatetimeIndex.\n+    dataframe.index = pandas.to_datetime(dataframe.index)\n+\n+    # Build a column Index or MultiIndex from the label values. Do not\n+    # include level names in the column header if the user requested a\n+    # single-level header by specifying \"label\".\n+    level_names = labels or None\n+    label_keys = labels or [label]\n+    dataframe.columns = pandas.MultiIndex.from_arrays(\n+        [[header.labels.get(key, '') for header in headers]\n+         for key in label_keys],","path":"gcloud/monitoring/_dataframe.py","position":99,"original_position":101,"commit_id":"2dfd890e15b0b1b81ac294c65a43898af3f81da4","original_commit_id":"adb7e102bb158a442e473166b66d5919334cfdbd","user":{"login":"rimey","id":360806,"avatar_url":"https://avatars.githubusercontent.com/u/360806?v=3","gravatar_id":"","url":"https://api.github.com/users/rimey","html_url":"https://github.com/rimey","followers_url":"https://api.github.com/users/rimey/followers","following_url":"https://api.github.com/users/rimey/following{/other_user}","gists_url":"https://api.github.com/users/rimey/gists{/gist_id}","starred_url":"https://api.github.com/users/rimey/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rimey/subscriptions","organizations_url":"https://api.github.com/users/rimey/orgs","repos_url":"https://api.github.com/users/rimey/repos","events_url":"https://api.github.com/users/rimey/events{/privacy}","received_events_url":"https://api.github.com/users/rimey/received_events","type":"User","site_admin":false},"body":"If we can't give the function meaningful name, we shouldn't define it. `_foo_helper` doesn't cut it. My local Google Python readability reviewer says \"use a nested helper function.\" I say \"not allowed\", and he just asks me \"why not?\" Oh well. :-)","created_at":"2016-04-21T22:25:30Z","updated_at":"2016-04-21T22:25:30Z","html_url":"https://github.com/GoogleCloudPlatform/gcloud-python/pull/1691#discussion_r60665106","pull_request_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/pulls/1691","_links":{"self":{"href":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/pulls/comments/60665106"},"html":{"href":"https://github.com/GoogleCloudPlatform/gcloud-python/pull/1691#discussion_r60665106"},"pull_request":{"href":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/pulls/1691"}}},"pull_request":{"url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/pulls/1691","id":65077415,"html_url":"https://github.com/GoogleCloudPlatform/gcloud-python/pull/1691","diff_url":"https://github.com/GoogleCloudPlatform/gcloud-python/pull/1691.diff","patch_url":"https://github.com/GoogleCloudPlatform/gcloud-python/pull/1691.patch","issue_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/issues/1691","number":1691,"state":"open","locked":false,"title":"Monitoring API","user":{"login":"rimey","id":360806,"avatar_url":"https://avatars.githubusercontent.com/u/360806?v=3","gravatar_id":"","url":"https://api.github.com/users/rimey","html_url":"https://github.com/rimey","followers_url":"https://api.github.com/users/rimey/followers","following_url":"https://api.github.com/users/rimey/following{/other_user}","gists_url":"https://api.github.com/users/rimey/gists{/gist_id}","starred_url":"https://api.github.com/users/rimey/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rimey/subscriptions","organizations_url":"https://api.github.com/users/rimey/orgs","repos_url":"https://api.github.com/users/rimey/repos","events_url":"https://api.github.com/users/rimey/events{/privacy}","received_events_url":"https://api.github.com/users/rimey/received_events","type":"User","site_admin":false},"body":"This initial version of the monitoring client supports querying of time series, metric descriptors, and monitored resource descriptors.\r\n\r\nThe authors of this code are @supriyagarg and myself, both at Google.","created_at":"2016-04-03T19:15:57Z","updated_at":"2016-04-21T22:25:30Z","closed_at":null,"merged_at":null,"merge_commit_sha":"1876abb896d155d1cf7c2a12bed778dd5d6234ed","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/pulls/1691/commits","review_comments_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/pulls/1691/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/1691/comments","statuses_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/statuses/2dfd890e15b0b1b81ac294c65a43898af3f81da4","head":{"label":"rimey:monitoring-api","ref":"monitoring-api","sha":"2dfd890e15b0b1b81ac294c65a43898af3f81da4","user":{"login":"rimey","id":360806,"avatar_url":"https://avatars.githubusercontent.com/u/360806?v=3","gravatar_id":"","url":"https://api.github.com/users/rimey","html_url":"https://github.com/rimey","followers_url":"https://api.github.com/users/rimey/followers","following_url":"https://api.github.com/users/rimey/following{/other_user}","gists_url":"https://api.github.com/users/rimey/gists{/gist_id}","starred_url":"https://api.github.com/users/rimey/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rimey/subscriptions","organizations_url":"https://api.github.com/users/rimey/orgs","repos_url":"https://api.github.com/users/rimey/repos","events_url":"https://api.github.com/users/rimey/events{/privacy}","received_events_url":"https://api.github.com/users/rimey/received_events","type":"User","site_admin":false},"repo":{"id":55299094,"name":"gcloud-python","full_name":"rimey/gcloud-python","owner":{"login":"rimey","id":360806,"avatar_url":"https://avatars.githubusercontent.com/u/360806?v=3","gravatar_id":"","url":"https://api.github.com/users/rimey","html_url":"https://github.com/rimey","followers_url":"https://api.github.com/users/rimey/followers","following_url":"https://api.github.com/users/rimey/following{/other_user}","gists_url":"https://api.github.com/users/rimey/gists{/gist_id}","starred_url":"https://api.github.com/users/rimey/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rimey/subscriptions","organizations_url":"https://api.github.com/users/rimey/orgs","repos_url":"https://api.github.com/users/rimey/repos","events_url":"https://api.github.com/users/rimey/events{/privacy}","received_events_url":"https://api.github.com/users/rimey/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/rimey/gcloud-python","description":"Google Cloud Client Library for Python","fork":true,"url":"https://api.github.com/repos/rimey/gcloud-python","forks_url":"https://api.github.com/repos/rimey/gcloud-python/forks","keys_url":"https://api.github.com/repos/rimey/gcloud-python/keys{/key_id}","collaborators_url":"https://api.github.com/repos/rimey/gcloud-python/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/rimey/gcloud-python/teams","hooks_url":"https://api.github.com/repos/rimey/gcloud-python/hooks","issue_events_url":"https://api.github.com/repos/rimey/gcloud-python/issues/events{/number}","events_url":"https://api.github.com/repos/rimey/gcloud-python/events","assignees_url":"https://api.github.com/repos/rimey/gcloud-python/assignees{/user}","branches_url":"https://api.github.com/repos/rimey/gcloud-python/branches{/branch}","tags_url":"https://api.github.com/repos/rimey/gcloud-python/tags","blobs_url":"https://api.github.com/repos/rimey/gcloud-python/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/rimey/gcloud-python/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/rimey/gcloud-python/git/refs{/sha}","trees_url":"https://api.github.com/repos/rimey/gcloud-python/git/trees{/sha}","statuses_url":"https://api.github.com/repos/rimey/gcloud-python/statuses/{sha}","languages_url":"https://api.github.com/repos/rimey/gcloud-python/languages","stargazers_url":"https://api.github.com/repos/rimey/gcloud-python/stargazers","contributors_url":"https://api.github.com/repos/rimey/gcloud-python/contributors","subscribers_url":"https://api.github.com/repos/rimey/gcloud-python/subscribers","subscription_url":"https://api.github.com/repos/rimey/gcloud-python/subscription","commits_url":"https://api.github.com/repos/rimey/gcloud-python/commits{/sha}","git_commits_url":"https://api.github.com/repos/rimey/gcloud-python/git/commits{/sha}","comments_url":"https://api.github.com/repos/rimey/gcloud-python/comments{/number}","issue_comment_url":"https://api.github.com/repos/rimey/gcloud-python/issues/comments{/number}","contents_url":"https://api.github.com/repos/rimey/gcloud-python/contents/{+path}","compare_url":"https://api.github.com/repos/rimey/gcloud-python/compare/{base}...{head}","merges_url":"https://api.github.com/repos/rimey/gcloud-python/merges","archive_url":"https://api.github.com/repos/rimey/gcloud-python/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/rimey/gcloud-python/downloads","issues_url":"https://api.github.com/repos/rimey/gcloud-python/issues{/number}","pulls_url":"https://api.github.com/repos/rimey/gcloud-python/pulls{/number}","milestones_url":"https://api.github.com/repos/rimey/gcloud-python/milestones{/number}","notifications_url":"https://api.github.com/repos/rimey/gcloud-python/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/rimey/gcloud-python/labels{/name}","releases_url":"https://api.github.com/repos/rimey/gcloud-python/releases{/id}","deployments_url":"https://api.github.com/repos/rimey/gcloud-python/deployments","created_at":"2016-04-02T14:33:17Z","updated_at":"2016-04-02T14:33:20Z","pushed_at":"2016-04-21T22:00:12Z","git_url":"git://github.com/rimey/gcloud-python.git","ssh_url":"git@github.com:rimey/gcloud-python.git","clone_url":"https://github.com/rimey/gcloud-python.git","svn_url":"https://github.com/rimey/gcloud-python","homepage":"https://googlecloudplatform.github.io/gcloud-python/","size":47986,"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":"cefff49fb57eea68e15e3a64f1a71c1ca107f44d","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-04-20T21:43:47Z","pushed_at":"2016-04-21T22:00:13Z","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":51910,"stargazers_count":288,"watchers_count":288,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":164,"mirror_url":null,"open_issues_count":115,"forks":164,"open_issues":115,"watchers":288,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/pulls/1691"},"html":{"href":"https://github.com/GoogleCloudPlatform/gcloud-python/pull/1691"},"issue":{"href":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/issues/1691"},"comments":{"href":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/issues/1691/comments"},"review_comments":{"href":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/pulls/1691/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/1691/commits"},"statuses":{"href":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-python/statuses/2dfd890e15b0b1b81ac294c65a43898af3f81da4"}}}}