{"action":"created","comment":{"url":"https://api.github.com/repos/bokeh/bokeh/pulls/comments/25450594","id":25450594,"diff_hunk":"@@ -0,0 +1,516 @@\n+#-----------------------------------------------------------------------------\n+# Copyright (c) 2012 - 2015, Continuum Analytics, Inc. All rights reserved.\n+#\n+# Powered by the Bokeh Development Team.\n+#\n+# The full license is in the file LICENSE.txt, distributed with this software.\n+#-----------------------------------------------------------------------------\n+\"\"\" Encapsulate implicit state for Bokeh plotting APIs.\n+\n+Generating output for Bokeh plots requires coordinating several things:\n+\n+:class:`Documents <bokeh.document>`\n+    Group together Bokeh models that may be shared between plots (e.g.,\n+    range or data source objects) into one common namespace.\n+\n+:class:`Resources <bokeh.resources>`\n+    Control how JavaScript and CSS for the client library BokehJS are\n+    included and used in the generated output.\n+\n+:class:`Sessions <bokeh.session>`\n+    Create and manage persistent connections to a Bokeh server.\n+\n+It is certainly possible to handle the configuration of these objects\n+manually, and several examples of this can be found in ``examples/glyphs``.\n+When developing sophisticated applications, it may be necessary or\n+desirable to work at this level. However, for general use this would\n+quickly become burdensome. The ``bokeh.state`` module provides a ``State``\n+class that encapsulates these objects and ensures their proper configuration.\n+It also provides a \"global\" or \"default\" ``State`` object, as well as\n+convenience functions for manipulating this default state.\n+\n+\"\"\"\n+\n+#-----------------------------------------------------------------------------\n+# Imports\n+#-----------------------------------------------------------------------------\n+\n+# Stdlib imports\n+import logging\n+logger = logging.getLogger(__name__)\n+\n+import io, os, time, warnings\n+\n+# Third-party imports\n+\n+# Our own imports\n+from . import browserlib\n+from .document import Document\n+from .embed import notebook_div, file_html, autoload_server\n+from .models import Widget\n+from .resources import Resources\n+from .session import DEFAULT_SERVER_URL, Session\n+from .utils import decode_utf8, publish_display_data\n+\n+#-----------------------------------------------------------------------------\n+# Globals and constants\n+#-----------------------------------------------------------------------------\n+\n+_new_param = {'tab': 2, 'window': 1}\n+\n+#-----------------------------------------------------------------------------\n+# Local utilities\n+#-----------------------------------------------------------------------------\n+\n+#-----------------------------------------------------------------------------\n+# Classes and functions\n+#-----------------------------------------------------------------------------\n+\n+class State(object):\n+    \"\"\" Manage state related to controlling Bokeh output.\n+\n+    Properties:\n+        document :\n+        file :\n+        notebook :\n+        session :\n+\n+\n+    \"\"\"\n+\n+    def __init__(self):\n+        self.reset()\n+\n+    @property\n+    def document(self):\n+        return self._document\n+\n+    @property\n+    def file(self):\n+        return self._file\n+\n+    @property\n+    def notebook(self):\n+        return self._notebook\n+\n+    @property\n+    def session(self):\n+        return self._session\n+\n+    def reset(self):\n+        ''' Deactivate all currently active output modes.\n+\n+        Subsequent calls to show() will not render until a new output mode is\n+        activated.\n+\n+        Returns:\n+            None\n+\n+        '''\n+        self._document = Document()\n+        self._file = None\n+        self._notebook = False\n+        self._session = None\n+\n+    def output_file(self, filename, title=\"Bokeh Plot\", autosave=False, mode=\"inline\", root_dir=None):\n+        \"\"\" Output to a static HTML file.\n+\n+        Args:\n+            filename (str) :\n+\n+            title (str, optional) :\n+\n+            autosave (bool, optional) : whether to automatically save (default: False)\n+                If True, then Bokeh plotting APIs may opt to automatically\n+                save the file more frequently (e.g., after any plotting\n+                command). If False, then the file is only saved upon calling\n+                show().\n+\n+            mode (str, optional) : how to inlcude BokehJS (default: \"inline\")\n+                One of: 'inline', 'cdn', 'relative(-dev)' or 'absolute(-dev)'.\n+                See :class:`bokeh.resources.Resources` for more details.\n+\n+            root_dir (str, optional) :\n+\n+        .. note::\n+            Generally, this should be called at the beginning of an interactive\n+            session or the top of a script.\n+\n+        .. warning::\n+            This output file will be overwritten on every save, e.g., each time\n+            show() or save() is invoked, or any time a Bokeh plotting API\n+            causes a save, if ``autosave`` is True.\n+\n+        \"\"\"\n+        self._file = {\n+            'filename'  : filename,\n+            'resources' : Resources(mode=mode, root_dir=root_dir),\n+            'autosave'  : autosave,\n+            'title'     : title,\n+        }\n+\n+        if os.path.isfile(filename):\n+            logger.info(\"Session output file '%s' already exists, will be overwritten.\" % filename)\n+\n+    def output_notebook(self, url=None, docname=None, session=None, name=None):\n+        self._notebook = True\n+\n+        if session or url or name:\n+            if docname is None:\n+                docname = \"IPython Session at %s\" % time.ctime()\n+            self.output_server(docname, url=url, session=session, name=name)\n+\n+    def output_server(self, docname, session=None, url=\"default\", name=None, clear=True):\n+        \"\"\" Store Bokeh plots and objects on a Bokeh server.\n+\n+        Args:\n+            docname (str) : Name of document to push on Bokeh server\n+                Any existing documents with the same name will be overwritten.\n+\n+            session (Session, optional) : An explicit session to use (default: None)\n+                If None, a new default session is created.\n+\n+            url (str, optional) : URL of the Bokeh server (default: \"default\")\n+                If \"default\", then ``session.DEFAULT_SERVER_URL`` is used.\n+\n+            name (str, optional) : A name for the session\n+                If None, the server URL is used as the name\n+\n+            clear (bool, optional) : Whether to clear the document (default: True)\n+                If True, an existing server document will be cleared of any\n+                existing objects.\n+\n+        Returns:\n+            None\n+\n+        .. note::\n+            Generally, this should be called at the beginning of an interactive\n+            session or the top of a script.\n+\n+        .. warning::\n+            Calling this function will replace any existing default session.\n+\n+        \"\"\"\n+        if url == \"default\":\n+            url = DEFAULT_SERVER_URL\n+\n+        if name is None:\n+            name = url\n+\n+        if not session:\n+            self._session = Session(name=name, root_url=url)\n+        else:\n+            self._session = session\n+\n+        self._session.use_doc(docname)\n+        self._session.load_document(self._document)\n+\n+        if clear:\n+            self._document.clear()\n+\n+\n+_state = State()\n+\n+\n+def output_file(filename, title=\"Bokeh Plot\", autosave=False, mode=\"inline\", root_dir=None):\n+    ''' Configure the default output state to generate output saved\n+    to a file when :func:`show` is called.\n+\n+    Args:\n+        filename (str) :\n+\n+        title (str, optional) :\n+\n+        autosave (bool, optional) : whether to automatically save (default: False)\n+            If True, then Bokeh plotting APIs may opt to automatically\n+            save the file more frequently (e.g., after any plotting\n+            command). If False, then the file is only saved upon calling\n+            show().\n+\n+        mode (str, optional) : how to inlcude BokehJS (default: \"inline\")\n+            One of: 'inline', 'cdn', 'relative(-dev)' or 'absolute(-dev)'.\n+            See :class:`bokeh.resources.Resources` for more details.\n+\n+        root_dir (str, optional) :\n+\n+    Returns:\n+        None\n+\n+    '''\n+    _state.output_file(\n+        filename,\n+        title=title,\n+        autosave=autosave,\n+        mode=mode,\n+        root_dir=root_dir\n+    )\n+\n+def output_notebook(url=None, docname=None, session=None, name=None):\n+    ''' Configure the default output state to generate output in\n+    Jupyter/IPython notebook cells when :func:`show` is called.\n+\n+    Args:\n+        url (str, optional) : URL of the Bokeh server (default: \"default\")\n+            If \"default\", then ``session.DEFAULT_SERVER_URL`` is used.\n+\n+        docname (str) : Name of document to push on Bokeh server\n+            Any existing documents with the same name will be overwritten.\n+\n+        session (Session, optional) : An explicit session to use (default: None)\n+            If None, a new default session is created.\n+\n+        name (str, optional) : A name for the session\n+            If None, the server URL is used as the name\n+\n+    Returns:\n+        None\n+\n+    '''\n+    _state.output_notebook(\n+        url=url, docname=docname, session=session, name=name\n+    )\n+\n+def output_server(docname, session=None, url=\"default\", name=None, clear=True):\n+    ''' Configure the default output state to generate output that gets\n+    pushed to a bokeh-server when :func:`show` or :func:`push` is called.\n+\n+    Args:\n+        docname (str) : Name of document to push on Bokeh server\n+            Any existing documents with the same name will be overwritten.\n+\n+        session (Session, optional) : An explicit session to use (default: None)\n+            If None, a new default session is created.\n+\n+        url (str, optional) : URL of the Bokeh server (default: \"default\")\n+            If \"default\", then ``session.DEFAULT_SERVER_URL`` is used.\n+\n+        name (str, optional) : A name for the session\n+            If None, the server URL is used as the name\n+\n+        clear (bool, optional) : Whether to clear the document (default: True)\n+            If True, an existing server document will be cleared of any\n+            existing objects.\n+\n+    Returns:\n+        None\n+\n+    '''\n+    _state.output_server(\n+        docname, session=session, url=url, name=name, clear=clear\n+    )\n+\n+\n+def curdoc():\n+    ''' Return the document for the current default state.\n+\n+    Returns:\n+        doc : the current default document object.\n+\n+    .. note::\n+        When using this API form within the server (e.g. in a Bokeh app), the\n+        appropriate document from the request context is returned, rather than\n+        the standard default global state. Doing so allows the same code using\n+        curdoc() to function correctly whether it is being run inside a server\n+        or not.\n+\n+    '''\n+    try:\n+        from flask import request\n+        doc = request.bokeh_server_document\n+        logger.debug(\"curdoc() returning Document from flask request context\")\n+        return doc\n+\n+    except (ImportError, RuntimeError, AttributeError):\n+        return _state.document\n+\n+def cursession():\n+    ''' Return the session for the current default state, if there is one.\n+\n+    Returns:\n+        session : the current default session object (or None)\n+\n+    '''\n+    return _state.session\n+\n+def show(obj, browser=None, new=\"tab\"):\n+    \"\"\" Immediately display a plot object.\n+\n+    In an IPython/Jupyter notebook, the output is displayed in an output\n+    cell. Otherwise, a browser window or tab is autoraised to display the\n+    plot object.\n+\n+    If a both a server session and notebook output have been configured on\n+    the default output state (or an explicitly provided ``State`` object)\n+    then the notebook output will be generated to load the plot from that\n+    server session.\n+\n+    Args:\n+        obj (Widget/Plot object): a plot object to display\n+\n+        browser (str, optional) : browser to show with (default: None)\n+            For systems that support it, the **browser** argument allows\n+            specifying which browser to display in, e.g. \"safari\", \"firefox\",\n+            \"opera\", \"windows-default\" (see the ``webbrowser`` module\n+            documentation in the standard lib for more details).\n+\n+        new (str, optional) : new file output mode (default: \"tab\")\n+            For file-based output, opens or raises the browser window\n+            showing the current output file.  If **new** is 'tab', then\n+            opens a new tab. If **new** is 'window', then opens a new window.\n+\n+    .. note::\n+        The ``browser`` and ``new`` parameters are ignored when showing in\n+        an IPython/Jupyter notebook.\n+\n+    \"\"\"\n+    _show_with_state(obj, _state, browser, new)\n+\n+def _show_with_state(obj, state, browser, new):\n+\n+    controller = browserlib.get_browser_controller(browser=browser)\n+\n+    if state.notebook:\n+        _show_notebook_with_state(obj, state)\n+\n+    elif state.session:\n+        _show_server_with_state(obj, state, new, controller)\n+\n+    if state.file:\n+        _show_file_with_state(obj, state, new, controller)\n+\n+def _show_file_with_state(obj, state, new, controller):\n+    save(obj, state=state)\n+    controller.open(\"file://\" + os.path.abspath(state.file['filename']), new=_new_param[new])\n+\n+def _show_notebook_with_state(obj, state):\n+    if state.session:\n+        push(state=state)\n+        snippet = autoload_server(obj, state.session)\n+        publish_display_data({'text/html': snippet})\n+    else:\n+        publish_display_data({'text/html': notebook_div(obj)})\n+\n+def _show_server_with_state(obj, state, new, controller):\n+    push(state=state)\n+    controller.open(state.session.object_link(state.document.context), new=_new_param[new])\n+\n+def save(obj, filename=None, resources=None, title=None, state=None):\n+    \"\"\" Save an HTML file with the data for the current document.\n+\n+    Will fall back to the default output state (or an explicitly provided\n+    ``State`` object) for ``filename``, ``resources``, or ``title`` if they\n+    are not provided.\n+\n+    Args:\n+        obj (Document or Widget/Plot object)\n+\n+        filename (str, optional) : filename to save document under\n+\n+        resources (Resources, optional) : BokehJS resource config to use\n+\n+        title (str, optional) : title of the bokeh plot\n+\n+    Returns:\n+        None\n+\n+    \"\"\"\n+    if state is None:\n+        state = _state\n+\n+    filename, resources, title = _get_save_args(state, filename, resources, title)\n+\n+    _save_helper(obj, filename, resources, title)\n+\n+def _get_save_args(state, filename, resources, title):\n+\n+    if filename is None and state.file:\n+        filename = state.file['filename']\n+\n+    if resources is None and state.file:\n+        resources = state.file['resources']\n+\n+    if title is None and state.file:\n+        title = state.file['title']\n+\n+    if filename is None:\n+        raise RuntimeError(\"save() called but no filename was supplied and output_file(...) was never called, nothing saved\")","path":"bokeh/state.py","position":488,"original_position":436,"commit_id":"b015fb59b78944c3bf1362bd13b1b2dcc1dd94ee","original_commit_id":"340d4b935d6f2985abfa1b05d57c37a98b84ab10","user":{"login":"damianavila","id":1640669,"avatar_url":"https://avatars.githubusercontent.com/u/1640669?v=3","gravatar_id":"","url":"https://api.github.com/users/damianavila","html_url":"https://github.com/damianavila","followers_url":"https://api.github.com/users/damianavila/followers","following_url":"https://api.github.com/users/damianavila/following{/other_user}","gists_url":"https://api.github.com/users/damianavila/gists{/gist_id}","starred_url":"https://api.github.com/users/damianavila/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/damianavila/subscriptions","organizations_url":"https://api.github.com/users/damianavila/orgs","repos_url":"https://api.github.com/users/damianavila/repos","events_url":"https://api.github.com/users/damianavila/events{/privacy}","received_events_url":"https://api.github.com/users/damianavila/received_events","type":"User","site_admin":false},"body":"ok, fair enough... I missed that issue...","created_at":"2015-02-26T18:24:28Z","updated_at":"2015-02-26T18:24:28Z","html_url":"https://github.com/bokeh/bokeh/pull/1931#discussion_r25450594","pull_request_url":"https://api.github.com/repos/bokeh/bokeh/pulls/1931","_links":{"self":{"href":"https://api.github.com/repos/bokeh/bokeh/pulls/comments/25450594"},"html":{"href":"https://github.com/bokeh/bokeh/pull/1931#discussion_r25450594"},"pull_request":{"href":"https://api.github.com/repos/bokeh/bokeh/pulls/1931"}}},"pull_request":{"url":"https://api.github.com/repos/bokeh/bokeh/pulls/1931","id":29577387,"html_url":"https://github.com/bokeh/bokeh/pull/1931","diff_url":"https://github.com/bokeh/bokeh/pull/1931.diff","patch_url":"https://github.com/bokeh/bokeh/pull/1931.patch","issue_url":"https://api.github.com/repos/bokeh/bokeh/issues/1931","number":1931,"state":"open","locked":false,"title":"encapsulate implicit state","user":{"login":"bryevdv","id":1078448,"avatar_url":"https://avatars.githubusercontent.com/u/1078448?v=3","gravatar_id":"","url":"https://api.github.com/users/bryevdv","html_url":"https://github.com/bryevdv","followers_url":"https://api.github.com/users/bryevdv/followers","following_url":"https://api.github.com/users/bryevdv/following{/other_user}","gists_url":"https://api.github.com/users/bryevdv/gists{/gist_id}","starred_url":"https://api.github.com/users/bryevdv/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bryevdv/subscriptions","organizations_url":"https://api.github.com/users/bryevdv/orgs","repos_url":"https://api.github.com/users/bryevdv/repos","events_url":"https://api.github.com/users/bryevdv/events{/privacy}","received_events_url":"https://api.github.com/users/bryevdv/received_events","type":"User","site_admin":false},"body":"issues: closes #1916","created_at":"2015-02-19T00:26:12Z","updated_at":"2015-02-26T18:24:28Z","closed_at":null,"merged_at":null,"merge_commit_sha":"ae108d6fe32bc2922772898b26eba28593cf5f36","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/bokeh/bokeh/pulls/1931/commits","review_comments_url":"https://api.github.com/repos/bokeh/bokeh/pulls/1931/comments","review_comment_url":"https://api.github.com/repos/bokeh/bokeh/pulls/comments{/number}","comments_url":"https://api.github.com/repos/bokeh/bokeh/issues/1931/comments","statuses_url":"https://api.github.com/repos/bokeh/bokeh/statuses/b015fb59b78944c3bf1362bd13b1b2dcc1dd94ee","head":{"label":"bokeh:task/1916_state","ref":"task/1916_state","sha":"b015fb59b78944c3bf1362bd13b1b2dcc1dd94ee","user":{"login":"bokeh","id":8440965,"avatar_url":"https://avatars.githubusercontent.com/u/8440965?v=3","gravatar_id":"","url":"https://api.github.com/users/bokeh","html_url":"https://github.com/bokeh","followers_url":"https://api.github.com/users/bokeh/followers","following_url":"https://api.github.com/users/bokeh/following{/other_user}","gists_url":"https://api.github.com/users/bokeh/gists{/gist_id}","starred_url":"https://api.github.com/users/bokeh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bokeh/subscriptions","organizations_url":"https://api.github.com/users/bokeh/orgs","repos_url":"https://api.github.com/users/bokeh/repos","events_url":"https://api.github.com/users/bokeh/events{/privacy}","received_events_url":"https://api.github.com/users/bokeh/received_events","type":"Organization","site_admin":false},"repo":{"id":3834332,"name":"bokeh","full_name":"bokeh/bokeh","owner":{"login":"bokeh","id":8440965,"avatar_url":"https://avatars.githubusercontent.com/u/8440965?v=3","gravatar_id":"","url":"https://api.github.com/users/bokeh","html_url":"https://github.com/bokeh","followers_url":"https://api.github.com/users/bokeh/followers","following_url":"https://api.github.com/users/bokeh/following{/other_user}","gists_url":"https://api.github.com/users/bokeh/gists{/gist_id}","starred_url":"https://api.github.com/users/bokeh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bokeh/subscriptions","organizations_url":"https://api.github.com/users/bokeh/orgs","repos_url":"https://api.github.com/users/bokeh/repos","events_url":"https://api.github.com/users/bokeh/events{/privacy}","received_events_url":"https://api.github.com/users/bokeh/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/bokeh/bokeh","description":"Interactive Web Plotting for Python","fork":false,"url":"https://api.github.com/repos/bokeh/bokeh","forks_url":"https://api.github.com/repos/bokeh/bokeh/forks","keys_url":"https://api.github.com/repos/bokeh/bokeh/keys{/key_id}","collaborators_url":"https://api.github.com/repos/bokeh/bokeh/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/bokeh/bokeh/teams","hooks_url":"https://api.github.com/repos/bokeh/bokeh/hooks","issue_events_url":"https://api.github.com/repos/bokeh/bokeh/issues/events{/number}","events_url":"https://api.github.com/repos/bokeh/bokeh/events","assignees_url":"https://api.github.com/repos/bokeh/bokeh/assignees{/user}","branches_url":"https://api.github.com/repos/bokeh/bokeh/branches{/branch}","tags_url":"https://api.github.com/repos/bokeh/bokeh/tags","blobs_url":"https://api.github.com/repos/bokeh/bokeh/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/bokeh/bokeh/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/bokeh/bokeh/git/refs{/sha}","trees_url":"https://api.github.com/repos/bokeh/bokeh/git/trees{/sha}","statuses_url":"https://api.github.com/repos/bokeh/bokeh/statuses/{sha}","languages_url":"https://api.github.com/repos/bokeh/bokeh/languages","stargazers_url":"https://api.github.com/repos/bokeh/bokeh/stargazers","contributors_url":"https://api.github.com/repos/bokeh/bokeh/contributors","subscribers_url":"https://api.github.com/repos/bokeh/bokeh/subscribers","subscription_url":"https://api.github.com/repos/bokeh/bokeh/subscription","commits_url":"https://api.github.com/repos/bokeh/bokeh/commits{/sha}","git_commits_url":"https://api.github.com/repos/bokeh/bokeh/git/commits{/sha}","comments_url":"https://api.github.com/repos/bokeh/bokeh/comments{/number}","issue_comment_url":"https://api.github.com/repos/bokeh/bokeh/issues/comments{/number}","contents_url":"https://api.github.com/repos/bokeh/bokeh/contents/{+path}","compare_url":"https://api.github.com/repos/bokeh/bokeh/compare/{base}...{head}","merges_url":"https://api.github.com/repos/bokeh/bokeh/merges","archive_url":"https://api.github.com/repos/bokeh/bokeh/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/bokeh/bokeh/downloads","issues_url":"https://api.github.com/repos/bokeh/bokeh/issues{/number}","pulls_url":"https://api.github.com/repos/bokeh/bokeh/pulls{/number}","milestones_url":"https://api.github.com/repos/bokeh/bokeh/milestones{/number}","notifications_url":"https://api.github.com/repos/bokeh/bokeh/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/bokeh/bokeh/labels{/name}","releases_url":"https://api.github.com/repos/bokeh/bokeh/releases{/id}","created_at":"2012-03-26T15:40:01Z","updated_at":"2015-02-26T17:40:34Z","pushed_at":"2015-02-26T18:09:39Z","git_url":"git://github.com/bokeh/bokeh.git","ssh_url":"git@github.com:bokeh/bokeh.git","clone_url":"https://github.com/bokeh/bokeh.git","svn_url":"https://github.com/bokeh/bokeh","homepage":"","size":146768,"stargazers_count":2459,"watchers_count":2459,"language":"CoffeeScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":373,"mirror_url":null,"open_issues_count":332,"forks":373,"open_issues":332,"watchers":2459,"default_branch":"master"}},"base":{"label":"bokeh:master","ref":"master","sha":"f180dd5815176d5ebacb8e135da33fe3b405f348","user":{"login":"bokeh","id":8440965,"avatar_url":"https://avatars.githubusercontent.com/u/8440965?v=3","gravatar_id":"","url":"https://api.github.com/users/bokeh","html_url":"https://github.com/bokeh","followers_url":"https://api.github.com/users/bokeh/followers","following_url":"https://api.github.com/users/bokeh/following{/other_user}","gists_url":"https://api.github.com/users/bokeh/gists{/gist_id}","starred_url":"https://api.github.com/users/bokeh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bokeh/subscriptions","organizations_url":"https://api.github.com/users/bokeh/orgs","repos_url":"https://api.github.com/users/bokeh/repos","events_url":"https://api.github.com/users/bokeh/events{/privacy}","received_events_url":"https://api.github.com/users/bokeh/received_events","type":"Organization","site_admin":false},"repo":{"id":3834332,"name":"bokeh","full_name":"bokeh/bokeh","owner":{"login":"bokeh","id":8440965,"avatar_url":"https://avatars.githubusercontent.com/u/8440965?v=3","gravatar_id":"","url":"https://api.github.com/users/bokeh","html_url":"https://github.com/bokeh","followers_url":"https://api.github.com/users/bokeh/followers","following_url":"https://api.github.com/users/bokeh/following{/other_user}","gists_url":"https://api.github.com/users/bokeh/gists{/gist_id}","starred_url":"https://api.github.com/users/bokeh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bokeh/subscriptions","organizations_url":"https://api.github.com/users/bokeh/orgs","repos_url":"https://api.github.com/users/bokeh/repos","events_url":"https://api.github.com/users/bokeh/events{/privacy}","received_events_url":"https://api.github.com/users/bokeh/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/bokeh/bokeh","description":"Interactive Web Plotting for Python","fork":false,"url":"https://api.github.com/repos/bokeh/bokeh","forks_url":"https://api.github.com/repos/bokeh/bokeh/forks","keys_url":"https://api.github.com/repos/bokeh/bokeh/keys{/key_id}","collaborators_url":"https://api.github.com/repos/bokeh/bokeh/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/bokeh/bokeh/teams","hooks_url":"https://api.github.com/repos/bokeh/bokeh/hooks","issue_events_url":"https://api.github.com/repos/bokeh/bokeh/issues/events{/number}","events_url":"https://api.github.com/repos/bokeh/bokeh/events","assignees_url":"https://api.github.com/repos/bokeh/bokeh/assignees{/user}","branches_url":"https://api.github.com/repos/bokeh/bokeh/branches{/branch}","tags_url":"https://api.github.com/repos/bokeh/bokeh/tags","blobs_url":"https://api.github.com/repos/bokeh/bokeh/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/bokeh/bokeh/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/bokeh/bokeh/git/refs{/sha}","trees_url":"https://api.github.com/repos/bokeh/bokeh/git/trees{/sha}","statuses_url":"https://api.github.com/repos/bokeh/bokeh/statuses/{sha}","languages_url":"https://api.github.com/repos/bokeh/bokeh/languages","stargazers_url":"https://api.github.com/repos/bokeh/bokeh/stargazers","contributors_url":"https://api.github.com/repos/bokeh/bokeh/contributors","subscribers_url":"https://api.github.com/repos/bokeh/bokeh/subscribers","subscription_url":"https://api.github.com/repos/bokeh/bokeh/subscription","commits_url":"https://api.github.com/repos/bokeh/bokeh/commits{/sha}","git_commits_url":"https://api.github.com/repos/bokeh/bokeh/git/commits{/sha}","comments_url":"https://api.github.com/repos/bokeh/bokeh/comments{/number}","issue_comment_url":"https://api.github.com/repos/bokeh/bokeh/issues/comments{/number}","contents_url":"https://api.github.com/repos/bokeh/bokeh/contents/{+path}","compare_url":"https://api.github.com/repos/bokeh/bokeh/compare/{base}...{head}","merges_url":"https://api.github.com/repos/bokeh/bokeh/merges","archive_url":"https://api.github.com/repos/bokeh/bokeh/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/bokeh/bokeh/downloads","issues_url":"https://api.github.com/repos/bokeh/bokeh/issues{/number}","pulls_url":"https://api.github.com/repos/bokeh/bokeh/pulls{/number}","milestones_url":"https://api.github.com/repos/bokeh/bokeh/milestones{/number}","notifications_url":"https://api.github.com/repos/bokeh/bokeh/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/bokeh/bokeh/labels{/name}","releases_url":"https://api.github.com/repos/bokeh/bokeh/releases{/id}","created_at":"2012-03-26T15:40:01Z","updated_at":"2015-02-26T17:40:34Z","pushed_at":"2015-02-26T18:09:39Z","git_url":"git://github.com/bokeh/bokeh.git","ssh_url":"git@github.com:bokeh/bokeh.git","clone_url":"https://github.com/bokeh/bokeh.git","svn_url":"https://github.com/bokeh/bokeh","homepage":"","size":146768,"stargazers_count":2459,"watchers_count":2459,"language":"CoffeeScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":373,"mirror_url":null,"open_issues_count":332,"forks":373,"open_issues":332,"watchers":2459,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/bokeh/bokeh/pulls/1931"},"html":{"href":"https://github.com/bokeh/bokeh/pull/1931"},"issue":{"href":"https://api.github.com/repos/bokeh/bokeh/issues/1931"},"comments":{"href":"https://api.github.com/repos/bokeh/bokeh/issues/1931/comments"},"review_comments":{"href":"https://api.github.com/repos/bokeh/bokeh/pulls/1931/comments"},"review_comment":{"href":"https://api.github.com/repos/bokeh/bokeh/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/bokeh/bokeh/pulls/1931/commits"},"statuses":{"href":"https://api.github.com/repos/bokeh/bokeh/statuses/b015fb59b78944c3bf1362bd13b1b2dcc1dd94ee"}}}}