{"action":"created","comment":{"url":"https://api.github.com/repos/buzzfeed/phonon/pulls/comments/59319384","id":59319384,"diff_hunk":"@@ -0,0 +1,35 @@\n+import phonon.fields\n+import phonon.exceptions\n+\n+\n+class MetaModel(type):\n+    def __new__(cls, name, parents, dct):\n+        cls._fields = {}\n+        for key, val in dct.items():\n+            if isinstance(val, phonon.fields.Field):\n+                cls._fields[key] = val\n+\n+        return super(MetaModel, cls).__new__(cls, name, parents, dct)\n+\n+\n+class Model(object):\n+    __metaclass__ = MetaModel\n+\n+    def __init__(self, *args, **kwargs):\n+        for key, field in self.__class__._fields.items():\n+            try:\n+                if hasattr(field, 'dtype'):\n+                    assert isinstance(kwargs[key], field.dtype)\n+            except KeyError, e:\n+                raise phonon.exceptions.PhononError(\"{} is a required field\".format(key))\n+            setattr(self, key, kwargs[key])","path":"phonon/model.py","position":25,"original_position":25,"commit_id":"be0c8c4c4cc82fed56e4f3124aec89d9d07a40b7","original_commit_id":"be0c8c4c4cc82fed56e4f3124aec89d9d07a40b7","user":{"login":"akellehe","id":227095,"avatar_url":"https://avatars.githubusercontent.com/u/227095?v=3","gravatar_id":"","url":"https://api.github.com/users/akellehe","html_url":"https://github.com/akellehe","followers_url":"https://api.github.com/users/akellehe/followers","following_url":"https://api.github.com/users/akellehe/following{/other_user}","gists_url":"https://api.github.com/users/akellehe/gists{/gist_id}","starred_url":"https://api.github.com/users/akellehe/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/akellehe/subscriptions","organizations_url":"https://api.github.com/users/akellehe/orgs","repos_url":"https://api.github.com/users/akellehe/repos","events_url":"https://api.github.com/users/akellehe/events{/privacy}","received_events_url":"https://api.github.com/users/akellehe/received_events","type":"User","site_admin":false},"body":"The user must pass the fields they define on each model as the model is initialized via kwargs. They're then set on the _instance_ as attributes.","created_at":"2016-04-12T04:28:26Z","updated_at":"2016-04-12T04:28:26Z","html_url":"https://github.com/buzzfeed/phonon/pull/50#discussion_r59319384","pull_request_url":"https://api.github.com/repos/buzzfeed/phonon/pulls/50","_links":{"self":{"href":"https://api.github.com/repos/buzzfeed/phonon/pulls/comments/59319384"},"html":{"href":"https://github.com/buzzfeed/phonon/pull/50#discussion_r59319384"},"pull_request":{"href":"https://api.github.com/repos/buzzfeed/phonon/pulls/50"}}},"pull_request":{"url":"https://api.github.com/repos/buzzfeed/phonon/pulls/50","id":66099074,"html_url":"https://github.com/buzzfeed/phonon/pull/50","diff_url":"https://github.com/buzzfeed/phonon/pull/50.diff","patch_url":"https://github.com/buzzfeed/phonon/pull/50.patch","issue_url":"https://api.github.com/repos/buzzfeed/phonon/issues/50","number":50,"state":"open","locked":false,"title":"Prototype for models and fields","user":{"login":"akellehe","id":227095,"avatar_url":"https://avatars.githubusercontent.com/u/227095?v=3","gravatar_id":"","url":"https://api.github.com/users/akellehe","html_url":"https://github.com/akellehe","followers_url":"https://api.github.com/users/akellehe/followers","following_url":"https://api.github.com/users/akellehe/following{/other_user}","gists_url":"https://api.github.com/users/akellehe/gists{/gist_id}","starred_url":"https://api.github.com/users/akellehe/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/akellehe/subscriptions","organizations_url":"https://api.github.com/users/akellehe/orgs","repos_url":"https://api.github.com/users/akellehe/repos","events_url":"https://api.github.com/users/akellehe/events{/privacy}","received_events_url":"https://api.github.com/users/akellehe/received_events","type":"User","site_admin":false},"body":"","created_at":"2016-04-12T04:24:59Z","updated_at":"2016-04-12T04:28:26Z","closed_at":null,"merged_at":null,"merge_commit_sha":"dd053daf51ff1244566653284ab344163edd7216","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/buzzfeed/phonon/pulls/50/commits","review_comments_url":"https://api.github.com/repos/buzzfeed/phonon/pulls/50/comments","review_comment_url":"https://api.github.com/repos/buzzfeed/phonon/pulls/comments{/number}","comments_url":"https://api.github.com/repos/buzzfeed/phonon/issues/50/comments","statuses_url":"https://api.github.com/repos/buzzfeed/phonon/statuses/be0c8c4c4cc82fed56e4f3124aec89d9d07a40b7","head":{"label":"buzzfeed:COPS-811-models-and-fields","ref":"COPS-811-models-and-fields","sha":"be0c8c4c4cc82fed56e4f3124aec89d9d07a40b7","user":{"login":"buzzfeed","id":1781305,"avatar_url":"https://avatars.githubusercontent.com/u/1781305?v=3","gravatar_id":"","url":"https://api.github.com/users/buzzfeed","html_url":"https://github.com/buzzfeed","followers_url":"https://api.github.com/users/buzzfeed/followers","following_url":"https://api.github.com/users/buzzfeed/following{/other_user}","gists_url":"https://api.github.com/users/buzzfeed/gists{/gist_id}","starred_url":"https://api.github.com/users/buzzfeed/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/buzzfeed/subscriptions","organizations_url":"https://api.github.com/users/buzzfeed/orgs","repos_url":"https://api.github.com/users/buzzfeed/repos","events_url":"https://api.github.com/users/buzzfeed/events{/privacy}","received_events_url":"https://api.github.com/users/buzzfeed/received_events","type":"Organization","site_admin":false},"repo":{"id":27844200,"name":"phonon","full_name":"buzzfeed/phonon","owner":{"login":"buzzfeed","id":1781305,"avatar_url":"https://avatars.githubusercontent.com/u/1781305?v=3","gravatar_id":"","url":"https://api.github.com/users/buzzfeed","html_url":"https://github.com/buzzfeed","followers_url":"https://api.github.com/users/buzzfeed/followers","following_url":"https://api.github.com/users/buzzfeed/following{/other_user}","gists_url":"https://api.github.com/users/buzzfeed/gists{/gist_id}","starred_url":"https://api.github.com/users/buzzfeed/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/buzzfeed/subscriptions","organizations_url":"https://api.github.com/users/buzzfeed/orgs","repos_url":"https://api.github.com/users/buzzfeed/repos","events_url":"https://api.github.com/users/buzzfeed/events{/privacy}","received_events_url":"https://api.github.com/users/buzzfeed/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/buzzfeed/phonon","description":"Phonon","fork":false,"url":"https://api.github.com/repos/buzzfeed/phonon","forks_url":"https://api.github.com/repos/buzzfeed/phonon/forks","keys_url":"https://api.github.com/repos/buzzfeed/phonon/keys{/key_id}","collaborators_url":"https://api.github.com/repos/buzzfeed/phonon/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/buzzfeed/phonon/teams","hooks_url":"https://api.github.com/repos/buzzfeed/phonon/hooks","issue_events_url":"https://api.github.com/repos/buzzfeed/phonon/issues/events{/number}","events_url":"https://api.github.com/repos/buzzfeed/phonon/events","assignees_url":"https://api.github.com/repos/buzzfeed/phonon/assignees{/user}","branches_url":"https://api.github.com/repos/buzzfeed/phonon/branches{/branch}","tags_url":"https://api.github.com/repos/buzzfeed/phonon/tags","blobs_url":"https://api.github.com/repos/buzzfeed/phonon/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/buzzfeed/phonon/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/buzzfeed/phonon/git/refs{/sha}","trees_url":"https://api.github.com/repos/buzzfeed/phonon/git/trees{/sha}","statuses_url":"https://api.github.com/repos/buzzfeed/phonon/statuses/{sha}","languages_url":"https://api.github.com/repos/buzzfeed/phonon/languages","stargazers_url":"https://api.github.com/repos/buzzfeed/phonon/stargazers","contributors_url":"https://api.github.com/repos/buzzfeed/phonon/contributors","subscribers_url":"https://api.github.com/repos/buzzfeed/phonon/subscribers","subscription_url":"https://api.github.com/repos/buzzfeed/phonon/subscription","commits_url":"https://api.github.com/repos/buzzfeed/phonon/commits{/sha}","git_commits_url":"https://api.github.com/repos/buzzfeed/phonon/git/commits{/sha}","comments_url":"https://api.github.com/repos/buzzfeed/phonon/comments{/number}","issue_comment_url":"https://api.github.com/repos/buzzfeed/phonon/issues/comments{/number}","contents_url":"https://api.github.com/repos/buzzfeed/phonon/contents/{+path}","compare_url":"https://api.github.com/repos/buzzfeed/phonon/compare/{base}...{head}","merges_url":"https://api.github.com/repos/buzzfeed/phonon/merges","archive_url":"https://api.github.com/repos/buzzfeed/phonon/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/buzzfeed/phonon/downloads","issues_url":"https://api.github.com/repos/buzzfeed/phonon/issues{/number}","pulls_url":"https://api.github.com/repos/buzzfeed/phonon/pulls{/number}","milestones_url":"https://api.github.com/repos/buzzfeed/phonon/milestones{/number}","notifications_url":"https://api.github.com/repos/buzzfeed/phonon/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/buzzfeed/phonon/labels{/name}","releases_url":"https://api.github.com/repos/buzzfeed/phonon/releases{/id}","deployments_url":"https://api.github.com/repos/buzzfeed/phonon/deployments","created_at":"2014-12-10T23:08:20Z","updated_at":"2016-02-05T20:05:16Z","pushed_at":"2016-04-12T04:25:00Z","git_url":"git://github.com/buzzfeed/phonon.git","ssh_url":"git@github.com:buzzfeed/phonon.git","clone_url":"https://github.com/buzzfeed/phonon.git","svn_url":"https://github.com/buzzfeed/phonon","homepage":"","size":478,"stargazers_count":2,"watchers_count":2,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":3,"forks":0,"open_issues":3,"watchers":2,"default_branch":"master"}},"base":{"label":"buzzfeed:COPS-805-asyncconn-with-tornado","ref":"COPS-805-asyncconn-with-tornado","sha":"625ec737875883796575830b7259ea8d5588a568","user":{"login":"buzzfeed","id":1781305,"avatar_url":"https://avatars.githubusercontent.com/u/1781305?v=3","gravatar_id":"","url":"https://api.github.com/users/buzzfeed","html_url":"https://github.com/buzzfeed","followers_url":"https://api.github.com/users/buzzfeed/followers","following_url":"https://api.github.com/users/buzzfeed/following{/other_user}","gists_url":"https://api.github.com/users/buzzfeed/gists{/gist_id}","starred_url":"https://api.github.com/users/buzzfeed/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/buzzfeed/subscriptions","organizations_url":"https://api.github.com/users/buzzfeed/orgs","repos_url":"https://api.github.com/users/buzzfeed/repos","events_url":"https://api.github.com/users/buzzfeed/events{/privacy}","received_events_url":"https://api.github.com/users/buzzfeed/received_events","type":"Organization","site_admin":false},"repo":{"id":27844200,"name":"phonon","full_name":"buzzfeed/phonon","owner":{"login":"buzzfeed","id":1781305,"avatar_url":"https://avatars.githubusercontent.com/u/1781305?v=3","gravatar_id":"","url":"https://api.github.com/users/buzzfeed","html_url":"https://github.com/buzzfeed","followers_url":"https://api.github.com/users/buzzfeed/followers","following_url":"https://api.github.com/users/buzzfeed/following{/other_user}","gists_url":"https://api.github.com/users/buzzfeed/gists{/gist_id}","starred_url":"https://api.github.com/users/buzzfeed/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/buzzfeed/subscriptions","organizations_url":"https://api.github.com/users/buzzfeed/orgs","repos_url":"https://api.github.com/users/buzzfeed/repos","events_url":"https://api.github.com/users/buzzfeed/events{/privacy}","received_events_url":"https://api.github.com/users/buzzfeed/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/buzzfeed/phonon","description":"Phonon","fork":false,"url":"https://api.github.com/repos/buzzfeed/phonon","forks_url":"https://api.github.com/repos/buzzfeed/phonon/forks","keys_url":"https://api.github.com/repos/buzzfeed/phonon/keys{/key_id}","collaborators_url":"https://api.github.com/repos/buzzfeed/phonon/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/buzzfeed/phonon/teams","hooks_url":"https://api.github.com/repos/buzzfeed/phonon/hooks","issue_events_url":"https://api.github.com/repos/buzzfeed/phonon/issues/events{/number}","events_url":"https://api.github.com/repos/buzzfeed/phonon/events","assignees_url":"https://api.github.com/repos/buzzfeed/phonon/assignees{/user}","branches_url":"https://api.github.com/repos/buzzfeed/phonon/branches{/branch}","tags_url":"https://api.github.com/repos/buzzfeed/phonon/tags","blobs_url":"https://api.github.com/repos/buzzfeed/phonon/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/buzzfeed/phonon/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/buzzfeed/phonon/git/refs{/sha}","trees_url":"https://api.github.com/repos/buzzfeed/phonon/git/trees{/sha}","statuses_url":"https://api.github.com/repos/buzzfeed/phonon/statuses/{sha}","languages_url":"https://api.github.com/repos/buzzfeed/phonon/languages","stargazers_url":"https://api.github.com/repos/buzzfeed/phonon/stargazers","contributors_url":"https://api.github.com/repos/buzzfeed/phonon/contributors","subscribers_url":"https://api.github.com/repos/buzzfeed/phonon/subscribers","subscription_url":"https://api.github.com/repos/buzzfeed/phonon/subscription","commits_url":"https://api.github.com/repos/buzzfeed/phonon/commits{/sha}","git_commits_url":"https://api.github.com/repos/buzzfeed/phonon/git/commits{/sha}","comments_url":"https://api.github.com/repos/buzzfeed/phonon/comments{/number}","issue_comment_url":"https://api.github.com/repos/buzzfeed/phonon/issues/comments{/number}","contents_url":"https://api.github.com/repos/buzzfeed/phonon/contents/{+path}","compare_url":"https://api.github.com/repos/buzzfeed/phonon/compare/{base}...{head}","merges_url":"https://api.github.com/repos/buzzfeed/phonon/merges","archive_url":"https://api.github.com/repos/buzzfeed/phonon/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/buzzfeed/phonon/downloads","issues_url":"https://api.github.com/repos/buzzfeed/phonon/issues{/number}","pulls_url":"https://api.github.com/repos/buzzfeed/phonon/pulls{/number}","milestones_url":"https://api.github.com/repos/buzzfeed/phonon/milestones{/number}","notifications_url":"https://api.github.com/repos/buzzfeed/phonon/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/buzzfeed/phonon/labels{/name}","releases_url":"https://api.github.com/repos/buzzfeed/phonon/releases{/id}","deployments_url":"https://api.github.com/repos/buzzfeed/phonon/deployments","created_at":"2014-12-10T23:08:20Z","updated_at":"2016-02-05T20:05:16Z","pushed_at":"2016-04-12T04:25:00Z","git_url":"git://github.com/buzzfeed/phonon.git","ssh_url":"git@github.com:buzzfeed/phonon.git","clone_url":"https://github.com/buzzfeed/phonon.git","svn_url":"https://github.com/buzzfeed/phonon","homepage":"","size":478,"stargazers_count":2,"watchers_count":2,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":3,"forks":0,"open_issues":3,"watchers":2,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/buzzfeed/phonon/pulls/50"},"html":{"href":"https://github.com/buzzfeed/phonon/pull/50"},"issue":{"href":"https://api.github.com/repos/buzzfeed/phonon/issues/50"},"comments":{"href":"https://api.github.com/repos/buzzfeed/phonon/issues/50/comments"},"review_comments":{"href":"https://api.github.com/repos/buzzfeed/phonon/pulls/50/comments"},"review_comment":{"href":"https://api.github.com/repos/buzzfeed/phonon/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/buzzfeed/phonon/pulls/50/commits"},"statuses":{"href":"https://api.github.com/repos/buzzfeed/phonon/statuses/be0c8c4c4cc82fed56e4f3124aec89d9d07a40b7"}}}}