{"action":"created","comment":{"url":"https://api.github.com/repos/numenta/numenta-apps/pulls/comments/43070648","id":43070648,"diff_hunk":"@@ -38,8 +90,133 @@ def dispatchNotification(self, checkFn, excType, excValue, excTraceback):\n     :param type excType: Exception type\n     :param exception excValue: Exception value\n     :param traceback excTraceback: Exception traceback\n+    :returns: None\n+    \"\"\"\n+    raise NotImplementedError(\"dispatchNotification() must be implemented in \"\n+                              \"subclass per abc protocol.\")\n+\n+\n+  @staticmethod\n+  def hashExceptionValue(excValue):\n+    \"\"\"\n+    :param exception excValue:\n+    :returns: Hash digest (currently sha1)\n+    \"\"\"\n+    return hashlib.sha1(str(excValue)).digest()\n+\n+\n+  @classmethod\n+  def clearAllNotificationsInteractiveConsoleScriptEntryPoint(cls):\n+    \"\"\" Interactive utility for manually clearing out all notifications.\n+    Meant to be used as a console script entry point, defined in setup.py.\n+\n+    User will be prompted with a stern warning to delete notifications, and\n+    required to enter \"Yes-\" followed by a random integer.\n+    \"\"\"\n+    engine = monitorsdb.engineFactory()\n+    expectedAnswer = \"Yes-%s\" % (random.randint(1, 30),)\n+\n+    answer = raw_input(\n+      \"Attention!  You are about to do something irreversible, and potentially\"\n+      \" dangerous.\\n\"\n+      \"\\n\"\n+      \"To back out immediately without making any changes, feel free to type \"\n+      \"anything but \\\"{}\\\" in the prompt below, and press return.\\n\"\n+      \"\\n\"\n+      \"Should you choose to continue, all notifications in the DATABASE \\\"{}\\\"\"\n+      \"will be PERMANENTLY DELETED.\\n\"\n+      \"\\n\"\n+      \"Are you sure you want to continue? \"\n+      .format(expectedAnswer, engine))\n+\n+    if answer.strip() != expectedAnswer:\n+      print \"Aborting - Wise choice, my friend. Bye.\"\n+\n+    #pylint: disable=E1120\n+    cmd = cls._dispatchTable.delete()\n+    monitorsdb.retryOnTransientErrors(monitorsdb.engineFactory().execute)(cmd)\n+\n+    print \"Notifications deleted.\"\n+\n+\n+  @classmethod\n+  @monitorsdb.retryOnTransientErrors\n+  def cleanupOldNotifications(cls):\n+    \"\"\" Delete all notifications older than a date determined by subtracting\n+    the number of days held in the value of the NOTIFICATION_RETENTION_PERIOD\n+    module-level variable from the current UTC timestamp.\n+    \"\"\"\n+    cutoffDate = (datetime.utcnow() -\n+                  timedelta(days=NOTIFICATION_RETENTION_PERIOD))\n+    #pylint: disable=E1120\n+    cmd = (cls._dispatchTable\n+              .delete()\n+              .where(cls._dispatchTable.c.timestamp < cutoffDate))\n+    monitorsdb.engineFactory().execute(cmd)\n+\n+\n+  @classmethod\n+  def recordNotification(cls, conn, checkFn, excType, excValue):\n+    \"\"\" Record notification, uniquely identified by the name of the function,\n+    the exception type, and a hash digest of the exception value that triggered\n+    the notification.  Duplicate notifications will be silently ignored.\n+\n+    :param conn: Database connection.  Note, preventDuplicates() starts a\n+      transaction using the monitorsdb.engineFactory().begin() context\n+      manager.  If the actual dispatchNotification() call fails for whatever\n+      reason, the transaction is not completed and changes are not committed.\n+    :param function checkFn: Function that triggered notification\n+    :param excType: Exception type that triggered notification\n+    :param excValue: Actual exception that triggered notification\n+    :returns: Boolean result.  True if notification succesfully recorded, False\n+      if IntegrityError raised due to pre-existing duplicate.\n+    \"\"\"\n+    excValueDigest = cls.hashExceptionValue(excValue)\n+    #pylint: disable=E1120\n+    ins = (cls._dispatchTable\n+              .insert()","path":"taurus.monitoring/taurus/monitoring/monitor_dispatcher.py","position":157,"original_position":157,"commit_id":"10b24a9f11d1aa4f8a2b282bf347c3ff22da21a9","original_commit_id":"10b24a9f11d1aa4f8a2b282bf347c3ff22da21a9","user":{"login":"vitaly-krugl","id":1441066,"avatar_url":"https://avatars.githubusercontent.com/u/1441066?v=3","gravatar_id":"","url":"https://api.github.com/users/vitaly-krugl","html_url":"https://github.com/vitaly-krugl","followers_url":"https://api.github.com/users/vitaly-krugl/followers","following_url":"https://api.github.com/users/vitaly-krugl/following{/other_user}","gists_url":"https://api.github.com/users/vitaly-krugl/gists{/gist_id}","starred_url":"https://api.github.com/users/vitaly-krugl/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vitaly-krugl/subscriptions","organizations_url":"https://api.github.com/users/vitaly-krugl/orgs","repos_url":"https://api.github.com/users/vitaly-krugl/repos","events_url":"https://api.github.com/users/vitaly-krugl/events{/privacy}","received_events_url":"https://api.github.com/users/vitaly-krugl/received_events","type":"User","site_admin":false},"body":"@oxtopus: I just ran pylint on this module, and get the following messages about some of the problems that I pointed out here:\r\n\r\n```\r\nLine 135\tI0011: Locally disabling no-value-for-parameter (E1120)\r\nLine 151\tI0011: Locally disabling no-value-for-parameter (E1120)\r\nLine 175\tI0011: Locally disabling no-value-for-parameter (E1120)\r\nLine 228\tI0011: Locally disabling broad-except (W0703)\r\nLine 153\tC0330: Wrong continued indentation.\r\nLine 154\tC0330: Wrong continued indentation.\r\nLine 177\tC0330: Wrong continued indentation.\r\nLine 178\tC0330: Wrong continued indentation.\r\n\r\nLine 187\tColumn 20\tW1202: Use % formatting in logging functions but pass the % parameters as arguments\r\n```","created_at":"2015-10-27T00:04:35Z","updated_at":"2015-10-27T00:04:35Z","html_url":"https://github.com/numenta/numenta-apps/pull/414#discussion_r43070648","pull_request_url":"https://api.github.com/repos/numenta/numenta-apps/pulls/414","_links":{"self":{"href":"https://api.github.com/repos/numenta/numenta-apps/pulls/comments/43070648"},"html":{"href":"https://github.com/numenta/numenta-apps/pull/414#discussion_r43070648"},"pull_request":{"href":"https://api.github.com/repos/numenta/numenta-apps/pulls/414"}}},"pull_request":{"url":"https://api.github.com/repos/numenta/numenta-apps/pulls/414","id":47835338,"html_url":"https://github.com/numenta/numenta-apps/pull/414","diff_url":"https://github.com/numenta/numenta-apps/pull/414.diff","patch_url":"https://github.com/numenta/numenta-apps/pull/414.patch","issue_url":"https://api.github.com/repos/numenta/numenta-apps/issues/414","number":414,"state":"open","locked":false,"title":"ENG-79 Nobody inspects the spammish repetition","user":{"login":"oxtopus","id":326528,"avatar_url":"https://avatars.githubusercontent.com/u/326528?v=3","gravatar_id":"","url":"https://api.github.com/users/oxtopus","html_url":"https://github.com/oxtopus","followers_url":"https://api.github.com/users/oxtopus/followers","following_url":"https://api.github.com/users/oxtopus/following{/other_user}","gists_url":"https://api.github.com/users/oxtopus/gists{/gist_id}","starred_url":"https://api.github.com/users/oxtopus/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/oxtopus/subscriptions","organizations_url":"https://api.github.com/users/oxtopus/orgs","repos_url":"https://api.github.com/users/oxtopus/repos","events_url":"https://api.github.com/users/oxtopus/events{/privacy}","received_events_url":"https://api.github.com/users/oxtopus/received_events","type":"User","site_admin":false},"body":"Includes an extension to the framework shared by the supervisor and latency monitors to prevent spamming multiple repeated notifications as well as other fixes.\r\n\r\nOf note, this only maintains uniqueness of notifications during a fixed retention period of 7 days.  If an issue is not solved within 7 days, the old notification is deleted and a new one is sent in its place.\r\n\r\nTypical email body looks like this:\r\n\r\n```\r\n*Monitor Info*\r\nCurrent Datetime:\tThu Oct 15 15:50:09 2015\r\nMonitor running on:\tAustins-MacBook-Pro-6.local\r\nResource being monitored:\ttaurus-model-latency-monitor --loggingConsole=stderr --days=14 --monitorConfPath=/Users/amarshall/nta/numenta-apps/taurus.monitoring/conf/monitoring.conf --loggingLevel=INFO --threshold=3600 --sigmaMultiplier=3 --metricDataTable=taurus.metric_data.production\r\n\r\n*Error Details*\r\nTraceback (most recent call last):\r\n File \"/Users/amarshall/nta/numenta-apps/taurus.monitoring/taurus/monitoring/monitor_dispatcher.py\", line 227, in checkAll\r\n   check(self)\r\n File \"/Users/amarshall/nta/numenta-apps/taurus.monitoring/taurus/monitoring/latency_monitor/model_latency_monitor.py\", line 271, in checkAllModelLatency\r\n   raise LatencyMonitorError(msg)\r\nLatencyMonitorError: The following models have exceeded the acceptable threshold for time since last timestamp in taurus.metric_data.production DynamoDB table:\r\n   LatencyMonitorErrorParams(model_name=u'XIGNITE.DTV.CLOSINGPRICE', model_uid=u'3de44abc62ab4b2ba5d1adbc3f70ea92', threshold=None)\r\n   LatencyMonitorErrorParams(model_name=u'XIGNITE.WAG.VOLUME', model_uid=u'44c4ae7e287b40fdbdf3f90194fecaed', threshold=None)\r\n   LatencyMonitorErrorParams(model_name=u'XIGNITE.ACT.CLOSINGPRICE', model_uid=u'6bb20651eb3a49bc9a37185ae8a5018e', threshold=None)\r\n   LatencyMonitorErrorParams(model_name=u'XIGNITE.KRFT.VOLUME', model_uid=u'75f018e7eaea4ab893f742e49a9cd8fb', threshold=None)\r\n   LatencyMonitorErrorParams(model_name=u'XIGNITE.KRFT.CLOSINGPRICE', model_uid=u'8066728b6fec4761ae682871e9fdb3fd', threshold=None)\r\n   LatencyMonitorErrorParams(model_name=u'XIGNITE.DTV.VOLUME', model_uid=u'adb9eb914d5643ad9f7ed69847f064c8', threshold=None)\r\n   LatencyMonitorErrorParams(model_name=u'XIGNITE.WAG.CLOSINGPRICE', model_uid=u'bd7e5d65a9704c38988d4c399eaf1cf8', threshold=None)\r\n   LatencyMonitorErrorParams(model_name=u'XIGNITE.ACT.VOLUME', model_uid=u'ef5ba1ad02334b709a78774e6d332e17', threshold=None)\r\n```\r\n\r\nSample log output:\r\n\r\n```\r\nAustins-MacBook-Pro-6:numenta-apps amarshall$ taurus-model-latency-monitor --monitorConfPath=/Users/amarshall/nta/numenta-apps/taurus.monitoring/conf/monitoring.conf --metricDataTable=taurus.metric_data.production --loggingLevel=INFO --loggingConsole=stderr\r\n2015-10-15 22:38:39,356 - taurus.monitoring.latency_monitor.model_latency_monitor(9283) - INFO - Initialized taurus-model-latency-monitor --loggingConsole=stderr --days=14 --monitorConfPath=/Users/amarshall/nta/numenta-apps/taurus.monitoring/conf/monitoring.conf --loggingLevel=INFO --threshold=3600 --sigmaMultiplier=3 --metricDataTable=taurus.metric_data.production\r\n2015-10-15 22:38:39,413 - requests.packages.urllib3.connectionpool(9283) - INFO - Starting new HTTPS connection (1): taurus-server.production.numenta.com\r\n2015-10-15 22:50:09,013 - taurus.monitoring.latency_monitor.model_latency_monitor(9283) - INFO - Processed statistics for 579 models, found 8 errors.\r\n2015-10-15 22:50:09,029 - taurus.monitoring.latency_monitor.model_latency_monitor(9283) - INFO - Dispatching notification: {'subjectPrefix': 'Model Latency Monitor', 'message': 'Traceback (most recent call last):\\n  File \"/Users/amarshall/nta/numenta-apps/taurus.monitoring/taurus/monitoring/monitor_dispatcher.py\", line 227, in checkAll\\n    check(self)\\n  File \"/Users/amarshall/nta/numenta-apps/taurus.monitoring/taurus/monitoring/latency_monitor/model_latency_monitor.py\", line 271, in checkAllModelLatency\\n    raise LatencyMonitorError(msg)\\nLatencyMonitorError: The following models have exceeded the acceptable threshold for time since last timestamp in taurus.metric_data.production DynamoDB table:\\n    LatencyMonitorErrorParams(model_name=u\\'XIGNITE.DTV.CLOSINGPRICE\\', model_uid=u\\'3de44abc62ab4b2ba5d1adbc3f70ea92\\', threshold=None)\\n    LatencyMonitorErrorParams(model_name=u\\'XIGNITE.WAG.VOLUME\\', model_uid=u\\'44c4ae7e287b40fdbdf3f90194fecaed\\', threshold=None)\\n    LatencyMonitorErrorParams(model_name=u\\'XIGNITE.ACT.CLOSINGPRICE\\', model_uid=u\\'6bb20651eb3a49bc9a37185ae8a5018e\\', threshold=None)\\n    LatencyMonitorErrorParams(model_name=u\\'XIGNITE.KRFT.VOLUME\\', model_uid=u\\'75f018e7eaea4ab893f742e49a9cd8fb\\', threshold=None)\\n    LatencyMonitorErrorParams(model_name=u\\'XIGNITE.KRFT.CLOSINGPRICE\\', model_uid=u\\'8066728b6fec4761ae682871e9fdb3fd\\', threshold=None)\\n    LatencyMonitorErrorParams(model_name=u\\'XIGNITE.DTV.VOLUME\\', model_uid=u\\'adb9eb914d5643ad9f7ed69847f064c8\\', threshold=None)\\n    LatencyMonitorErrorParams(model_name=u\\'XIGNITE.WAG.CLOSINGPRICE\\', model_uid=u\\'bd7e5d65a9704c38988d4c399eaf1cf8\\', threshold=None)\\n    LatencyMonitorErrorParams(model_name=u\\'XIGNITE.ACT.VOLUME\\', model_uid=u\\'ef5ba1ad02334b709a78774e6d332e17\\', threshold=None)\\n', 'params': {'senderAddress': 'support@numenta.com', 'awsAccessKeyId': None, 'recipients': 'amarshall@numenta.com', 'awsSecretAccessKey': None, 'awsRegion': 'us-east-1', 'sesEndpoint': 'email.us-east-1.amazonaws.com'}, 'resourceName': 'taurus-model-latency-monitor --loggingConsole=stderr --days=14 --monitorConfPath=/Users/amarshall/nta/numenta-apps/taurus.monitoring/conf/monitoring.conf --loggingLevel=INFO --threshold=3600 --sigmaMultiplier=3 --metricDataTable=taurus.metric_data.production', 'monitorName': 'taurus.monitoring.latency_monitor.model_latency_monitor:checkAllModelLatency'}\r\n2015-10-15 22:50:10,364 - nta.utils.error_reporting(9283) - INFO - Called boto.ses.SESConnection.send_email. This does not necessarily mean that the email was successfully sent.\r\n```\r\n\r\ncc @vitaly-krugl @scottpurdy ","created_at":"2015-10-15T20:12:09Z","updated_at":"2015-10-27T00:04:35Z","closed_at":null,"merged_at":null,"merge_commit_sha":"4da68ebb0f871f5c56fc5738f31724b1b311356e","assignee":{"login":"vitaly-krugl","id":1441066,"avatar_url":"https://avatars.githubusercontent.com/u/1441066?v=3","gravatar_id":"","url":"https://api.github.com/users/vitaly-krugl","html_url":"https://github.com/vitaly-krugl","followers_url":"https://api.github.com/users/vitaly-krugl/followers","following_url":"https://api.github.com/users/vitaly-krugl/following{/other_user}","gists_url":"https://api.github.com/users/vitaly-krugl/gists{/gist_id}","starred_url":"https://api.github.com/users/vitaly-krugl/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vitaly-krugl/subscriptions","organizations_url":"https://api.github.com/users/vitaly-krugl/orgs","repos_url":"https://api.github.com/users/vitaly-krugl/repos","events_url":"https://api.github.com/users/vitaly-krugl/events{/privacy}","received_events_url":"https://api.github.com/users/vitaly-krugl/received_events","type":"User","site_admin":false},"milestone":null,"commits_url":"https://api.github.com/repos/numenta/numenta-apps/pulls/414/commits","review_comments_url":"https://api.github.com/repos/numenta/numenta-apps/pulls/414/comments","review_comment_url":"https://api.github.com/repos/numenta/numenta-apps/pulls/comments{/number}","comments_url":"https://api.github.com/repos/numenta/numenta-apps/issues/414/comments","statuses_url":"https://api.github.com/repos/numenta/numenta-apps/statuses/10b24a9f11d1aa4f8a2b282bf347c3ff22da21a9","head":{"label":"oxtopus:ENG-79-spam-in-monitors","ref":"ENG-79-spam-in-monitors","sha":"10b24a9f11d1aa4f8a2b282bf347c3ff22da21a9","user":{"login":"oxtopus","id":326528,"avatar_url":"https://avatars.githubusercontent.com/u/326528?v=3","gravatar_id":"","url":"https://api.github.com/users/oxtopus","html_url":"https://github.com/oxtopus","followers_url":"https://api.github.com/users/oxtopus/followers","following_url":"https://api.github.com/users/oxtopus/following{/other_user}","gists_url":"https://api.github.com/users/oxtopus/gists{/gist_id}","starred_url":"https://api.github.com/users/oxtopus/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/oxtopus/subscriptions","organizations_url":"https://api.github.com/users/oxtopus/orgs","repos_url":"https://api.github.com/users/oxtopus/repos","events_url":"https://api.github.com/users/oxtopus/events{/privacy}","received_events_url":"https://api.github.com/users/oxtopus/received_events","type":"User","site_admin":false},"repo":{"id":36955481,"name":"numenta-apps","full_name":"oxtopus/numenta-apps","owner":{"login":"oxtopus","id":326528,"avatar_url":"https://avatars.githubusercontent.com/u/326528?v=3","gravatar_id":"","url":"https://api.github.com/users/oxtopus","html_url":"https://github.com/oxtopus","followers_url":"https://api.github.com/users/oxtopus/followers","following_url":"https://api.github.com/users/oxtopus/following{/other_user}","gists_url":"https://api.github.com/users/oxtopus/gists{/gist_id}","starred_url":"https://api.github.com/users/oxtopus/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/oxtopus/subscriptions","organizations_url":"https://api.github.com/users/oxtopus/orgs","repos_url":"https://api.github.com/users/oxtopus/repos","events_url":"https://api.github.com/users/oxtopus/events{/privacy}","received_events_url":"https://api.github.com/users/oxtopus/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/oxtopus/numenta-apps","description":"HTM based applications and support libraries. Includes Grok for IT Analytics and Grok for Stocks.","fork":true,"url":"https://api.github.com/repos/oxtopus/numenta-apps","forks_url":"https://api.github.com/repos/oxtopus/numenta-apps/forks","keys_url":"https://api.github.com/repos/oxtopus/numenta-apps/keys{/key_id}","collaborators_url":"https://api.github.com/repos/oxtopus/numenta-apps/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/oxtopus/numenta-apps/teams","hooks_url":"https://api.github.com/repos/oxtopus/numenta-apps/hooks","issue_events_url":"https://api.github.com/repos/oxtopus/numenta-apps/issues/events{/number}","events_url":"https://api.github.com/repos/oxtopus/numenta-apps/events","assignees_url":"https://api.github.com/repos/oxtopus/numenta-apps/assignees{/user}","branches_url":"https://api.github.com/repos/oxtopus/numenta-apps/branches{/branch}","tags_url":"https://api.github.com/repos/oxtopus/numenta-apps/tags","blobs_url":"https://api.github.com/repos/oxtopus/numenta-apps/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/oxtopus/numenta-apps/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/oxtopus/numenta-apps/git/refs{/sha}","trees_url":"https://api.github.com/repos/oxtopus/numenta-apps/git/trees{/sha}","statuses_url":"https://api.github.com/repos/oxtopus/numenta-apps/statuses/{sha}","languages_url":"https://api.github.com/repos/oxtopus/numenta-apps/languages","stargazers_url":"https://api.github.com/repos/oxtopus/numenta-apps/stargazers","contributors_url":"https://api.github.com/repos/oxtopus/numenta-apps/contributors","subscribers_url":"https://api.github.com/repos/oxtopus/numenta-apps/subscribers","subscription_url":"https://api.github.com/repos/oxtopus/numenta-apps/subscription","commits_url":"https://api.github.com/repos/oxtopus/numenta-apps/commits{/sha}","git_commits_url":"https://api.github.com/repos/oxtopus/numenta-apps/git/commits{/sha}","comments_url":"https://api.github.com/repos/oxtopus/numenta-apps/comments{/number}","issue_comment_url":"https://api.github.com/repos/oxtopus/numenta-apps/issues/comments{/number}","contents_url":"https://api.github.com/repos/oxtopus/numenta-apps/contents/{+path}","compare_url":"https://api.github.com/repos/oxtopus/numenta-apps/compare/{base}...{head}","merges_url":"https://api.github.com/repos/oxtopus/numenta-apps/merges","archive_url":"https://api.github.com/repos/oxtopus/numenta-apps/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/oxtopus/numenta-apps/downloads","issues_url":"https://api.github.com/repos/oxtopus/numenta-apps/issues{/number}","pulls_url":"https://api.github.com/repos/oxtopus/numenta-apps/pulls{/number}","milestones_url":"https://api.github.com/repos/oxtopus/numenta-apps/milestones{/number}","notifications_url":"https://api.github.com/repos/oxtopus/numenta-apps/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/oxtopus/numenta-apps/labels{/name}","releases_url":"https://api.github.com/repos/oxtopus/numenta-apps/releases{/id}","created_at":"2015-06-05T21:09:03Z","updated_at":"2015-06-05T21:09:08Z","pushed_at":"2015-10-23T15:24:20Z","git_url":"git://github.com/oxtopus/numenta-apps.git","ssh_url":"git@github.com:oxtopus/numenta-apps.git","clone_url":"https://github.com/oxtopus/numenta-apps.git","svn_url":"https://github.com/oxtopus/numenta-apps","homepage":"http://numenta.com","size":48737,"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":"numenta:master","ref":"master","sha":"c66647b7d96dfd75526887602976f8fee7e4bd95","user":{"login":"numenta","id":1039191,"avatar_url":"https://avatars.githubusercontent.com/u/1039191?v=3","gravatar_id":"","url":"https://api.github.com/users/numenta","html_url":"https://github.com/numenta","followers_url":"https://api.github.com/users/numenta/followers","following_url":"https://api.github.com/users/numenta/following{/other_user}","gists_url":"https://api.github.com/users/numenta/gists{/gist_id}","starred_url":"https://api.github.com/users/numenta/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/numenta/subscriptions","organizations_url":"https://api.github.com/users/numenta/orgs","repos_url":"https://api.github.com/users/numenta/repos","events_url":"https://api.github.com/users/numenta/events{/privacy}","received_events_url":"https://api.github.com/users/numenta/received_events","type":"Organization","site_admin":false},"repo":{"id":36754402,"name":"numenta-apps","full_name":"numenta/numenta-apps","owner":{"login":"numenta","id":1039191,"avatar_url":"https://avatars.githubusercontent.com/u/1039191?v=3","gravatar_id":"","url":"https://api.github.com/users/numenta","html_url":"https://github.com/numenta","followers_url":"https://api.github.com/users/numenta/followers","following_url":"https://api.github.com/users/numenta/following{/other_user}","gists_url":"https://api.github.com/users/numenta/gists{/gist_id}","starred_url":"https://api.github.com/users/numenta/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/numenta/subscriptions","organizations_url":"https://api.github.com/users/numenta/orgs","repos_url":"https://api.github.com/users/numenta/repos","events_url":"https://api.github.com/users/numenta/events{/privacy}","received_events_url":"https://api.github.com/users/numenta/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/numenta/numenta-apps","description":"HTM based applications and support libraries. Includes Grok for IT Analytics and Grok for Stocks (code name \"Taurus\").","fork":false,"url":"https://api.github.com/repos/numenta/numenta-apps","forks_url":"https://api.github.com/repos/numenta/numenta-apps/forks","keys_url":"https://api.github.com/repos/numenta/numenta-apps/keys{/key_id}","collaborators_url":"https://api.github.com/repos/numenta/numenta-apps/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/numenta/numenta-apps/teams","hooks_url":"https://api.github.com/repos/numenta/numenta-apps/hooks","issue_events_url":"https://api.github.com/repos/numenta/numenta-apps/issues/events{/number}","events_url":"https://api.github.com/repos/numenta/numenta-apps/events","assignees_url":"https://api.github.com/repos/numenta/numenta-apps/assignees{/user}","branches_url":"https://api.github.com/repos/numenta/numenta-apps/branches{/branch}","tags_url":"https://api.github.com/repos/numenta/numenta-apps/tags","blobs_url":"https://api.github.com/repos/numenta/numenta-apps/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/numenta/numenta-apps/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/numenta/numenta-apps/git/refs{/sha}","trees_url":"https://api.github.com/repos/numenta/numenta-apps/git/trees{/sha}","statuses_url":"https://api.github.com/repos/numenta/numenta-apps/statuses/{sha}","languages_url":"https://api.github.com/repos/numenta/numenta-apps/languages","stargazers_url":"https://api.github.com/repos/numenta/numenta-apps/stargazers","contributors_url":"https://api.github.com/repos/numenta/numenta-apps/contributors","subscribers_url":"https://api.github.com/repos/numenta/numenta-apps/subscribers","subscription_url":"https://api.github.com/repos/numenta/numenta-apps/subscription","commits_url":"https://api.github.com/repos/numenta/numenta-apps/commits{/sha}","git_commits_url":"https://api.github.com/repos/numenta/numenta-apps/git/commits{/sha}","comments_url":"https://api.github.com/repos/numenta/numenta-apps/comments{/number}","issue_comment_url":"https://api.github.com/repos/numenta/numenta-apps/issues/comments{/number}","contents_url":"https://api.github.com/repos/numenta/numenta-apps/contents/{+path}","compare_url":"https://api.github.com/repos/numenta/numenta-apps/compare/{base}...{head}","merges_url":"https://api.github.com/repos/numenta/numenta-apps/merges","archive_url":"https://api.github.com/repos/numenta/numenta-apps/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/numenta/numenta-apps/downloads","issues_url":"https://api.github.com/repos/numenta/numenta-apps/issues{/number}","pulls_url":"https://api.github.com/repos/numenta/numenta-apps/pulls{/number}","milestones_url":"https://api.github.com/repos/numenta/numenta-apps/milestones{/number}","notifications_url":"https://api.github.com/repos/numenta/numenta-apps/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/numenta/numenta-apps/labels{/name}","releases_url":"https://api.github.com/repos/numenta/numenta-apps/releases{/id}","created_at":"2015-06-02T18:49:30Z","updated_at":"2015-10-23T04:52:40Z","pushed_at":"2015-10-26T23:51:33Z","git_url":"git://github.com/numenta/numenta-apps.git","ssh_url":"git@github.com:numenta/numenta-apps.git","clone_url":"https://github.com/numenta/numenta-apps.git","svn_url":"https://github.com/numenta/numenta-apps","homepage":"http://numenta.com","size":51410,"stargazers_count":68,"watchers_count":68,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":42,"mirror_url":null,"open_issues_count":7,"forks":42,"open_issues":7,"watchers":68,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/numenta/numenta-apps/pulls/414"},"html":{"href":"https://github.com/numenta/numenta-apps/pull/414"},"issue":{"href":"https://api.github.com/repos/numenta/numenta-apps/issues/414"},"comments":{"href":"https://api.github.com/repos/numenta/numenta-apps/issues/414/comments"},"review_comments":{"href":"https://api.github.com/repos/numenta/numenta-apps/pulls/414/comments"},"review_comment":{"href":"https://api.github.com/repos/numenta/numenta-apps/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/numenta/numenta-apps/pulls/414/commits"},"statuses":{"href":"https://api.github.com/repos/numenta/numenta-apps/statuses/10b24a9f11d1aa4f8a2b282bf347c3ff22da21a9"}}}}