{"action":"created","comment":{"url":"https://api.github.com/repos/dimagi/commcare-hq/pulls/comments/44280416","id":44280416,"diff_hunk":"@@ -0,0 +1,432 @@\n+# coding: utf-8\n+\"\"\"\n+XFormBuilder is intended to be a simple way to create an XForm, and add\n+questions to it.\n+\n+It was created for importing a CDISC ODM document as a CommCare app.\n+Third-party solutions lacked important features like nested groups, and most\n+required their input to come via an Excel spreadsheet or JSON, which did not\n+seem to be a good fit.\n+\n+\n+>>> from corehq.apps.app_manager.xform_builder import XFormBuilder\n+>>> xform = XFormBuilder('Built by XFormBuilder')\n+>>> xform.new_question('name', 'What is your name?')\n+>>> group = xform.new_group('personal', 'Personal Questions')\n+>>> group.new_question('fav_color', u'Quelle est ta couleur préférée?',\n+...                    choices={'r': 'Rot', 'g': u'Grün', 'b': 'Blau'})\n+>>> xml = xform.tostring(pretty_print=True, encoding='utf-8', xml_declaration=True)\n+>>> # Skip the random xmlns when checking the result:\n+>>> xml.startswith(\n+... '''<?xml version=\\'1.0\\' encoding=\\'utf-8\\'?>\\\\n'''\n+... '''<h:html xmlns:h=\"http://www.w3.org/1999/xhtml\" '''\n+...         '''xmlns:orx=\"http://openrosa.org/jr/xforms\" '''\n+...         '''xmlns=\"http://www.w3.org/2002/xforms\" '''\n+...         '''xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" '''\n+...         '''xmlns:jr=\"http://openrosa.org/javarosa\">\\\\n'''\n+... '''  <h:head>\\\\n'''\n+... '''    <h:title>Built by XFormBuilder</h:title>\\\\n'''\n+... '''    <model>\\\\n'''\n+... '''      <instance>\\\\n'''\n+... '''        <data xmlns:jrm=\"http://dev.commcarehq.org/jr/xforms\" '''\n+...               '''xmlns=\"http://openrosa.org/formdesigner/''') and xml.endswith('''\" '''\n+...               '''uiVersion=\"1\" '''\n+...               '''version=\"3\" '''\n+...               '''name=\"Built by XFormBuilder\">\\\\n'''\n+... '''          <name/>\\\\n'''\n+... '''          <personal>\\\\n'''\n+... '''            <fav_color/>\\\\n'''\n+... '''          </personal>\\\\n'''\n+... '''        </data>\\\\n'''\n+... '''      </instance>\\\\n'''\n+... '''      <itext>\\\\n'''\n+... '''        <translation lang=\"en\" default=\"\">\\\\n'''\n+... '''          <text id=\"name-label\">\\\\n'''\n+... '''            <value>What is your name?</value>\\\\n'''\n+... '''          </text>\\\\n'''\n+... '''          <text id=\"personal-label\">\\\\n'''\n+... '''            <value>Personal Questions</value>\\\\n'''\n+... '''          </text>\\\\n'''\n+... '''          <text id=\"personal/fav_color-label\">\\\\n'''\n+... '''            <value>'''\n+...               '''Quelle est ta couleur pr\\xc3\\x83\\xc2\\xa9f\\xc3\\x83\\xc2\\xa9r\\xc3\\x83\\xc2\\xa9e?'''\n+...             '''</value>\\\\n'''\n+... '''          </text>\\\\n'''\n+... '''          <text id=\"personal/fav_color-r-label\">\\\\n'''\n+... '''            <value>Rot</value>\\\\n'''\n+... '''          </text>\\\\n'''\n+... '''          <text id=\"personal/fav_color-b-label\">\\\\n'''\n+... '''            <value>Blau</value>\\\\n'''\n+... '''          </text>\\\\n'''\n+... '''          <text id=\"personal/fav_color-g-label\">\\\\n'''\n+... '''            <value>Gr\\xc3\\x83\\xc2\\xbcn</value>\\\\n'''\n+... '''          </text>\\\\n'''\n+... '''        </translation>\\\\n'''\n+... '''      </itext>\\\\n'''\n+... '''      <bind nodeset=\"/data/name\" type=\"xsd:string\"/>\\\\n'''\n+... '''      <bind nodeset=\"/data/personal\"/>\\\\n'''\n+... '''      <bind nodeset=\"/data/personal/fav_color\" type=\"xsd:string\"/>\\\\n'''\n+... '''    </model>\\\\n'''\n+... '''  </h:head>\\\\n'''\n+... '''  <h:body>\\\\n'''\n+... '''    <input ref=\"/data/name\">\\\\n'''\n+... '''      <label ref=\"jr:itext(\\'name-label\\')\"/>\\\\n'''\n+... '''    </input>\\\\n'''\n+... '''    <group ref=\"/data/personal\">\\\\n'''\n+... '''      <label ref=\"jr:itext(\\'personal-label\\')\"/>\\\\n'''\n+... '''      <input ref=\"/data/personal/fav_color\">\\\\n'''\n+... '''        <label ref=\"jr:itext(\\'personal/fav_color-label\\')\"/>\\\\n'''\n+... '''      </input>\\\\n'''\n+... '''    </group>\\\\n'''\n+... '''  </h:body>\\\\n'''\n+... '''</h:html>\\\\n''')\n+True\n+\n+\"\"\"\n+import uuid\n+from lxml import etree\n+from lxml.builder import E\n+\n+EMPTY_XFORM = \"\"\"<?xml version=\"1.0\"?>\n+<h:html xmlns:h=\"http://www.w3.org/1999/xhtml\"\n+        xmlns:orx=\"http://openrosa.org/jr/xforms\"\n+        xmlns=\"http://www.w3.org/2002/xforms\"\n+        xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n+        xmlns:jr=\"http://openrosa.org/javarosa\">\n+    <h:head>\n+        <h:title>{name}</h:title>\n+        <model>\n+            <instance>\n+                <data xmlns:jrm=\"http://dev.commcarehq.org/jr/xforms\"\n+                      xmlns=\"{xmlns}\"\n+                      uiVersion=\"1\"\n+                      version=\"3\"\n+                      name=\"{name}\"/>\n+            </instance>\n+            <itext>\n+                <translation lang=\"en\" default=\"\"/>\n+            </itext>\n+        </model>\n+    </h:head>\n+    <h:body/>\n+</h:html>\"\"\"\n+\n+\n+# The data types supported by the Open Data Kit XForm spec\n+# cf. https://opendatakit.github.io/odk-xform-spec/#data-types\n+ODK_TYPES = (\n+    'string', 'int', 'boolean', 'decimal', 'date', 'time', 'dateTime', 'select', 'select1', 'geopoint', 'geotrace',\n+    'geoshape', 'binary', 'barcode',\n+)\n+# CommCare question group types\n+GROUP_TYPES = ('group', 'repeatGroup')  # TODO: Support 'questionList'\n+# The subset of ODK data types that are XSD data types\n+# cf. http://www.w3.org/TR/xmlschema-2/#built-in-datatypes\n+XSD_TYPES = ('string', 'int', 'boolean', 'decimal', 'date', 'time', 'dateTime')","path":"corehq/apps/app_manager/xform_builder.py","position":null,"original_position":125,"commit_id":"e9910f186ac8af399e74b4c42ada49c98afa8224","original_commit_id":"f1ab54d04d35d974a31ccb54a39c30b1c37270cd","user":{"login":"kaapstorm","id":708421,"avatar_url":"https://avatars.githubusercontent.com/u/708421?v=3","gravatar_id":"","url":"https://api.github.com/users/kaapstorm","html_url":"https://github.com/kaapstorm","followers_url":"https://api.github.com/users/kaapstorm/followers","following_url":"https://api.github.com/users/kaapstorm/following{/other_user}","gists_url":"https://api.github.com/users/kaapstorm/gists{/gist_id}","starred_url":"https://api.github.com/users/kaapstorm/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kaapstorm/subscriptions","organizations_url":"https://api.github.com/users/kaapstorm/orgs","repos_url":"https://api.github.com/users/kaapstorm/repos","events_url":"https://api.github.com/users/kaapstorm/events{/privacy}","received_events_url":"https://api.github.com/users/kaapstorm/received_events","type":"User","site_admin":false},"body":":+1:","created_at":"2015-11-09T14:34:07Z","updated_at":"2015-11-09T14:34:07Z","html_url":"https://github.com/dimagi/commcare-hq/pull/8953#discussion_r44280416","pull_request_url":"https://api.github.com/repos/dimagi/commcare-hq/pulls/8953","_links":{"self":{"href":"https://api.github.com/repos/dimagi/commcare-hq/pulls/comments/44280416"},"html":{"href":"https://github.com/dimagi/commcare-hq/pull/8953#discussion_r44280416"},"pull_request":{"href":"https://api.github.com/repos/dimagi/commcare-hq/pulls/8953"}}},"pull_request":{"url":"https://api.github.com/repos/dimagi/commcare-hq/pulls/8953","id":49845362,"html_url":"https://github.com/dimagi/commcare-hq/pull/8953","diff_url":"https://github.com/dimagi/commcare-hq/pull/8953.diff","patch_url":"https://github.com/dimagi/commcare-hq/pull/8953.patch","issue_url":"https://api.github.com/repos/dimagi/commcare-hq/issues/8953","number":8953,"state":"open","locked":false,"title":"XFormBuilder for easy XForms","user":{"login":"kaapstorm","id":708421,"avatar_url":"https://avatars.githubusercontent.com/u/708421?v=3","gravatar_id":"","url":"https://api.github.com/users/kaapstorm","html_url":"https://github.com/kaapstorm","followers_url":"https://api.github.com/users/kaapstorm/followers","following_url":"https://api.github.com/users/kaapstorm/following{/other_user}","gists_url":"https://api.github.com/users/kaapstorm/gists{/gist_id}","starred_url":"https://api.github.com/users/kaapstorm/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kaapstorm/subscriptions","organizations_url":"https://api.github.com/users/kaapstorm/orgs","repos_url":"https://api.github.com/users/kaapstorm/repos","events_url":"https://api.github.com/users/kaapstorm/events{/privacy}","received_events_url":"https://api.github.com/users/kaapstorm/received_events","type":"User","site_admin":false},"body":"XFormBuilder is intended to be a simple way to create an XForm, and add questions to it.\r\n\r\nIt was created for importing a CDISC ODM document as a CommCare app. Third-party solutions lacked important features like nested groups, and most required their input to come via an Excel spreadsheet or JSON, which did not seem to be a good fit. I also took a look at [app_manager.xform.XForm][1] but it seemed aimed at getting data from xfoms already built by Vellum. So I thought XFormBuilder might be a useful tool to add. Usage is as simple as\r\n```python\r\nxform = XFormBuilder('Built by XFormBuilder')\r\nxform.add_question('personal', 'Personal Questions', data_type='group')\r\nxform.add_question('name', 'What is your name?', group='personal')\r\nxform.add_question('fav_color', 'What is your favorite color?',\r\n                   group='personal',\r\n                   choices={'r': 'Red', 'g': 'Green', 'b': 'Blue'})\r\nxml = xform.tostring(pretty_print=True, encoding='utf-8')\r\n```\r\n\r\n(Please excuse the ugly XML formatting in the doctest. I can't see why `pretty_print=True` is so not pretty.)\r\n\r\n@millerdev @snopoke cc @orangejenny @czue\r\n\r\n\r\n  [1]: https://github.com/dimagi/commcare-hq/blob/xform_builder/corehq/apps/app_manager/xform.py#L539-539\r\n","created_at":"2015-11-05T16:20:23Z","updated_at":"2015-11-09T14:34:07Z","closed_at":null,"merged_at":null,"merge_commit_sha":"28d4bdd33e2d67eaa7b597846e988c46015afffe","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/dimagi/commcare-hq/pulls/8953/commits","review_comments_url":"https://api.github.com/repos/dimagi/commcare-hq/pulls/8953/comments","review_comment_url":"https://api.github.com/repos/dimagi/commcare-hq/pulls/comments{/number}","comments_url":"https://api.github.com/repos/dimagi/commcare-hq/issues/8953/comments","statuses_url":"https://api.github.com/repos/dimagi/commcare-hq/statuses/e9910f186ac8af399e74b4c42ada49c98afa8224","head":{"label":"dimagi:xform_builder","ref":"xform_builder","sha":"e9910f186ac8af399e74b4c42ada49c98afa8224","user":{"login":"dimagi","id":94514,"avatar_url":"https://avatars.githubusercontent.com/u/94514?v=3","gravatar_id":"","url":"https://api.github.com/users/dimagi","html_url":"https://github.com/dimagi","followers_url":"https://api.github.com/users/dimagi/followers","following_url":"https://api.github.com/users/dimagi/following{/other_user}","gists_url":"https://api.github.com/users/dimagi/gists{/gist_id}","starred_url":"https://api.github.com/users/dimagi/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dimagi/subscriptions","organizations_url":"https://api.github.com/users/dimagi/orgs","repos_url":"https://api.github.com/users/dimagi/repos","events_url":"https://api.github.com/users/dimagi/events{/privacy}","received_events_url":"https://api.github.com/users/dimagi/received_events","type":"Organization","site_admin":false},"repo":{"id":247278,"name":"commcare-hq","full_name":"dimagi/commcare-hq","owner":{"login":"dimagi","id":94514,"avatar_url":"https://avatars.githubusercontent.com/u/94514?v=3","gravatar_id":"","url":"https://api.github.com/users/dimagi","html_url":"https://github.com/dimagi","followers_url":"https://api.github.com/users/dimagi/followers","following_url":"https://api.github.com/users/dimagi/following{/other_user}","gists_url":"https://api.github.com/users/dimagi/gists{/gist_id}","starred_url":"https://api.github.com/users/dimagi/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dimagi/subscriptions","organizations_url":"https://api.github.com/users/dimagi/orgs","repos_url":"https://api.github.com/users/dimagi/repos","events_url":"https://api.github.com/users/dimagi/events{/privacy}","received_events_url":"https://api.github.com/users/dimagi/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/dimagi/commcare-hq","description":"A server-side tool to help manage community health workers, written in Django","fork":false,"url":"https://api.github.com/repos/dimagi/commcare-hq","forks_url":"https://api.github.com/repos/dimagi/commcare-hq/forks","keys_url":"https://api.github.com/repos/dimagi/commcare-hq/keys{/key_id}","collaborators_url":"https://api.github.com/repos/dimagi/commcare-hq/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/dimagi/commcare-hq/teams","hooks_url":"https://api.github.com/repos/dimagi/commcare-hq/hooks","issue_events_url":"https://api.github.com/repos/dimagi/commcare-hq/issues/events{/number}","events_url":"https://api.github.com/repos/dimagi/commcare-hq/events","assignees_url":"https://api.github.com/repos/dimagi/commcare-hq/assignees{/user}","branches_url":"https://api.github.com/repos/dimagi/commcare-hq/branches{/branch}","tags_url":"https://api.github.com/repos/dimagi/commcare-hq/tags","blobs_url":"https://api.github.com/repos/dimagi/commcare-hq/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/dimagi/commcare-hq/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/dimagi/commcare-hq/git/refs{/sha}","trees_url":"https://api.github.com/repos/dimagi/commcare-hq/git/trees{/sha}","statuses_url":"https://api.github.com/repos/dimagi/commcare-hq/statuses/{sha}","languages_url":"https://api.github.com/repos/dimagi/commcare-hq/languages","stargazers_url":"https://api.github.com/repos/dimagi/commcare-hq/stargazers","contributors_url":"https://api.github.com/repos/dimagi/commcare-hq/contributors","subscribers_url":"https://api.github.com/repos/dimagi/commcare-hq/subscribers","subscription_url":"https://api.github.com/repos/dimagi/commcare-hq/subscription","commits_url":"https://api.github.com/repos/dimagi/commcare-hq/commits{/sha}","git_commits_url":"https://api.github.com/repos/dimagi/commcare-hq/git/commits{/sha}","comments_url":"https://api.github.com/repos/dimagi/commcare-hq/comments{/number}","issue_comment_url":"https://api.github.com/repos/dimagi/commcare-hq/issues/comments{/number}","contents_url":"https://api.github.com/repos/dimagi/commcare-hq/contents/{+path}","compare_url":"https://api.github.com/repos/dimagi/commcare-hq/compare/{base}...{head}","merges_url":"https://api.github.com/repos/dimagi/commcare-hq/merges","archive_url":"https://api.github.com/repos/dimagi/commcare-hq/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/dimagi/commcare-hq/downloads","issues_url":"https://api.github.com/repos/dimagi/commcare-hq/issues{/number}","pulls_url":"https://api.github.com/repos/dimagi/commcare-hq/pulls{/number}","milestones_url":"https://api.github.com/repos/dimagi/commcare-hq/milestones{/number}","notifications_url":"https://api.github.com/repos/dimagi/commcare-hq/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/dimagi/commcare-hq/labels{/name}","releases_url":"https://api.github.com/repos/dimagi/commcare-hq/releases{/id}","created_at":"2009-07-09T17:00:07Z","updated_at":"2015-11-05T13:41:38Z","pushed_at":"2015-11-09T14:31:34Z","git_url":"git://github.com/dimagi/commcare-hq.git","ssh_url":"git@github.com:dimagi/commcare-hq.git","clone_url":"https://github.com/dimagi/commcare-hq.git","svn_url":"https://github.com/dimagi/commcare-hq","homepage":"http://www.commcarehq.org","size":431010,"stargazers_count":54,"watchers_count":54,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":62,"mirror_url":null,"open_issues_count":58,"forks":62,"open_issues":58,"watchers":54,"default_branch":"master"}},"base":{"label":"dimagi:master","ref":"master","sha":"9b84fec73451145b1cf03d36530baf7b93fbe0fd","user":{"login":"dimagi","id":94514,"avatar_url":"https://avatars.githubusercontent.com/u/94514?v=3","gravatar_id":"","url":"https://api.github.com/users/dimagi","html_url":"https://github.com/dimagi","followers_url":"https://api.github.com/users/dimagi/followers","following_url":"https://api.github.com/users/dimagi/following{/other_user}","gists_url":"https://api.github.com/users/dimagi/gists{/gist_id}","starred_url":"https://api.github.com/users/dimagi/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dimagi/subscriptions","organizations_url":"https://api.github.com/users/dimagi/orgs","repos_url":"https://api.github.com/users/dimagi/repos","events_url":"https://api.github.com/users/dimagi/events{/privacy}","received_events_url":"https://api.github.com/users/dimagi/received_events","type":"Organization","site_admin":false},"repo":{"id":247278,"name":"commcare-hq","full_name":"dimagi/commcare-hq","owner":{"login":"dimagi","id":94514,"avatar_url":"https://avatars.githubusercontent.com/u/94514?v=3","gravatar_id":"","url":"https://api.github.com/users/dimagi","html_url":"https://github.com/dimagi","followers_url":"https://api.github.com/users/dimagi/followers","following_url":"https://api.github.com/users/dimagi/following{/other_user}","gists_url":"https://api.github.com/users/dimagi/gists{/gist_id}","starred_url":"https://api.github.com/users/dimagi/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dimagi/subscriptions","organizations_url":"https://api.github.com/users/dimagi/orgs","repos_url":"https://api.github.com/users/dimagi/repos","events_url":"https://api.github.com/users/dimagi/events{/privacy}","received_events_url":"https://api.github.com/users/dimagi/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/dimagi/commcare-hq","description":"A server-side tool to help manage community health workers, written in Django","fork":false,"url":"https://api.github.com/repos/dimagi/commcare-hq","forks_url":"https://api.github.com/repos/dimagi/commcare-hq/forks","keys_url":"https://api.github.com/repos/dimagi/commcare-hq/keys{/key_id}","collaborators_url":"https://api.github.com/repos/dimagi/commcare-hq/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/dimagi/commcare-hq/teams","hooks_url":"https://api.github.com/repos/dimagi/commcare-hq/hooks","issue_events_url":"https://api.github.com/repos/dimagi/commcare-hq/issues/events{/number}","events_url":"https://api.github.com/repos/dimagi/commcare-hq/events","assignees_url":"https://api.github.com/repos/dimagi/commcare-hq/assignees{/user}","branches_url":"https://api.github.com/repos/dimagi/commcare-hq/branches{/branch}","tags_url":"https://api.github.com/repos/dimagi/commcare-hq/tags","blobs_url":"https://api.github.com/repos/dimagi/commcare-hq/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/dimagi/commcare-hq/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/dimagi/commcare-hq/git/refs{/sha}","trees_url":"https://api.github.com/repos/dimagi/commcare-hq/git/trees{/sha}","statuses_url":"https://api.github.com/repos/dimagi/commcare-hq/statuses/{sha}","languages_url":"https://api.github.com/repos/dimagi/commcare-hq/languages","stargazers_url":"https://api.github.com/repos/dimagi/commcare-hq/stargazers","contributors_url":"https://api.github.com/repos/dimagi/commcare-hq/contributors","subscribers_url":"https://api.github.com/repos/dimagi/commcare-hq/subscribers","subscription_url":"https://api.github.com/repos/dimagi/commcare-hq/subscription","commits_url":"https://api.github.com/repos/dimagi/commcare-hq/commits{/sha}","git_commits_url":"https://api.github.com/repos/dimagi/commcare-hq/git/commits{/sha}","comments_url":"https://api.github.com/repos/dimagi/commcare-hq/comments{/number}","issue_comment_url":"https://api.github.com/repos/dimagi/commcare-hq/issues/comments{/number}","contents_url":"https://api.github.com/repos/dimagi/commcare-hq/contents/{+path}","compare_url":"https://api.github.com/repos/dimagi/commcare-hq/compare/{base}...{head}","merges_url":"https://api.github.com/repos/dimagi/commcare-hq/merges","archive_url":"https://api.github.com/repos/dimagi/commcare-hq/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/dimagi/commcare-hq/downloads","issues_url":"https://api.github.com/repos/dimagi/commcare-hq/issues{/number}","pulls_url":"https://api.github.com/repos/dimagi/commcare-hq/pulls{/number}","milestones_url":"https://api.github.com/repos/dimagi/commcare-hq/milestones{/number}","notifications_url":"https://api.github.com/repos/dimagi/commcare-hq/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/dimagi/commcare-hq/labels{/name}","releases_url":"https://api.github.com/repos/dimagi/commcare-hq/releases{/id}","created_at":"2009-07-09T17:00:07Z","updated_at":"2015-11-05T13:41:38Z","pushed_at":"2015-11-09T14:31:34Z","git_url":"git://github.com/dimagi/commcare-hq.git","ssh_url":"git@github.com:dimagi/commcare-hq.git","clone_url":"https://github.com/dimagi/commcare-hq.git","svn_url":"https://github.com/dimagi/commcare-hq","homepage":"http://www.commcarehq.org","size":431010,"stargazers_count":54,"watchers_count":54,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":62,"mirror_url":null,"open_issues_count":58,"forks":62,"open_issues":58,"watchers":54,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/dimagi/commcare-hq/pulls/8953"},"html":{"href":"https://github.com/dimagi/commcare-hq/pull/8953"},"issue":{"href":"https://api.github.com/repos/dimagi/commcare-hq/issues/8953"},"comments":{"href":"https://api.github.com/repos/dimagi/commcare-hq/issues/8953/comments"},"review_comments":{"href":"https://api.github.com/repos/dimagi/commcare-hq/pulls/8953/comments"},"review_comment":{"href":"https://api.github.com/repos/dimagi/commcare-hq/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/dimagi/commcare-hq/pulls/8953/commits"},"statuses":{"href":"https://api.github.com/repos/dimagi/commcare-hq/statuses/e9910f186ac8af399e74b4c42ada49c98afa8224"}}}}