{"action":"created","comment":{"url":"https://api.github.com/repos/django/deps/pulls/comments/86681868","pull_request_review_id":7329223,"id":86681868,"diff_hunk":"@@ -0,0 +1,306 @@\n+=======================================\n+DEP 8: Gathering Django usage analytics\n+=======================================\n+\n+:DEP: 8\n+:Author: Jacob Kaplan-Moss\n+:Implementation Team: TBD\n+:Shepherd: TBD\n+:Status: Draft\n+:Type: Feature/Process\n+:Created: 2016-11-05\n+:Last-Modified: 2016-11-05\n+\n+.. contents:: Table of Contents\n+   :depth: 3\n+   :local:\n+\n+Abstract\n+========\n+\n+    Maintaining open source code used to be more manageable. [...]\n+\n+    Today, everybody uses open source code, including Fortune 500 companies,\n+    government, major software companies and startups. Sharing, rather than\n+    building proprietary code, turned out to be cheaper, easier, and more\n+    efficient. This increased demand puts additional strain on those who\n+    maintain this infrastructure, yet because these communities are not highly\n+    visible, the rest of the world has been slow to notice. Most of us take\n+    opening a software application for granted, the way we take turning on the\n+    lights for granted. We don’t think about the human capital necessary to make\n+    that happen. \n+\n+    In the face of unprecedented demand, the costs of not supporting our digital\n+    infrastructure are numerous.\n+\n+    — Nadia Eghbal, `Roads and Bridges: The Unseen Labor Behind Our Digital Infrastructure <http://www.fordfoundation.org/library/reports-and-studies/roads-and-bridges-the-unseen-labor-behind-our-digital-infrastructure/>`_.\n+\n+..\n+\n+    A lot of people contribute to OSS in their free time and do it because they\n+    generally enjoy it. [...]  Ask any open source project\n+    maintainer, though, and they will tell you about the reality of the amount\n+    of work that goes into managing a project. You have clients. You are fixing\n+    issues for them. You are creating new features. This becomes a real demand\n+    on your time.\n+\n+    Paid or not, play or not, this is labor that is currently not being\n+    compensated.\n+\n+    — Ashe Dryden, `The Ethics of Unpaid Labor and the OSS Community <https://www.ashedryden.com/blog/the-ethics-of-unpaid-labor-and-the-oss-community>`_.\n+\n+As Django enters its second decade, we're thinking about the long game.\n+Sustainability has become a key concern. Django is indeed used by  \"Fortune 500\n+companies, government, major software companies and startups\", yet those\n+organizations mostly don't contribute meaningfully to Django's continued\n+success. The majority of work is at the whim of volunteers and their free time.\n+\n+Increasingly, we've recognized that this is not sustainable. Relying on the\n+free labor of volunteers is ineffective, unfair, and risky. Put bluntly:\n+**the future of Django depends on our ability to fund its development**.\n+\n+In the last few years, we've started taking steps to fund important work. The\n+Django Software Foundation now employs an engineer to shepherd Django's\n+development, and this has been wildly successful in improving Django's velocity,\n+reducing bugs, and shipping releases on-time. Additionally, several major new\n+features in Django were funded through some mix of corporate sponsorship,\n+grants, or crowdfunding.\n+\n+These funded projects have been quite successful, but this success is tenuous.\n+Most work is still volunteer-driven, and those who are paid by and large have\n+been paid well below market rates. \n+\n+This is because fundraising is extremely difficult: it's hard to convince\n+organizations to spend money on something they get for free.\n+\n+A major reason that fundraising remains difficult is our inability to measure\n+the size of the Django community. The only information we have about the use of\n+Django is anecdotal (e.g. \"Instagram uses Django\") or is measuring information\n+without much value (e.g. number of times Django's been installed, which is\n+essentially a vanity metric inflated by virtual environments, CI servers, and\n+the like). If we had clear data on the extent of Django's usage, it would be\n+much easier to approach organizations for funding. As Eghbal writes:\n+\n+    [W]ithout data about which tools are used, and how much we rely upon them,\n+    [it is hard to paint a clear picture of what is underfunded.\n+\n+    With better metrics, we could describe the economic impact of digital\n+    infrastructure, identify critical projects that are lacking support, and\n+    understand dependencies between projects and people. Right now, it is\n+    impossible to say who is using an open source project unless that person or\n+    company discloses their usage. Our information about which projects need\n+    better support is mostly anecdotal.\n+\n+Anyone who's tried to raise money for Django knows this first-hand: potential\n+sponsors always ask for data. When they hear that we have no hard metrics,\n+their offers decrease (or vanish).\n+\n+We aim to solve this problem by starting gathering anonymous usage metrics. We\n+know that this is touchy -- privacy is an important value in our community, and\n+we're not interested in tracking our users. However, we need this data to\n+make the case to companies and governments for increased funding.\n+\n+We believe that we've struck a balance that lets us gather the data we need\n+for sustainability while respecting our users' privacy. And, it'll always\n+be possible for users to disable this metric collection. We're hoping the vast\n+majority of our users will choose to leave it enabled as a small but important\n+way of helping Django continue to thrive.\n+\n+The rest of this DEP explains what we measure and how that data is used.\n+\n+Specification\n+=============\n+\n+Starting in version XXX, Django gathers anonymous user analytics and report\n+those to Google Analytics. This will happen when certain ``django-admin``\n+commands are run. Metric collection will be enabled by default, and users \n+will be warned the first time they run ``django-admin``.\n+\n+When will analytics be sent?\n+----------------------------\n+\n+Analytics will be sent when certain ``django-admin`` commands are run:\n+``startproject``, ``startapp``, and ``runserver``. If a settings file\n+can be loaded (i.e. for``startapp`` and ``runserver``), analytics will only\n+be gathered and sent if ``DEBUG`` is ``True``.\n+\n+Our goal is to try to measure \"unique developers\", so we've tried to select\n+commands that will only be run in development situations, and won't be run by\n+production servers. By selecting a few different commands, we account for a\n+variety of developer workflows.\n+\n+What is tracked?\n+----------------\n+\n+Django sends an ``event`` hit type when you run one of the above commands.\n+This event includes the following information:\n+\n+- An event category corresponding to the specific command run (e.g. \n+  ``startproject``, ``startapp``, or ``runserver``). No arguments to \n+  the command are sent (so we don't receive the project name or app name,\n+  where the server is running, etc.)\n+\n+- A HTTP User-Agent that identifies the version of Django, the version of\n+  Python, and a platform identifier. For example: \n+  ``Django/1.11 CPython/3.5.1 (Macintosh; Intel macOS 10.12.0)``\n+\n+- The Django name (e.g. ``Django``) and version (e.g. ``1.11``) passed as\n+  the Google Analytics application name (`aid`_) and application version (`av`_).\n+\n+- A unique Django analytics user ID, e.g. ``3fa04034-a36b-11e6-acd6-acbc32c6febd``.\n+  This is generated by the Python standard library function ``uuid.uuid1()`` and\n+  stored in ``~/.config/djangoanalytics`` (or equivalent on non-Linux\n+  platforms). This means we can't track individual users, but does enable us to\n+  more accurate measure distinct user counts vs. event accounts. This is sent as\n+  the Google Analytics `cid parameter`_.\n+\n+  Note that we can't actually see this ID -- it's used anonymously to identify\n+  a single user, but isn't exposed in Google Analytics. This means we can't\n+  tie an event to a single user, even if we wanted to -- which we most certainly\n+  do not. \n+\n+- The flag to enable IP anonymization, which ensures that we can't see, and \n+  Google Analytics doesn't store, your actual IP. This is done by setting the\n+  Google Analytics `aip parameter`_ to ``1``.\n+\n+- The Google Analytics version - ``1`` . This is sent as the Google Analytics \n+  `v parameter`_. \n+\n+- Django's Google Analytics tracking ID - e.g. ``UA-XXXXXXXX-X``.\n+  This is sent as the Google Analytics `tid parameter`_.\n+\n+.. _cid parameter: https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters#cid\n+.. _v parameter: https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters#v\n+.. _tid parameter: https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters#tid\n+.. _aip parameter: https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters#aip\n+.. _aid: https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters#aid\n+.. _av: https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters#av\n+\n+You can view all information that is sent by setting ``DJANGO_ANALYTICS_DEBUG=1``\n+in your environment. This'll print analytics to the console instead of sending\n+them to Google Analytics.\n+\n+.. note::\n+\n+    This section is largely cribbed from `Homebrew's analytics implementation <https://github.com/Homebrew/brew/blob/bbed7246bc5c5b7acb8c1d427d10b43e090dfd39/docs/Analytics.md>`_. Thanks!\n+\n+How will analytics be sent?\n+---------------------------\n+\n+Data is sent to Google Analytics over HTTPs using Python's ``urllib2`` standard\n+library.\n+\n+Who has access to analytics data?\n+---------------------------------\n+\n+Access to the Google Analytics dashboard and data will be limited to the \n+following people/groups:\n+\n+- The DSF President, in their role providing oversight to the DSF.\n+\n+- Members of a fundraising committee, if established by the DSF Board. Employees\n+  or contractors hired for fundraising purposes may also be granted access by\n+  this fundraising committee.\n+\n+- Members of the Django Technical Board, upon request.\n+\n+- Members of the Django Infrastructure Team (so they can maintain the GA \n+  instance and grant/revoke access). These will be the only administrative\n+  users (i.e., the only users who can grant or revoke access).\n+\n+Opting out\n+----------\n+\n+Users can disable analytics collection in two ways:\n+\n+1. By setting an environment variable: ``export DJANGO_NO_ANALYTICS=1``.\n+\n+2. Setting ``disable=1`` in ``~/.config/djangoanalytics`` (or equivalent).\n+\n+The first time Django tries to send analytics for a given user, it'll \n+print out a message about metrics collection with instructions for disabling it.\n+\n+Implementation\n+--------------\n+\n+Once the implementation is merged, it'll be linked up here. In the meantime,\n+see the `Reference Implementation`_ section for a rough picture.\n+\n+Rationale\n+=========\n+\n+The high-level rationale is explained in the `Abstract`_: gather data that  we\n+can use to convince organizations to support Django. This section articulates\n+the detailed decisions we made to get from that high-level goal to this specific\n+implementation.\n+\n+Other options for what to collect and measure\n+---------------------------------------------\n+\n+The number we'd *really* like to have is the number of production websites or\n+servers running Django. We could gather this by sending metrics data when a\n+Django worker is started -- for example, from within ``django.setup()``, or\n+or when the WSGI application is initialized. \n+\n+However, this would be unacceptable to many organizations. Application servers\n+\"phoning home\" raise serious security concerns, and many larger organizations\n+consider information on their production environments to be confidential. So,\n+as much as we want this data, collecting it is simply too invasive.\n+\n+Another option would be to collect data on the admin usage (e.g. embedding\n+Google Analytics directly). A couple of Django projects (Wagtail and Oscar)\n+have done this successfully. We decided against this since \"people\n+who use the admin\" isn't as useful a metric as counting developers.\n+\n+Finally, we considered tracking *all* ``django-admin`` commands, which would  do\n+a better job of finding developers (not everyone uses ``startproject``,\n+``startapp``, or ``runserver``). However, would risk getting run on production\n+servers -- for example, many people run ``migrate`` on their production servers\n+-- which raise some of the same concerns as above. So, we choose to only measure\n+upon certain commands that we can feel fairly certain won't be run in production.\n+This runs the risk of undercounting, but we think this is the best option.\n+\n+Opt-out vs opt-in\n+-----------------\n+\n+We chose to send analytics data by default, with a way to opt out. Another\n+option would be an opt-in system, along the lines of Debian's `popularity\n+contest <http://popcon.debian.org/>`_.\n+\n+The downsides of this approach is that it severely undercounts: the only\n+people who will turn something like this on are \"true fans\". So, an opt-in\n+approach isn't substantially better than a community survey. We've run these\n+in the past, and while they've given data that we've found interesting, \n+potential sponsors have been far less impressed by that data.\n+\n+We believe that collecting data by default is the only way we'll get a roughly\n+accurate measure of Django's usage.\n+\n+Google Analytics vs other platforms/choices\n+-------------------------------------------\n+\n+Using Google Analytics is a trade-off. On the one hand, Google's track record ","path":"draft/0008-gathering-usage-metrics.rst","position":282,"original_position":282,"commit_id":"4fde38d6b26e5f5adf9e15486479143083e075f8","original_commit_id":"4fde38d6b26e5f5adf9e15486479143083e075f8","user":{"login":"raphaelm","id":64280,"avatar_url":"https://avatars.githubusercontent.com/u/64280?v=3","gravatar_id":"","url":"https://api.github.com/users/raphaelm","html_url":"https://github.com/raphaelm","followers_url":"https://api.github.com/users/raphaelm/followers","following_url":"https://api.github.com/users/raphaelm/following{/other_user}","gists_url":"https://api.github.com/users/raphaelm/gists{/gist_id}","starred_url":"https://api.github.com/users/raphaelm/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/raphaelm/subscriptions","organizations_url":"https://api.github.com/users/raphaelm/orgs","repos_url":"https://api.github.com/users/raphaelm/repos","events_url":"https://api.github.com/users/raphaelm/events{/privacy}","received_events_url":"https://api.github.com/users/raphaelm/received_events","type":"User","site_admin":false},"body":"I'd be much in favor of a proxy of that kind.","created_at":"2016-11-06T09:05:54Z","updated_at":"2016-11-06T09:05:54Z","html_url":"https://github.com/django/deps/pull/31#discussion_r86681868","pull_request_url":"https://api.github.com/repos/django/deps/pulls/31","_links":{"self":{"href":"https://api.github.com/repos/django/deps/pulls/comments/86681868"},"html":{"href":"https://github.com/django/deps/pull/31#discussion_r86681868"},"pull_request":{"href":"https://api.github.com/repos/django/deps/pulls/31"}}},"pull_request":{"url":"https://api.github.com/repos/django/deps/pulls/31","id":92459152,"html_url":"https://github.com/django/deps/pull/31","diff_url":"https://github.com/django/deps/pull/31.diff","patch_url":"https://github.com/django/deps/pull/31.patch","issue_url":"https://api.github.com/repos/django/deps/issues/31","number":31,"state":"open","locked":false,"title":"DEP 8: Gathering Django usage analytics","user":{"login":"jacobian","id":21148,"avatar_url":"https://avatars.githubusercontent.com/u/21148?v=3","gravatar_id":"","url":"https://api.github.com/users/jacobian","html_url":"https://github.com/jacobian","followers_url":"https://api.github.com/users/jacobian/followers","following_url":"https://api.github.com/users/jacobian/following{/other_user}","gists_url":"https://api.github.com/users/jacobian/gists{/gist_id}","starred_url":"https://api.github.com/users/jacobian/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jacobian/subscriptions","organizations_url":"https://api.github.com/users/jacobian/orgs","repos_url":"https://api.github.com/users/jacobian/repos","events_url":"https://api.github.com/users/jacobian/events{/privacy}","received_events_url":"https://api.github.com/users/jacobian/received_events","type":"User","site_admin":false},"body":"I want to start collecting some basic usage metrics so that it's easier for the DSF to raise money.\r\n\r\nTODO before merging to master:\r\n- [ ] reference implementation\r\n- [ ] list prior art\r\n- [ ] clarify the `cid` bit and why we couldn't track a user even if we knew their id\r\n- [ ] other things I'm probably forgetting","created_at":"2016-11-05T16:48:06Z","updated_at":"2016-11-06T09:05:54Z","closed_at":null,"merged_at":null,"merge_commit_sha":"ff9ab30168404a532b6c3b2d3f06eefd1a831a02","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/django/deps/pulls/31/commits","review_comments_url":"https://api.github.com/repos/django/deps/pulls/31/comments","review_comment_url":"https://api.github.com/repos/django/deps/pulls/comments{/number}","comments_url":"https://api.github.com/repos/django/deps/issues/31/comments","statuses_url":"https://api.github.com/repos/django/deps/statuses/4fde38d6b26e5f5adf9e15486479143083e075f8","head":{"label":"django:metrics","ref":"metrics","sha":"4fde38d6b26e5f5adf9e15486479143083e075f8","user":{"login":"django","id":27804,"avatar_url":"https://avatars.githubusercontent.com/u/27804?v=3","gravatar_id":"","url":"https://api.github.com/users/django","html_url":"https://github.com/django","followers_url":"https://api.github.com/users/django/followers","following_url":"https://api.github.com/users/django/following{/other_user}","gists_url":"https://api.github.com/users/django/gists{/gist_id}","starred_url":"https://api.github.com/users/django/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/django/subscriptions","organizations_url":"https://api.github.com/users/django/orgs","repos_url":"https://api.github.com/users/django/repos","events_url":"https://api.github.com/users/django/events{/privacy}","received_events_url":"https://api.github.com/users/django/received_events","type":"Organization","site_admin":false},"repo":{"id":18764735,"name":"deps","full_name":"django/deps","owner":{"login":"django","id":27804,"avatar_url":"https://avatars.githubusercontent.com/u/27804?v=3","gravatar_id":"","url":"https://api.github.com/users/django","html_url":"https://github.com/django","followers_url":"https://api.github.com/users/django/followers","following_url":"https://api.github.com/users/django/following{/other_user}","gists_url":"https://api.github.com/users/django/gists{/gist_id}","starred_url":"https://api.github.com/users/django/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/django/subscriptions","organizations_url":"https://api.github.com/users/django/orgs","repos_url":"https://api.github.com/users/django/repos","events_url":"https://api.github.com/users/django/events{/privacy}","received_events_url":"https://api.github.com/users/django/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/django/deps","description":"Django Enhancement Proposals","fork":false,"url":"https://api.github.com/repos/django/deps","forks_url":"https://api.github.com/repos/django/deps/forks","keys_url":"https://api.github.com/repos/django/deps/keys{/key_id}","collaborators_url":"https://api.github.com/repos/django/deps/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/django/deps/teams","hooks_url":"https://api.github.com/repos/django/deps/hooks","issue_events_url":"https://api.github.com/repos/django/deps/issues/events{/number}","events_url":"https://api.github.com/repos/django/deps/events","assignees_url":"https://api.github.com/repos/django/deps/assignees{/user}","branches_url":"https://api.github.com/repos/django/deps/branches{/branch}","tags_url":"https://api.github.com/repos/django/deps/tags","blobs_url":"https://api.github.com/repos/django/deps/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/django/deps/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/django/deps/git/refs{/sha}","trees_url":"https://api.github.com/repos/django/deps/git/trees{/sha}","statuses_url":"https://api.github.com/repos/django/deps/statuses/{sha}","languages_url":"https://api.github.com/repos/django/deps/languages","stargazers_url":"https://api.github.com/repos/django/deps/stargazers","contributors_url":"https://api.github.com/repos/django/deps/contributors","subscribers_url":"https://api.github.com/repos/django/deps/subscribers","subscription_url":"https://api.github.com/repos/django/deps/subscription","commits_url":"https://api.github.com/repos/django/deps/commits{/sha}","git_commits_url":"https://api.github.com/repos/django/deps/git/commits{/sha}","comments_url":"https://api.github.com/repos/django/deps/comments{/number}","issue_comment_url":"https://api.github.com/repos/django/deps/issues/comments{/number}","contents_url":"https://api.github.com/repos/django/deps/contents/{+path}","compare_url":"https://api.github.com/repos/django/deps/compare/{base}...{head}","merges_url":"https://api.github.com/repos/django/deps/merges","archive_url":"https://api.github.com/repos/django/deps/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/django/deps/downloads","issues_url":"https://api.github.com/repos/django/deps/issues{/number}","pulls_url":"https://api.github.com/repos/django/deps/pulls{/number}","milestones_url":"https://api.github.com/repos/django/deps/milestones{/number}","notifications_url":"https://api.github.com/repos/django/deps/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/django/deps/labels{/name}","releases_url":"https://api.github.com/repos/django/deps/releases{/id}","deployments_url":"https://api.github.com/repos/django/deps/deployments","created_at":"2014-04-14T14:59:32Z","updated_at":"2016-11-06T09:39:42Z","pushed_at":"2016-11-05T16:55:43Z","git_url":"git://github.com/django/deps.git","ssh_url":"git@github.com:django/deps.git","clone_url":"https://github.com/django/deps.git","svn_url":"https://github.com/django/deps","homepage":null,"size":190,"stargazers_count":201,"watchers_count":201,"language":null,"has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":37,"mirror_url":null,"open_issues_count":3,"forks":37,"open_issues":3,"watchers":201,"default_branch":"master"}},"base":{"label":"django:master","ref":"master","sha":"0f8f8b3392e99b7d6bbd5377f532e64e7adf9eb8","user":{"login":"django","id":27804,"avatar_url":"https://avatars.githubusercontent.com/u/27804?v=3","gravatar_id":"","url":"https://api.github.com/users/django","html_url":"https://github.com/django","followers_url":"https://api.github.com/users/django/followers","following_url":"https://api.github.com/users/django/following{/other_user}","gists_url":"https://api.github.com/users/django/gists{/gist_id}","starred_url":"https://api.github.com/users/django/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/django/subscriptions","organizations_url":"https://api.github.com/users/django/orgs","repos_url":"https://api.github.com/users/django/repos","events_url":"https://api.github.com/users/django/events{/privacy}","received_events_url":"https://api.github.com/users/django/received_events","type":"Organization","site_admin":false},"repo":{"id":18764735,"name":"deps","full_name":"django/deps","owner":{"login":"django","id":27804,"avatar_url":"https://avatars.githubusercontent.com/u/27804?v=3","gravatar_id":"","url":"https://api.github.com/users/django","html_url":"https://github.com/django","followers_url":"https://api.github.com/users/django/followers","following_url":"https://api.github.com/users/django/following{/other_user}","gists_url":"https://api.github.com/users/django/gists{/gist_id}","starred_url":"https://api.github.com/users/django/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/django/subscriptions","organizations_url":"https://api.github.com/users/django/orgs","repos_url":"https://api.github.com/users/django/repos","events_url":"https://api.github.com/users/django/events{/privacy}","received_events_url":"https://api.github.com/users/django/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/django/deps","description":"Django Enhancement Proposals","fork":false,"url":"https://api.github.com/repos/django/deps","forks_url":"https://api.github.com/repos/django/deps/forks","keys_url":"https://api.github.com/repos/django/deps/keys{/key_id}","collaborators_url":"https://api.github.com/repos/django/deps/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/django/deps/teams","hooks_url":"https://api.github.com/repos/django/deps/hooks","issue_events_url":"https://api.github.com/repos/django/deps/issues/events{/number}","events_url":"https://api.github.com/repos/django/deps/events","assignees_url":"https://api.github.com/repos/django/deps/assignees{/user}","branches_url":"https://api.github.com/repos/django/deps/branches{/branch}","tags_url":"https://api.github.com/repos/django/deps/tags","blobs_url":"https://api.github.com/repos/django/deps/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/django/deps/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/django/deps/git/refs{/sha}","trees_url":"https://api.github.com/repos/django/deps/git/trees{/sha}","statuses_url":"https://api.github.com/repos/django/deps/statuses/{sha}","languages_url":"https://api.github.com/repos/django/deps/languages","stargazers_url":"https://api.github.com/repos/django/deps/stargazers","contributors_url":"https://api.github.com/repos/django/deps/contributors","subscribers_url":"https://api.github.com/repos/django/deps/subscribers","subscription_url":"https://api.github.com/repos/django/deps/subscription","commits_url":"https://api.github.com/repos/django/deps/commits{/sha}","git_commits_url":"https://api.github.com/repos/django/deps/git/commits{/sha}","comments_url":"https://api.github.com/repos/django/deps/comments{/number}","issue_comment_url":"https://api.github.com/repos/django/deps/issues/comments{/number}","contents_url":"https://api.github.com/repos/django/deps/contents/{+path}","compare_url":"https://api.github.com/repos/django/deps/compare/{base}...{head}","merges_url":"https://api.github.com/repos/django/deps/merges","archive_url":"https://api.github.com/repos/django/deps/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/django/deps/downloads","issues_url":"https://api.github.com/repos/django/deps/issues{/number}","pulls_url":"https://api.github.com/repos/django/deps/pulls{/number}","milestones_url":"https://api.github.com/repos/django/deps/milestones{/number}","notifications_url":"https://api.github.com/repos/django/deps/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/django/deps/labels{/name}","releases_url":"https://api.github.com/repos/django/deps/releases{/id}","deployments_url":"https://api.github.com/repos/django/deps/deployments","created_at":"2014-04-14T14:59:32Z","updated_at":"2016-11-06T09:39:42Z","pushed_at":"2016-11-05T16:55:43Z","git_url":"git://github.com/django/deps.git","ssh_url":"git@github.com:django/deps.git","clone_url":"https://github.com/django/deps.git","svn_url":"https://github.com/django/deps","homepage":null,"size":190,"stargazers_count":201,"watchers_count":201,"language":null,"has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":37,"mirror_url":null,"open_issues_count":3,"forks":37,"open_issues":3,"watchers":201,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/django/deps/pulls/31"},"html":{"href":"https://github.com/django/deps/pull/31"},"issue":{"href":"https://api.github.com/repos/django/deps/issues/31"},"comments":{"href":"https://api.github.com/repos/django/deps/issues/31/comments"},"review_comments":{"href":"https://api.github.com/repos/django/deps/pulls/31/comments"},"review_comment":{"href":"https://api.github.com/repos/django/deps/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/django/deps/pulls/31/commits"},"statuses":{"href":"https://api.github.com/repos/django/deps/statuses/4fde38d6b26e5f5adf9e15486479143083e075f8"}}}}
{"actor":{"display_login":"raphaelm"}}