GitHub PullRequestReviewCommentEvent at 2014-07-03 12:08:01
Repository: airbrake-python
Actor: samstav
Payload: {"action":"created","comment":{"url":"https://api.github.com/repos/airbrake/airbrake-python/pulls/comments/14509947","id":14509947,"diff_hunk":"@@ -0,0 +1,272 @@\n+\"\"\"Airbrake object to handle airbrake.io reporting.\"\"\"\n+import json\n+import os\n+import platform\n+import socket\n+import sys\n+import traceback\n+import urlparse\n+import warnings\n+\n+import requests\n+\n+from airbrake import __notifier__ as airbrake_python_notifier\n+from airbrake import utils\n+\n+\n+class Airbrake(object):\n+    \"\"\"\n+    Class to handle exceptions that need to be sent to airbrake.io\n+\n+    The payload (dict) to be POSTed as json is defined by an\n+    instance's `payload` attribute, which can be modified after\n+    Airbrake instantiation.\n+\n+    If auto_notify=True (default), errors logged ( using Airbrake.log() )\n+    will automatically be shipped; otherwise, logged errors will be\n+    aggregated and shipped as a group when Airbrake.notify() is called.\n+\n+    Non-logging Handler usage:\n+\n+    // Auto-notify is enabled by default\n+\n+        import airbrake\n+        ab = Airbrake(project_id=\"1234\", api_key=\"1234\")\n+\n+        try:\n+            1/0\n+        except Exception:\n+            ab.log()\n+\n+    If auto-notify is disabled:\n+\n+        import airbrake\n+        ab = Airbrake(project_id=\"1234\", api_key=\"1234\", auto_notify=False)\n+\n+        try:\n+            1/0\n+        except Exception as exc:\n+            ab.log()\n+\n+        # more code, possible errors\n+\n+        ab.notify()\n+\n+    The airbrake.io docs used to implements this class are here:\n+        http://help.airbrake.io/kb/api-2/notifier-api-v3\n+    \"\"\"\n+\n+    def __init__(self, project_id=None, api_key=None, environment=None,\n+                 use_ssl=True, auto_notify=True):\n+\n+        #properties\n+        self._api_url = None\n+        self._env_context = None\n+        self.deploy_url = \"http://api.airbrake.io/deploys.txt\"\n+        self.notifier = airbrake_python_notifier\n+\n+        if not environment:\n+            environment = (os.getenv('AIRBRAKE_ENVIRONMENT') or\n+                           socket.gethostname())\n+        if not project_id:\n+            project_id = os.getenv('AIRBRAKE_PROJECT_ID', '')\n+        if not api_key:\n+            api_key = os.getenv('AIRBRAKE_API_KEY', '')\n+\n+        self.environment = str(environment)\n+        self.project_id = str(project_id)\n+        self.api_key = str(api_key)\n+        self.auto_notify = auto_notify\n+        self.use_ssl = use_ssl\n+        self.errors = []\n+        self.payload_params = {}\n+        self.payload_session = {}\n+        self.payload = {'context': self.context,\n+                        'params': self.payload_params,\n+                        'errors': self.errors,\n+                        'notifier': self.notifier,\n+                        'environment': {},\n+                        'session': self.payload_session}\n+\n+    def __repr__(self):\n+        return (\"Airbrake(project_id=%s, api_key=*****, environment=%s, \"\n+                \"use_ssl=%s, auto_notify=%s\"\n+                % (self.project_id, self.environment,\n+                   self.use_ssl, self.auto_notify))\n+\n+    @property\n+    def context(self):\n+        \"\"\"Contains the python, os, and app environment context.\"\"\"\n+        if not self._env_context:\n+            self._env_context = {}\n+            # python\n+            version = platform.python_version()\n+            self._env_context.update({'language': 'Python %s' % version})\n+            # os\n+            plat = platform.platform()\n+            self._env_context.update({'os': plat})\n+            # env name\n+            self._env_context.update({'environment': self.environment})\n+            # TODO(samstav)\n+            #   add user info:\n+            #       userID, userName, userEmail\n+            #   add application info:\n+            #       version, url, rootDirectory\n+        return self._env_context\n+\n+    @property\n+    def api_url(self):\n+        \"\"\"Create the airbrake api endpoint and return a string.\"\"\"\n+        if not self._api_url:\n+            if self.project_id and self.api_key:\n+                address = (\"http://airbrake.io/api/v3/projects/%s/notices\"\n+                           % self.project_id)\n+                if self.use_ssl:\n+                    api_endpoint = urlparse.urlparse(address)\n+                    self._api_url = api_endpoint._replace(\n+                        scheme=\"https\").geturl()\n+                else:\n+                    self._api_url = address\n+            else:\n+                warnings.warn(\"API Key and Project ID required \"","path":"airbrake/notifier.py","position":131,"original_position":131,"commit_id":"1c04aa217995f4e7e5fea0c223b90a42278d00fa","original_commit_id":"1c04aa217995f4e7e5fea0c223b90a42278d00fa","user":{"login":"samstav","id":2030182,"avatar_url":"https://avatars.githubusercontent.com/u/2030182?","gravatar_id":"89acea45d9c5ee7f36ab3981262bded0","url":"https://api.github.com/users/samstav","html_url":"https://github.com/samstav","followers_url":"https://api.github.com/users/samstav/followers","following_url":"https://api.github.com/users/samstav/following{/other_user}","gists_url":"https://api.github.com/users/samstav/gists{/gist_id}","starred_url":"https://api.github.com/users/samstav/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/samstav/subscriptions","organizations_url":"https://api.github.com/users/samstav/orgs","repos_url":"https://api.github.com/users/samstav/repos","events_url":"https://api.github.com/users/samstav/events{/privacy}","received_events_url":"https://api.github.com/users/samstav/received_events","type":"User","site_admin":false},"body":"I agree about the Exception. For some reason I was hesitant to implement it that way. Not sure why...\r\n\r\nShould the exception be thrown as soon as you try to instantiate the Handler (which I think would be valid, since the url cannot even be built.) I think some would argue that it should be lazy, and wait to throw an Exception once the first attempt to call `notify()` is made. ","created_at":"2014-07-03T12:08:01Z","updated_at":"2014-07-03T12:08:01Z","html_url":"https://github.com/airbrake/airbrake-python/pull/8#discussion_r14509947","pull_request_url":"https://api.github.com/repos/airbrake/airbrake-python/pulls/8","_links":{"self":{"href":"https://api.github.com/repos/airbrake/airbrake-python/pulls/comments/14509947"},"html":{"href":"https://github.com/airbrake/airbrake-python/pull/8#discussion_r14509947"},"pull_request":{"href":"https://api.github.com/repos/airbrake/airbrake-python/pulls/8"}}},"pull_request":{"url":"https://api.github.com/repos/airbrake/airbrake-python/pulls/8","id":17926464,"html_url":"https://github.com/airbrake/airbrake-python/pull/8","diff_url":"https://github.com/airbrake/airbrake-python/pull/8.diff","patch_url":"https://github.com/airbrake/airbrake-python/pull/8.patch","issue_url":"https://api.github.com/repos/airbrake/airbrake-python/issues/8","number":8,"state":"open","title":"V1.1.0 updates","user":{"login":"samstav","id":2030182,"avatar_url":"https://avatars.githubusercontent.com/u/2030182?","gravatar_id":"89acea45d9c5ee7f36ab3981262bded0","url":"https://api.github.com/users/samstav","html_url":"https://github.com/samstav","followers_url":"https://api.github.com/users/samstav/followers","following_url":"https://api.github.com/users/samstav/following{/other_user}","gists_url":"https://api.github.com/users/samstav/gists{/gist_id}","starred_url":"https://api.github.com/users/samstav/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/samstav/subscriptions","organizations_url":"https://api.github.com/users/samstav/orgs","repos_url":"https://api.github.com/users/samstav/repos","events_url":"https://api.github.com/users/samstav/events{/privacy}","received_events_url":"https://api.github.com/users/samstav/received_events","type":"User","site_admin":false},"body":"Some long needed updates. Improves usability and leverages more of the datapoints available through the airbrake error reporting API. Includes a helper for fetching a logger object, pre-configured with an AirbrakeHandler, and many other improvements.\r\n\r\nUpdated [the README](https://github.com/samstav/airbrake-python/blob/v1.1.0/README.md) to reflect the simplified interface.","created_at":"2014-07-03T05:30:05Z","updated_at":"2014-07-03T12:08:01Z","closed_at":null,"merged_at":null,"merge_commit_sha":"2f1a4ee4c187ec1f0a93ea9e0519d2a0fb8f6704","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/airbrake/airbrake-python/pulls/8/commits","review_comments_url":"https://api.github.com/repos/airbrake/airbrake-python/pulls/8/comments","review_comment_url":"https://api.github.com/repos/airbrake/airbrake-python/pulls/comments/{number}","comments_url":"https://api.github.com/repos/airbrake/airbrake-python/issues/8/comments","statuses_url":"https://api.github.com/repos/airbrake/airbrake-python/statuses/1c04aa217995f4e7e5fea0c223b90a42278d00fa","head":{"label":"samstav:v1.1.0","ref":"v1.1.0","sha":"1c04aa217995f4e7e5fea0c223b90a42278d00fa","user":{"login":"samstav","id":2030182,"avatar_url":"https://avatars.githubusercontent.com/u/2030182?","gravatar_id":"89acea45d9c5ee7f36ab3981262bded0","url":"https://api.github.com/users/samstav","html_url":"https://github.com/samstav","followers_url":"https://api.github.com/users/samstav/followers","following_url":"https://api.github.com/users/samstav/following{/other_user}","gists_url":"https://api.github.com/users/samstav/gists{/gist_id}","starred_url":"https://api.github.com/users/samstav/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/samstav/subscriptions","organizations_url":"https://api.github.com/users/samstav/orgs","repos_url":"https://api.github.com/users/samstav/repos","events_url":"https://api.github.com/users/samstav/events{/privacy}","received_events_url":"https://api.github.com/users/samstav/received_events","type":"User","site_admin":false},"repo":{"id":16961525,"name":"airbrake-python","full_name":"samstav/airbrake-python","owner":{"login":"samstav","id":2030182,"avatar_url":"https://avatars.githubusercontent.com/u/2030182?","gravatar_id":"89acea45d9c5ee7f36ab3981262bded0","url":"https://api.github.com/users/samstav","html_url":"https://github.com/samstav","followers_url":"https://api.github.com/users/samstav/followers","following_url":"https://api.github.com/users/samstav/following{/other_user}","gists_url":"https://api.github.com/users/samstav/gists{/gist_id}","starred_url":"https://api.github.com/users/samstav/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/samstav/subscriptions","organizations_url":"https://api.github.com/users/samstav/orgs","repos_url":"https://api.github.com/users/samstav/repos","events_url":"https://api.github.com/users/samstav/events{/privacy}","received_events_url":"https://api.github.com/users/samstav/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/samstav/airbrake-python","description":"Airbrake Python","fork":true,"url":"https://api.github.com/repos/samstav/airbrake-python","forks_url":"https://api.github.com/repos/samstav/airbrake-python/forks","keys_url":"https://api.github.com/repos/samstav/airbrake-python/keys{/key_id}","collaborators_url":"https://api.github.com/repos/samstav/airbrake-python/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/samstav/airbrake-python/teams","hooks_url":"https://api.github.com/repos/samstav/airbrake-python/hooks","issue_events_url":"https://api.github.com/repos/samstav/airbrake-python/issues/events{/number}","events_url":"https://api.github.com/repos/samstav/airbrake-python/events","assignees_url":"https://api.github.com/repos/samstav/airbrake-python/assignees{/user}","branches_url":"https://api.github.com/repos/samstav/airbrake-python/branches{/branch}","tags_url":"https://api.github.com/repos/samstav/airbrake-python/tags","blobs_url":"https://api.github.com/repos/samstav/airbrake-python/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/samstav/airbrake-python/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/samstav/airbrake-python/git/refs{/sha}","trees_url":"https://api.github.com/repos/samstav/airbrake-python/git/trees{/sha}","statuses_url":"https://api.github.com/repos/samstav/airbrake-python/statuses/{sha}","languages_url":"https://api.github.com/repos/samstav/airbrake-python/languages","stargazers_url":"https://api.github.com/repos/samstav/airbrake-python/stargazers","contributors_url":"https://api.github.com/repos/samstav/airbrake-python/contributors","subscribers_url":"https://api.github.com/repos/samstav/airbrake-python/subscribers","subscription_url":"https://api.github.com/repos/samstav/airbrake-python/subscription","commits_url":"https://api.github.com/repos/samstav/airbrake-python/commits{/sha}","git_commits_url":"https://api.github.com/repos/samstav/airbrake-python/git/commits{/sha}","comments_url":"https://api.github.com/repos/samstav/airbrake-python/comments{/number}","issue_comment_url":"https://api.github.com/repos/samstav/airbrake-python/issues/comments/{number}","contents_url":"https://api.github.com/repos/samstav/airbrake-python/contents/{+path}","compare_url":"https://api.github.com/repos/samstav/airbrake-python/compare/{base}...{head}","merges_url":"https://api.github.com/repos/samstav/airbrake-python/merges","archive_url":"https://api.github.com/repos/samstav/airbrake-python/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/samstav/airbrake-python/downloads","issues_url":"https://api.github.com/repos/samstav/airbrake-python/issues{/number}","pulls_url":"https://api.github.com/repos/samstav/airbrake-python/pulls{/number}","milestones_url":"https://api.github.com/repos/samstav/airbrake-python/milestones{/number}","notifications_url":"https://api.github.com/repos/samstav/airbrake-python/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/samstav/airbrake-python/labels{/name}","releases_url":"https://api.github.com/repos/samstav/airbrake-python/releases{/id}","created_at":"2014-02-18T19:51:47Z","updated_at":"2014-07-03T06:28:14Z","pushed_at":"2014-07-03T06:24:46Z","git_url":"git://github.com/samstav/airbrake-python.git","ssh_url":"git@github.com:samstav/airbrake-python.git","clone_url":"https://github.com/samstav/airbrake-python.git","svn_url":"https://github.com/samstav/airbrake-python","homepage":"","size":244,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_downloads":true,"has_wiki":true,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"airbrake:master","ref":"master","sha":"03cfbcc4d07f03b1027ffea54dd6e23d4c1fea8d","user":{"login":"airbrake","id":1015434,"avatar_url":"https://avatars.githubusercontent.com/u/1015434?","gravatar_id":"9b706b7832bea4e387a9956531c12a7f","url":"https://api.github.com/users/airbrake","html_url":"https://github.com/airbrake","followers_url":"https://api.github.com/users/airbrake/followers","following_url":"https://api.github.com/users/airbrake/following{/other_user}","gists_url":"https://api.github.com/users/airbrake/gists{/gist_id}","starred_url":"https://api.github.com/users/airbrake/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/airbrake/subscriptions","organizations_url":"https://api.github.com/users/airbrake/orgs","repos_url":"https://api.github.com/users/airbrake/repos","events_url":"https://api.github.com/users/airbrake/events{/privacy}","received_events_url":"https://api.github.com/users/airbrake/received_events","type":"Organization","site_admin":false},"repo":{"id":16956940,"name":"airbrake-python","full_name":"airbrake/airbrake-python","owner":{"login":"airbrake","id":1015434,"avatar_url":"https://avatars.githubusercontent.com/u/1015434?","gravatar_id":"9b706b7832bea4e387a9956531c12a7f","url":"https://api.github.com/users/airbrake","html_url":"https://github.com/airbrake","followers_url":"https://api.github.com/users/airbrake/followers","following_url":"https://api.github.com/users/airbrake/following{/other_user}","gists_url":"https://api.github.com/users/airbrake/gists{/gist_id}","starred_url":"https://api.github.com/users/airbrake/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/airbrake/subscriptions","organizations_url":"https://api.github.com/users/airbrake/orgs","repos_url":"https://api.github.com/users/airbrake/repos","events_url":"https://api.github.com/users/airbrake/events{/privacy}","received_events_url":"https://api.github.com/users/airbrake/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/airbrake/airbrake-python","description":"Airbrake Python","fork":false,"url":"https://api.github.com/repos/airbrake/airbrake-python","forks_url":"https://api.github.com/repos/airbrake/airbrake-python/forks","keys_url":"https://api.github.com/repos/airbrake/airbrake-python/keys{/key_id}","collaborators_url":"https://api.github.com/repos/airbrake/airbrake-python/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/airbrake/airbrake-python/teams","hooks_url":"https://api.github.com/repos/airbrake/airbrake-python/hooks","issue_events_url":"https://api.github.com/repos/airbrake/airbrake-python/issues/events{/number}","events_url":"https://api.github.com/repos/airbrake/airbrake-python/events","assignees_url":"https://api.github.com/repos/airbrake/airbrake-python/assignees{/user}","branches_url":"https://api.github.com/repos/airbrake/airbrake-python/branches{/branch}","tags_url":"https://api.github.com/repos/airbrake/airbrake-python/tags","blobs_url":"https://api.github.com/repos/airbrake/airbrake-python/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/airbrake/airbrake-python/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/airbrake/airbrake-python/git/refs{/sha}","trees_url":"https://api.github.com/repos/airbrake/airbrake-python/git/trees{/sha}","statuses_url":"https://api.github.com/repos/airbrake/airbrake-python/statuses/{sha}","languages_url":"https://api.github.com/repos/airbrake/airbrake-python/languages","stargazers_url":"https://api.github.com/repos/airbrake/airbrake-python/stargazers","contributors_url":"https://api.github.com/repos/airbrake/airbrake-python/contributors","subscribers_url":"https://api.github.com/repos/airbrake/airbrake-python/subscribers","subscription_url":"https://api.github.com/repos/airbrake/airbrake-python/subscription","commits_url":"https://api.github.com/repos/airbrake/airbrake-python/commits{/sha}","git_commits_url":"https://api.github.com/repos/airbrake/airbrake-python/git/commits{/sha}","comments_url":"https://api.github.com/repos/airbrake/airbrake-python/comments{/number}","issue_comment_url":"https://api.github.com/repos/airbrake/airbrake-python/issues/comments/{number}","contents_url":"https://api.github.com/repos/airbrake/airbrake-python/contents/{+path}","compare_url":"https://api.github.com/repos/airbrake/airbrake-python/compare/{base}...{head}","merges_url":"https://api.github.com/repos/airbrake/airbrake-python/merges","archive_url":"https://api.github.com/repos/airbrake/airbrake-python/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/airbrake/airbrake-python/downloads","issues_url":"https://api.github.com/repos/airbrake/airbrake-python/issues{/number}","pulls_url":"https://api.github.com/repos/airbrake/airbrake-python/pulls{/number}","milestones_url":"https://api.github.com/repos/airbrake/airbrake-python/milestones{/number}","notifications_url":"https://api.github.com/repos/airbrake/airbrake-python/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/airbrake/airbrake-python/labels{/name}","releases_url":"https://api.github.com/repos/airbrake/airbrake-python/releases{/id}","created_at":"2014-02-18T17:17:59Z","updated_at":"2014-06-19T18:24:20Z","pushed_at":"2014-05-07T14:07:10Z","git_url":"git://github.com/airbrake/airbrake-python.git","ssh_url":"git@github.com:airbrake/airbrake-python.git","clone_url":"https://github.com/airbrake/airbrake-python.git","svn_url":"https://github.com/airbrake/airbrake-python","homepage":"","size":280,"stargazers_count":4,"watchers_count":4,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"forks_count":5,"mirror_url":null,"open_issues_count":1,"forks":5,"open_issues":1,"watchers":4,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/airbrake/airbrake-python/pulls/8"},"html":{"href":"https://github.com/airbrake/airbrake-python/pull/8"},"issue":{"href":"https://api.github.com/repos/airbrake/airbrake-python/issues/8"},"comments":{"href":"https://api.github.com/repos/airbrake/airbrake-python/issues/8/comments"},"review_comments":{"href":"https://api.github.com/repos/airbrake/airbrake-python/pulls/8/comments"},"review_comment":{"href":"https://api.github.com/repos/airbrake/airbrake-python/pulls/comments/{number}"},"commits":{"href":"https://api.github.com/repos/airbrake/airbrake-python/pulls/8/commits"},"statuses":{"href":"https://api.github.com/repos/airbrake/airbrake-python/statuses/1c04aa217995f4e7e5fea0c223b90a42278d00fa"}}}}