{"action":"created","comment":{"url":"https://api.github.com/repos/managedbyq/mbq.env/pulls/comments/244042906","pull_request_review_id":187953804,"id":244042906,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDI0NDA0MjkwNg==","diff_hunk":"@@ -7,30 +9,73 @@ class EnvException(Exception):\n     pass\n \n \n+class Environment(Enum):\n+    \"\"\"\n+    A simple Enum to provide consistency in how we detect and\n+    represent the environment in which a service is running.\n+    \"\"\"\n+\n+    PRODUCTION = ('prd', 'Production')\n+    DEVELOPMENT = ('dev', 'Development')\n+    LOCAL = ('lcl', 'Local')\n+\n+    def __init__(self, short, long):\n+        self.short = short\n+        self.long = long\n+        self._searchable = {short.lower(), long.lower()}\n+\n+    @classmethod\n+    def from_value(cls, value):\n+        \"\"\"\n+        Find an Environment using a single `str`.\n+\n+        Using a typical Enum, finding a member by value would be as\n+        simple as MyEnum('the-value') but since Environment members\n+        are stored as tuples and we want to look up using `str`s,\n+        `from_value` can used to make that lookup in a case-\n+        insensitive way.\n+\n+        >>> assert Environment.from_value('prd') is Environment.from_value('PRODUCTION')\n+        \"\"\"\n+\n+        for member in list(cls):\n+            if value.lower() in member._searchable:\n+                return member\n+\n+        raise ValueError(f\"'{value}' is not a valid {cls.__name__}\")\n+\n+\n class Env:\n     def get(self, key, default=NOT_PROVIDED, required=True, coerce=NOT_PROVIDED):\n         try:\n             val = os.environ[key].strip()\n-        except KeyError:\n+        except KeyError as e:\n             if default is not NOT_PROVIDED:\n                 return default\n \n             if not required:\n                 return None\n \n-            raise EnvException('Missing key \"{}\"'.format(key))\n+            raise EnvException('Missing key \"{}\"'.format(key)) from e\n \n         if coerce is not NOT_PROVIDED:\n             val = coerce(val)\n \n         return val\n \n+    def get_environment(self, key, default=NOT_PROVIDED, required=True):\n+        try:\n+            return self.get(key, default=default, required=required, coerce=Environment.from_value)\n+        except ValueError as e:\n+            if 'is not a valid Environment' in str(e):","path":"mbq/env/__init__.py","position":null,"original_position":71,"commit_id":"2c1e891862bd7de146401b79700adbd253616920","original_commit_id":"6be91278375be9e5bcfde4862494aa42fce6c672","user":{"login":"mattbriancon","id":152974,"node_id":"MDQ6VXNlcjE1Mjk3NA==","avatar_url":"https://avatars0.githubusercontent.com/u/152974?v=4","gravatar_id":"","url":"https://api.github.com/users/mattbriancon","html_url":"https://github.com/mattbriancon","followers_url":"https://api.github.com/users/mattbriancon/followers","following_url":"https://api.github.com/users/mattbriancon/following{/other_user}","gists_url":"https://api.github.com/users/mattbriancon/gists{/gist_id}","starred_url":"https://api.github.com/users/mattbriancon/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mattbriancon/subscriptions","organizations_url":"https://api.github.com/users/mattbriancon/orgs","repos_url":"https://api.github.com/users/mattbriancon/repos","events_url":"https://api.github.com/users/mattbriancon/events{/privacy}","received_events_url":"https://api.github.com/users/mattbriancon/received_events","type":"User","site_admin":false},"body":"Changed it to let the ValueError through. I don't feel strongly about it and the traceback should make it fairly straightforward to figure out.","created_at":"2018-12-26T20:04:54Z","updated_at":"2018-12-26T20:04:55Z","html_url":"https://github.com/managedbyq/mbq.env/pull/7#discussion_r244042906","pull_request_url":"https://api.github.com/repos/managedbyq/mbq.env/pulls/7","author_association":"MEMBER","_links":{"self":{"href":"https://api.github.com/repos/managedbyq/mbq.env/pulls/comments/244042906"},"html":{"href":"https://github.com/managedbyq/mbq.env/pull/7#discussion_r244042906"},"pull_request":{"href":"https://api.github.com/repos/managedbyq/mbq.env/pulls/7"}},"in_reply_to_id":243855749},"pull_request":{"url":"https://api.github.com/repos/managedbyq/mbq.env/pulls/7","id":240724769,"node_id":"MDExOlB1bGxSZXF1ZXN0MjQwNzI0NzY5","html_url":"https://github.com/managedbyq/mbq.env/pull/7","diff_url":"https://github.com/managedbyq/mbq.env/pull/7.diff","patch_url":"https://github.com/managedbyq/mbq.env/pull/7.patch","issue_url":"https://api.github.com/repos/managedbyq/mbq.env/issues/7","number":7,"state":"open","locked":false,"title":"Environment Enum","user":{"login":"mattbriancon","id":152974,"node_id":"MDQ6VXNlcjE1Mjk3NA==","avatar_url":"https://avatars0.githubusercontent.com/u/152974?v=4","gravatar_id":"","url":"https://api.github.com/users/mattbriancon","html_url":"https://github.com/mattbriancon","followers_url":"https://api.github.com/users/mattbriancon/followers","following_url":"https://api.github.com/users/mattbriancon/following{/other_user}","gists_url":"https://api.github.com/users/mattbriancon/gists{/gist_id}","starred_url":"https://api.github.com/users/mattbriancon/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mattbriancon/subscriptions","organizations_url":"https://api.github.com/users/mattbriancon/orgs","repos_url":"https://api.github.com/users/mattbriancon/repos","events_url":"https://api.github.com/users/mattbriancon/events{/privacy}","received_events_url":"https://api.github.com/users/mattbriancon/received_events","type":"User","site_admin":false},"body":"I needed a consistent way to get the short and long environment names in mbq.pubsub and I figured that'd be useful everywhere. This solution was the first thing that came to mind; very open to feedback.\r\n\r\nAnother \"feature\" we might consider is the \"is deployed\" test that we use in a lot of places. Something like \r\n\r\n```python\r\nfrom mbq import env\r\ncurrent_env = env.get_environment('ENV_NAME')\r\nif current_env.is_deployed:\r\n    # only executed in dev and prd\r\n```","created_at":"2018-12-24T06:03:29Z","updated_at":"2018-12-26T20:04:55Z","closed_at":null,"merged_at":null,"merge_commit_sha":"6fab5c81039940e3ea196bd18e061fc411f977ff","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/managedbyq/mbq.env/pulls/7/commits","review_comments_url":"https://api.github.com/repos/managedbyq/mbq.env/pulls/7/comments","review_comment_url":"https://api.github.com/repos/managedbyq/mbq.env/pulls/comments{/number}","comments_url":"https://api.github.com/repos/managedbyq/mbq.env/issues/7/comments","statuses_url":"https://api.github.com/repos/managedbyq/mbq.env/statuses/2c1e891862bd7de146401b79700adbd253616920","head":{"label":"managedbyq:mb/environment-enum","ref":"mb/environment-enum","sha":"2c1e891862bd7de146401b79700adbd253616920","user":{"login":"managedbyq","id":11465985,"node_id":"MDEyOk9yZ2FuaXphdGlvbjExNDY1OTg1","avatar_url":"https://avatars1.githubusercontent.com/u/11465985?v=4","gravatar_id":"","url":"https://api.github.com/users/managedbyq","html_url":"https://github.com/managedbyq","followers_url":"https://api.github.com/users/managedbyq/followers","following_url":"https://api.github.com/users/managedbyq/following{/other_user}","gists_url":"https://api.github.com/users/managedbyq/gists{/gist_id}","starred_url":"https://api.github.com/users/managedbyq/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/managedbyq/subscriptions","organizations_url":"https://api.github.com/users/managedbyq/orgs","repos_url":"https://api.github.com/users/managedbyq/repos","events_url":"https://api.github.com/users/managedbyq/events{/privacy}","received_events_url":"https://api.github.com/users/managedbyq/received_events","type":"Organization","site_admin":false},"repo":{"id":92563813,"node_id":"MDEwOlJlcG9zaXRvcnk5MjU2MzgxMw==","name":"mbq.env","full_name":"managedbyq/mbq.env","private":false,"owner":{"login":"managedbyq","id":11465985,"node_id":"MDEyOk9yZ2FuaXphdGlvbjExNDY1OTg1","avatar_url":"https://avatars1.githubusercontent.com/u/11465985?v=4","gravatar_id":"","url":"https://api.github.com/users/managedbyq","html_url":"https://github.com/managedbyq","followers_url":"https://api.github.com/users/managedbyq/followers","following_url":"https://api.github.com/users/managedbyq/following{/other_user}","gists_url":"https://api.github.com/users/managedbyq/gists{/gist_id}","starred_url":"https://api.github.com/users/managedbyq/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/managedbyq/subscriptions","organizations_url":"https://api.github.com/users/managedbyq/orgs","repos_url":"https://api.github.com/users/managedbyq/repos","events_url":"https://api.github.com/users/managedbyq/events{/privacy}","received_events_url":"https://api.github.com/users/managedbyq/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/managedbyq/mbq.env","description":"mbq.env: protect the environment","fork":false,"url":"https://api.github.com/repos/managedbyq/mbq.env","forks_url":"https://api.github.com/repos/managedbyq/mbq.env/forks","keys_url":"https://api.github.com/repos/managedbyq/mbq.env/keys{/key_id}","collaborators_url":"https://api.github.com/repos/managedbyq/mbq.env/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/managedbyq/mbq.env/teams","hooks_url":"https://api.github.com/repos/managedbyq/mbq.env/hooks","issue_events_url":"https://api.github.com/repos/managedbyq/mbq.env/issues/events{/number}","events_url":"https://api.github.com/repos/managedbyq/mbq.env/events","assignees_url":"https://api.github.com/repos/managedbyq/mbq.env/assignees{/user}","branches_url":"https://api.github.com/repos/managedbyq/mbq.env/branches{/branch}","tags_url":"https://api.github.com/repos/managedbyq/mbq.env/tags","blobs_url":"https://api.github.com/repos/managedbyq/mbq.env/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/managedbyq/mbq.env/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/managedbyq/mbq.env/git/refs{/sha}","trees_url":"https://api.github.com/repos/managedbyq/mbq.env/git/trees{/sha}","statuses_url":"https://api.github.com/repos/managedbyq/mbq.env/statuses/{sha}","languages_url":"https://api.github.com/repos/managedbyq/mbq.env/languages","stargazers_url":"https://api.github.com/repos/managedbyq/mbq.env/stargazers","contributors_url":"https://api.github.com/repos/managedbyq/mbq.env/contributors","subscribers_url":"https://api.github.com/repos/managedbyq/mbq.env/subscribers","subscription_url":"https://api.github.com/repos/managedbyq/mbq.env/subscription","commits_url":"https://api.github.com/repos/managedbyq/mbq.env/commits{/sha}","git_commits_url":"https://api.github.com/repos/managedbyq/mbq.env/git/commits{/sha}","comments_url":"https://api.github.com/repos/managedbyq/mbq.env/comments{/number}","issue_comment_url":"https://api.github.com/repos/managedbyq/mbq.env/issues/comments{/number}","contents_url":"https://api.github.com/repos/managedbyq/mbq.env/contents/{+path}","compare_url":"https://api.github.com/repos/managedbyq/mbq.env/compare/{base}...{head}","merges_url":"https://api.github.com/repos/managedbyq/mbq.env/merges","archive_url":"https://api.github.com/repos/managedbyq/mbq.env/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/managedbyq/mbq.env/downloads","issues_url":"https://api.github.com/repos/managedbyq/mbq.env/issues{/number}","pulls_url":"https://api.github.com/repos/managedbyq/mbq.env/pulls{/number}","milestones_url":"https://api.github.com/repos/managedbyq/mbq.env/milestones{/number}","notifications_url":"https://api.github.com/repos/managedbyq/mbq.env/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/managedbyq/mbq.env/labels{/name}","releases_url":"https://api.github.com/repos/managedbyq/mbq.env/releases{/id}","deployments_url":"https://api.github.com/repos/managedbyq/mbq.env/deployments","created_at":"2017-05-27T02:20:50Z","updated_at":"2018-12-19T17:09:54Z","pushed_at":"2018-12-26T19:59:51Z","git_url":"git://github.com/managedbyq/mbq.env.git","ssh_url":"git@github.com:managedbyq/mbq.env.git","clone_url":"https://github.com/managedbyq/mbq.env.git","svn_url":"https://github.com/managedbyq/mbq.env","homepage":"https://pypi.org/project/mbq.env","size":21,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":true,"has_projects":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":1,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0","node_id":"MDc6TGljZW5zZTI="},"forks":0,"open_issues":1,"watchers":0,"default_branch":"master"}},"base":{"label":"managedbyq:master","ref":"master","sha":"618e9d50d5f07eb8db3fab1249254c60393c9838","user":{"login":"managedbyq","id":11465985,"node_id":"MDEyOk9yZ2FuaXphdGlvbjExNDY1OTg1","avatar_url":"https://avatars1.githubusercontent.com/u/11465985?v=4","gravatar_id":"","url":"https://api.github.com/users/managedbyq","html_url":"https://github.com/managedbyq","followers_url":"https://api.github.com/users/managedbyq/followers","following_url":"https://api.github.com/users/managedbyq/following{/other_user}","gists_url":"https://api.github.com/users/managedbyq/gists{/gist_id}","starred_url":"https://api.github.com/users/managedbyq/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/managedbyq/subscriptions","organizations_url":"https://api.github.com/users/managedbyq/orgs","repos_url":"https://api.github.com/users/managedbyq/repos","events_url":"https://api.github.com/users/managedbyq/events{/privacy}","received_events_url":"https://api.github.com/users/managedbyq/received_events","type":"Organization","site_admin":false},"repo":{"id":92563813,"node_id":"MDEwOlJlcG9zaXRvcnk5MjU2MzgxMw==","name":"mbq.env","full_name":"managedbyq/mbq.env","private":false,"owner":{"login":"managedbyq","id":11465985,"node_id":"MDEyOk9yZ2FuaXphdGlvbjExNDY1OTg1","avatar_url":"https://avatars1.githubusercontent.com/u/11465985?v=4","gravatar_id":"","url":"https://api.github.com/users/managedbyq","html_url":"https://github.com/managedbyq","followers_url":"https://api.github.com/users/managedbyq/followers","following_url":"https://api.github.com/users/managedbyq/following{/other_user}","gists_url":"https://api.github.com/users/managedbyq/gists{/gist_id}","starred_url":"https://api.github.com/users/managedbyq/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/managedbyq/subscriptions","organizations_url":"https://api.github.com/users/managedbyq/orgs","repos_url":"https://api.github.com/users/managedbyq/repos","events_url":"https://api.github.com/users/managedbyq/events{/privacy}","received_events_url":"https://api.github.com/users/managedbyq/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/managedbyq/mbq.env","description":"mbq.env: protect the environment","fork":false,"url":"https://api.github.com/repos/managedbyq/mbq.env","forks_url":"https://api.github.com/repos/managedbyq/mbq.env/forks","keys_url":"https://api.github.com/repos/managedbyq/mbq.env/keys{/key_id}","collaborators_url":"https://api.github.com/repos/managedbyq/mbq.env/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/managedbyq/mbq.env/teams","hooks_url":"https://api.github.com/repos/managedbyq/mbq.env/hooks","issue_events_url":"https://api.github.com/repos/managedbyq/mbq.env/issues/events{/number}","events_url":"https://api.github.com/repos/managedbyq/mbq.env/events","assignees_url":"https://api.github.com/repos/managedbyq/mbq.env/assignees{/user}","branches_url":"https://api.github.com/repos/managedbyq/mbq.env/branches{/branch}","tags_url":"https://api.github.com/repos/managedbyq/mbq.env/tags","blobs_url":"https://api.github.com/repos/managedbyq/mbq.env/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/managedbyq/mbq.env/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/managedbyq/mbq.env/git/refs{/sha}","trees_url":"https://api.github.com/repos/managedbyq/mbq.env/git/trees{/sha}","statuses_url":"https://api.github.com/repos/managedbyq/mbq.env/statuses/{sha}","languages_url":"https://api.github.com/repos/managedbyq/mbq.env/languages","stargazers_url":"https://api.github.com/repos/managedbyq/mbq.env/stargazers","contributors_url":"https://api.github.com/repos/managedbyq/mbq.env/contributors","subscribers_url":"https://api.github.com/repos/managedbyq/mbq.env/subscribers","subscription_url":"https://api.github.com/repos/managedbyq/mbq.env/subscription","commits_url":"https://api.github.com/repos/managedbyq/mbq.env/commits{/sha}","git_commits_url":"https://api.github.com/repos/managedbyq/mbq.env/git/commits{/sha}","comments_url":"https://api.github.com/repos/managedbyq/mbq.env/comments{/number}","issue_comment_url":"https://api.github.com/repos/managedbyq/mbq.env/issues/comments{/number}","contents_url":"https://api.github.com/repos/managedbyq/mbq.env/contents/{+path}","compare_url":"https://api.github.com/repos/managedbyq/mbq.env/compare/{base}...{head}","merges_url":"https://api.github.com/repos/managedbyq/mbq.env/merges","archive_url":"https://api.github.com/repos/managedbyq/mbq.env/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/managedbyq/mbq.env/downloads","issues_url":"https://api.github.com/repos/managedbyq/mbq.env/issues{/number}","pulls_url":"https://api.github.com/repos/managedbyq/mbq.env/pulls{/number}","milestones_url":"https://api.github.com/repos/managedbyq/mbq.env/milestones{/number}","notifications_url":"https://api.github.com/repos/managedbyq/mbq.env/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/managedbyq/mbq.env/labels{/name}","releases_url":"https://api.github.com/repos/managedbyq/mbq.env/releases{/id}","deployments_url":"https://api.github.com/repos/managedbyq/mbq.env/deployments","created_at":"2017-05-27T02:20:50Z","updated_at":"2018-12-19T17:09:54Z","pushed_at":"2018-12-26T19:59:51Z","git_url":"git://github.com/managedbyq/mbq.env.git","ssh_url":"git@github.com:managedbyq/mbq.env.git","clone_url":"https://github.com/managedbyq/mbq.env.git","svn_url":"https://github.com/managedbyq/mbq.env","homepage":"https://pypi.org/project/mbq.env","size":21,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":true,"has_projects":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":1,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0","node_id":"MDc6TGljZW5zZTI="},"forks":0,"open_issues":1,"watchers":0,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/managedbyq/mbq.env/pulls/7"},"html":{"href":"https://github.com/managedbyq/mbq.env/pull/7"},"issue":{"href":"https://api.github.com/repos/managedbyq/mbq.env/issues/7"},"comments":{"href":"https://api.github.com/repos/managedbyq/mbq.env/issues/7/comments"},"review_comments":{"href":"https://api.github.com/repos/managedbyq/mbq.env/pulls/7/comments"},"review_comment":{"href":"https://api.github.com/repos/managedbyq/mbq.env/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/managedbyq/mbq.env/pulls/7/commits"},"statuses":{"href":"https://api.github.com/repos/managedbyq/mbq.env/statuses/2c1e891862bd7de146401b79700adbd253616920"}},"author_association":"MEMBER"}}
{"actor":{"display_login":"mattbriancon"}}