We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
undeprecate .from_df
With server apps it is necessary to update `.data` all "at once" so a method to construct a dictionary for `.data` is actually useful and needed. Going to un-deprecate for now, can discuss other ideas for this functionality later. 


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `bokeh/models/sources.py`
Content:
```
1 from __future__ import absolute_import
2 
3 from ..core import validation
4 from ..core.validation.errors import COLUMN_LENGTHS
5 from ..core.properties import abstract
6 from ..core.properties import Any, Int, String, Instance, List, Dict, Bool, Enum, JSON
7 from ..model import Model
8 from ..util.dependencies import import_optional
9 from ..util.deprecate import deprecated
10 from ..util.serialization import transform_column_source_data
11 from .callbacks import Callback
12 
13 pd = import_optional('pandas')
14 
15 @abstract
16 class DataSource(Model):
17     """ A base class for data source types. ``DataSource`` is
18     not generally useful to instantiate on its own.
19 
20     """
21 
22     selected = Dict(String, Dict(String, Any), default={
23         '0d': {'glyph': None, 'indices': []},
24         '1d': {'indices': []},
25         '2d': {'indices': []}
26     }, help="""
27     A dict to indicate selected indices on different dimensions on this DataSource. Keys are:
28 
29     - 0d: indicates whether a Line or Patch glyphs have been hit. Value is a
30             dict with the following keys:
31 
32             - flag (boolean): true if glyph was with false otherwise
33             - indices (list): indices hit (if applicable)
34 
35     - 1d: indicates whether any of all other glyph (except [multi]line or
36             patches) was hit:
37 
38             - indices (list): indices that were hit/selected
39 
40     - 2d: indicates whether a [multi]line or patches) were hit:
41 
42             - indices (list(list)): indices of the lines/patches that were
43                 hit/selected
44     """)
45 
46     callback = Instance(Callback, help="""
47     A callback to run in the browser whenever the selection is changed.
48     """)
49 
50 class ColumnDataSource(DataSource):
51     """ Maps names of columns to sequences or arrays.
52 
53     If the ColumnDataSource initializer is called with a single argument that
54     is a dict or pandas.DataFrame, that argument is used as the value for the
55     "data" attribute. For example::
56 
57         ColumnDataSource(mydict) # same as ColumnDataSource(data=mydict)
58         ColumnDataSource(df) # same as ColumnDataSource(data=df)
59 
60     .. note::
61         There is an implicit assumption that all the columns in a
62         a given ColumnDataSource have the same length.
63 
64     """
65 
66     data = Dict(String, Any, help="""
67     Mapping of column names to sequences of data. The data can be, e.g,
68     Python lists or tuples, NumPy arrays, etc.
69     """)
70 
71     column_names = List(String, help="""
72     An list of names for all the columns in this DataSource.
73     """)
74 
75     def __init__(self, *args, **kw):
76         """ If called with a single argument that is a dict or
77         pandas.DataFrame, treat that implicitly as the "data" attribute.
78         """
79         if len(args) == 1 and "data" not in kw:
80             kw["data"] = args[0]
81         # TODO (bev) invalid to pass args and "data", check and raise exception
82         raw_data = kw.pop("data", {})
83         if not isinstance(raw_data, dict):
84             if pd and isinstance(raw_data, pd.DataFrame):
85                 raw_data = self._data_from_df(raw_data)
86             else:
87                 raise ValueError("expected a dict or pandas.DataFrame, got %s" % raw_data)
88         super(ColumnDataSource, self).__init__(**kw)
89         for name, data in raw_data.items():
90             self.add(data, name)
91 
92     @staticmethod
93     def _data_from_df(df):
94         """ Create a ``dict`` of columns from a Pandas DataFrame,
95         suitable for creating a ColumnDataSource.
96 
97         Args:
98             df (DataFrame) : data to convert
99 
100         Returns:
101             dict(str, list)
102 
103         """
104         index = df.index
105         new_data = {}
106         for colname in df:
107             new_data[colname] = df[colname].tolist()
108         if index.name:
109             new_data[index.name] = index.tolist()
110         elif index.names and not all([x is None for x in index.names]):
111             new_data["_".join(index.names)] = index.tolist()
112         else:
113             new_data["index"] = index.tolist()
114         return new_data
115 
116     @classmethod
117     @deprecated("Bokeh 0.9.3", "ColumnDataSource initializer")
118     def from_df(cls, data):
119         """ Create a ``dict`` of columns from a Pandas DataFrame,
120         suitable for creating a ColumnDataSource.
121 
122         Args:
123             data (DataFrame) : data to convert
124 
125         Returns:
126             dict(str, list)
127 
128         """
129         import warnings
130         warnings.warn("Method deprecated in Bokeh 0.9.3")
131         return cls._data_from_df(data)
132 
133     def to_df(self):
134         """ Convert this data source to pandas dataframe.
135 
136         If ``column_names`` is set, use those. Otherwise let Pandas
137         infer the column names. The ``column_names`` property can be
138         used both to order and filter the columns.
139 
140         Returns:
141             DataFrame
142 
143         """
144         if not pd:
145             raise RuntimeError('Pandas must be installed to convert to a Pandas Dataframe')
146         if self.column_names:
147             return pd.DataFrame(self.data, columns=self.column_names)
148         else:
149             return pd.DataFrame(self.data)
150 
151     def add(self, data, name=None):
152         """ Appends a new column of data to the data source.
153 
154         Args:
155             data (seq) : new data to add
156             name (str, optional) : column name to use.
157                 If not supplied, generate a name go the form "Series ####"
158 
159         Returns:
160             str:  the column name used
161 
162         """
163         if name is None:
164             n = len(self.data)
165             while "Series %d"%n in self.data:
166                 n += 1
167             name = "Series %d"%n
168         self.column_names.append(name)
169         self.data[name] = data
170         return name
171 
172     def _to_json_like(self, include_defaults):
173         attrs = super(ColumnDataSource, self)._to_json_like(include_defaults=include_defaults)
174         if 'data' in attrs:
175             attrs['data'] = transform_column_source_data(attrs['data'])
176         return attrs
177 
178     def remove(self, name):
179         """ Remove a column of data.
180 
181         Args:
182             name (str) : name of the column to remove
183 
184         Returns:
185             None
186 
187         .. note::
188             If the column name does not exist, a warning is issued.
189 
190         """
191         try:
192             self.column_names.remove(name)
193             del self.data[name]
194         except (ValueError, KeyError):
195             import warnings
196             warnings.warn("Unable to find column '%s' in data source" % name)
197 
198     @deprecated("Bokeh 0.11.0", "bokeh.io.push_notebook")
199     def push_notebook(self):
200         """ Update a data source for a plot in a Jupyter notebook.
201 
202         This function can be be used to update data in plot data sources
203         in the Jupyter notebook, without having to use the Bokeh server.
204 
205         .. warning::
206             This function has been deprecated. Please use
207             ``bokeh.io.push_notebook()`` which will push all changes
208             (not just data sources) to the last shown plot in a Jupyter
209             notebook.
210 
211         Returns:
212             None
213 
214         """
215         from bokeh.io import push_notebook
216         push_notebook()
217 
218     @validation.error(COLUMN_LENGTHS)
219     def _check_column_lengths(self):
220         lengths = set(len(x) for x in self.data.values())
221         if len(lengths) > 1:
222             return str(self)
223 
224 
225     def stream(self, new_data, rollover=None):
226         import numpy as np
227 
228         newkeys = set(new_data.keys())
229         oldkeys = set(self.data.keys())
230         if newkeys != oldkeys:
231             missing = oldkeys - newkeys
232             extra = newkeys - oldkeys
233             if missing and extra:
234                 raise ValueError("Must stream updates to all existing columns (missing: %s, extra: %s)" % (", ".join(sorted(missing)), ", ".join(sorted(extra))))
235             elif missing:
236                 raise ValueError("Must stream updates to all existing columns (missing: %s)" % ", ".join(sorted(missing)))
237             else:
238                 raise ValueError("Must stream updates to all existing columns (extra: %s)" % ", ".join(sorted(extra)))
239 
240         lengths = set()
241         for x in new_data.values():
242             if isinstance(x, np.ndarray):
243                 if len(x.shape) != 1:
244                     raise ValueError("stream(...) only supports 1d sequences, got ndarray with size %r" % (x.shape,))
245                 lengths.add(x.shape[0])
246             else:
247                 lengths.add(len(x))
248 
249         if len(lengths) > 1:
250             raise ValueError("All streaming column updates must be the same length")
251 
252         self.data._stream(self.document, self, new_data, rollover)
253 
254 class GeoJSONDataSource(ColumnDataSource):
255 
256     geojson = JSON(help="""
257     GeoJSON that contains features for plotting. Currently GeoJSONDataSource can
258     only process a FeatureCollection or GeometryCollection.
259     """)
260 
261 
262 @abstract
263 class RemoteSource(ColumnDataSource):
264 
265     data_url = String(help="""
266     The URL to the endpoint for the data.
267     """)
268 
269     polling_interval = Int(help="""
270     polling interval for updating data source in milliseconds
271     """)
272 
273 class AjaxDataSource(RemoteSource):
274 
275     method = Enum('POST', 'GET', help="http method - GET or POST")
276 
277     mode = Enum("replace", "append", help="""
278     Whether to append new data to existing data (up to ``max_size``),
279     or to replace existing data entirely.
280     """)
281 
282     max_size = Int(help="""
283     Maximum size of the data array being kept after each pull requests.
284     Larger than that size, the data will be right shifted.
285     """)
286 
287     if_modified = Bool(False, help="""
288     Whether to include an ``If-Modified-Since`` header in AJAX requests
289     to the server. If this header is supported by the server, then only
290     new data since the last request will be returned.
291     """)
292     content_type = String(default='application/json', help="""
293     Set the "contentType" parameter for the Ajax request.
294     """)
295     http_headers = Dict(String, String, help="""
296     HTTP headers to set for the Ajax request.
297     """)
298
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/bokeh/models/sources.py b/bokeh/models/sources.py
--- a/bokeh/models/sources.py
+++ b/bokeh/models/sources.py
@@ -114,7 +114,6 @@
         return new_data
 
     @classmethod
-    @deprecated("Bokeh 0.9.3", "ColumnDataSource initializer")
     def from_df(cls, data):
         """ Create a ``dict`` of columns from a Pandas DataFrame,
         suitable for creating a ColumnDataSource.
@@ -126,8 +125,6 @@
             dict(str, list)
 
         """
-        import warnings
-        warnings.warn("Method deprecated in Bokeh 0.9.3")
         return cls._data_from_df(data)
 
     def to_df(self):

{"golden_diff": "diff --git a/bokeh/models/sources.py b/bokeh/models/sources.py\n--- a/bokeh/models/sources.py\n+++ b/bokeh/models/sources.py\n@@ -114,7 +114,6 @@\n         return new_data\n \n     @classmethod\n-    @deprecated(\"Bokeh 0.9.3\", \"ColumnDataSource initializer\")\n     def from_df(cls, data):\n         \"\"\" Create a ``dict`` of columns from a Pandas DataFrame,\n         suitable for creating a ColumnDataSource.\n@@ -126,8 +125,6 @@\n             dict(str, list)\n \n         \"\"\"\n-        import warnings\n-        warnings.warn(\"Method deprecated in Bokeh 0.9.3\")\n         return cls._data_from_df(data)\n \n     def to_df(self):\n", "issue": "undeprecate .from_df\nWith server apps it is necessary to update `.data` all \"at once\" so a method to construct a dictionary for `.data` is actually useful and needed. Going to un-deprecate for now, can discuss other ideas for this functionality later. \n\n", "before_files": [{"content": "from __future__ import absolute_import\n\nfrom ..core import validation\nfrom ..core.validation.errors import COLUMN_LENGTHS\nfrom ..core.properties import abstract\nfrom ..core.properties import Any, Int, String, Instance, List, Dict, Bool, Enum, JSON\nfrom ..model import Model\nfrom ..util.dependencies import import_optional\nfrom ..util.deprecate import deprecated\nfrom ..util.serialization import transform_column_source_data\nfrom .callbacks import Callback\n\npd = import_optional('pandas')\n\n@abstract\nclass DataSource(Model):\n    \"\"\" A base class for data source types. ``DataSource`` is\n    not generally useful to instantiate on its own.\n\n    \"\"\"\n\n    selected = Dict(String, Dict(String, Any), default={\n        '0d': {'glyph': None, 'indices': []},\n        '1d': {'indices': []},\n        '2d': {'indices': []}\n    }, help=\"\"\"\n    A dict to indicate selected indices on different dimensions on this DataSource. Keys are:\n\n    - 0d: indicates whether a Line or Patch glyphs have been hit. Value is a\n            dict with the following keys:\n\n            - flag (boolean): true if glyph was with false otherwise\n            - indices (list): indices hit (if applicable)\n\n    - 1d: indicates whether any of all other glyph (except [multi]line or\n            patches) was hit:\n\n            - indices (list): indices that were hit/selected\n\n    - 2d: indicates whether a [multi]line or patches) were hit:\n\n            - indices (list(list)): indices of the lines/patches that were\n                hit/selected\n    \"\"\")\n\n    callback = Instance(Callback, help=\"\"\"\n    A callback to run in the browser whenever the selection is changed.\n    \"\"\")\n\nclass ColumnDataSource(DataSource):\n    \"\"\" Maps names of columns to sequences or arrays.\n\n    If the ColumnDataSource initializer is called with a single argument that\n    is a dict or pandas.DataFrame, that argument is used as the value for the\n    \"data\" attribute. For example::\n\n        ColumnDataSource(mydict) # same as ColumnDataSource(data=mydict)\n        ColumnDataSource(df) # same as ColumnDataSource(data=df)\n\n    .. note::\n        There is an implicit assumption that all the columns in a\n        a given ColumnDataSource have the same length.\n\n    \"\"\"\n\n    data = Dict(String, Any, help=\"\"\"\n    Mapping of column names to sequences of data. The data can be, e.g,\n    Python lists or tuples, NumPy arrays, etc.\n    \"\"\")\n\n    column_names = List(String, help=\"\"\"\n    An list of names for all the columns in this DataSource.\n    \"\"\")\n\n    def __init__(self, *args, **kw):\n        \"\"\" If called with a single argument that is a dict or\n        pandas.DataFrame, treat that implicitly as the \"data\" attribute.\n        \"\"\"\n        if len(args) == 1 and \"data\" not in kw:\n            kw[\"data\"] = args[0]\n        # TODO (bev) invalid to pass args and \"data\", check and raise exception\n        raw_data = kw.pop(\"data\", {})\n        if not isinstance(raw_data, dict):\n            if pd and isinstance(raw_data, pd.DataFrame):\n                raw_data = self._data_from_df(raw_data)\n            else:\n                raise ValueError(\"expected a dict or pandas.DataFrame, got %s\" % raw_data)\n        super(ColumnDataSource, self).__init__(**kw)\n        for name, data in raw_data.items():\n            self.add(data, name)\n\n    @staticmethod\n    def _data_from_df(df):\n        \"\"\" Create a ``dict`` of columns from a Pandas DataFrame,\n        suitable for creating a ColumnDataSource.\n\n        Args:\n            df (DataFrame) : data to convert\n\n        Returns:\n            dict(str, list)\n\n        \"\"\"\n        index = df.index\n        new_data = {}\n        for colname in df:\n            new_data[colname] = df[colname].tolist()\n        if index.name:\n            new_data[index.name] = index.tolist()\n        elif index.names and not all([x is None for x in index.names]):\n            new_data[\"_\".join(index.names)] = index.tolist()\n        else:\n            new_data[\"index\"] = index.tolist()\n        return new_data\n\n    @classmethod\n    @deprecated(\"Bokeh 0.9.3\", \"ColumnDataSource initializer\")\n    def from_df(cls, data):\n        \"\"\" Create a ``dict`` of columns from a Pandas DataFrame,\n        suitable for creating a ColumnDataSource.\n\n        Args:\n            data (DataFrame) : data to convert\n\n        Returns:\n            dict(str, list)\n\n        \"\"\"\n        import warnings\n        warnings.warn(\"Method deprecated in Bokeh 0.9.3\")\n        return cls._data_from_df(data)\n\n    def to_df(self):\n        \"\"\" Convert this data source to pandas dataframe.\n\n        If ``column_names`` is set, use those. Otherwise let Pandas\n        infer the column names. The ``column_names`` property can be\n        used both to order and filter the columns.\n\n        Returns:\n            DataFrame\n\n        \"\"\"\n        if not pd:\n            raise RuntimeError('Pandas must be installed to convert to a Pandas Dataframe')\n        if self.column_names:\n            return pd.DataFrame(self.data, columns=self.column_names)\n        else:\n            return pd.DataFrame(self.data)\n\n    def add(self, data, name=None):\n        \"\"\" Appends a new column of data to the data source.\n\n        Args:\n            data (seq) : new data to add\n            name (str, optional) : column name to use.\n                If not supplied, generate a name go the form \"Series ####\"\n\n        Returns:\n            str:  the column name used\n\n        \"\"\"\n        if name is None:\n            n = len(self.data)\n            while \"Series %d\"%n in self.data:\n                n += 1\n            name = \"Series %d\"%n\n        self.column_names.append(name)\n        self.data[name] = data\n        return name\n\n    def _to_json_like(self, include_defaults):\n        attrs = super(ColumnDataSource, self)._to_json_like(include_defaults=include_defaults)\n        if 'data' in attrs:\n            attrs['data'] = transform_column_source_data(attrs['data'])\n        return attrs\n\n    def remove(self, name):\n        \"\"\" Remove a column of data.\n\n        Args:\n            name (str) : name of the column to remove\n\n        Returns:\n            None\n\n        .. note::\n            If the column name does not exist, a warning is issued.\n\n        \"\"\"\n        try:\n            self.column_names.remove(name)\n            del self.data[name]\n        except (ValueError, KeyError):\n            import warnings\n            warnings.warn(\"Unable to find column '%s' in data source\" % name)\n\n    @deprecated(\"Bokeh 0.11.0\", \"bokeh.io.push_notebook\")\n    def push_notebook(self):\n        \"\"\" Update a data source for a plot in a Jupyter notebook.\n\n        This function can be be used to update data in plot data sources\n        in the Jupyter notebook, without having to use the Bokeh server.\n\n        .. warning::\n            This function has been deprecated. Please use\n            ``bokeh.io.push_notebook()`` which will push all changes\n            (not just data sources) to the last shown plot in a Jupyter\n            notebook.\n\n        Returns:\n            None\n\n        \"\"\"\n        from bokeh.io import push_notebook\n        push_notebook()\n\n    @validation.error(COLUMN_LENGTHS)\n    def _check_column_lengths(self):\n        lengths = set(len(x) for x in self.data.values())\n        if len(lengths) > 1:\n            return str(self)\n\n\n    def stream(self, new_data, rollover=None):\n        import numpy as np\n\n        newkeys = set(new_data.keys())\n        oldkeys = set(self.data.keys())\n        if newkeys != oldkeys:\n            missing = oldkeys - newkeys\n            extra = newkeys - oldkeys\n            if missing and extra:\n                raise ValueError(\"Must stream updates to all existing columns (missing: %s, extra: %s)\" % (\", \".join(sorted(missing)), \", \".join(sorted(extra))))\n            elif missing:\n                raise ValueError(\"Must stream updates to all existing columns (missing: %s)\" % \", \".join(sorted(missing)))\n            else:\n                raise ValueError(\"Must stream updates to all existing columns (extra: %s)\" % \", \".join(sorted(extra)))\n\n        lengths = set()\n        for x in new_data.values():\n            if isinstance(x, np.ndarray):\n                if len(x.shape) != 1:\n                    raise ValueError(\"stream(...) only supports 1d sequences, got ndarray with size %r\" % (x.shape,))\n                lengths.add(x.shape[0])\n            else:\n                lengths.add(len(x))\n\n        if len(lengths) > 1:\n            raise ValueError(\"All streaming column updates must be the same length\")\n\n        self.data._stream(self.document, self, new_data, rollover)\n\nclass GeoJSONDataSource(ColumnDataSource):\n\n    geojson = JSON(help=\"\"\"\n    GeoJSON that contains features for plotting. Currently GeoJSONDataSource can\n    only process a FeatureCollection or GeometryCollection.\n    \"\"\")\n\n\n@abstract\nclass RemoteSource(ColumnDataSource):\n\n    data_url = String(help=\"\"\"\n    The URL to the endpoint for the data.\n    \"\"\")\n\n    polling_interval = Int(help=\"\"\"\n    polling interval for updating data source in milliseconds\n    \"\"\")\n\nclass AjaxDataSource(RemoteSource):\n\n    method = Enum('POST', 'GET', help=\"http method - GET or POST\")\n\n    mode = Enum(\"replace\", \"append\", help=\"\"\"\n    Whether to append new data to existing data (up to ``max_size``),\n    or to replace existing data entirely.\n    \"\"\")\n\n    max_size = Int(help=\"\"\"\n    Maximum size of the data array being kept after each pull requests.\n    Larger than that size, the data will be right shifted.\n    \"\"\")\n\n    if_modified = Bool(False, help=\"\"\"\n    Whether to include an ``If-Modified-Since`` header in AJAX requests\n    to the server. If this header is supported by the server, then only\n    new data since the last request will be returned.\n    \"\"\")\n    content_type = String(default='application/json', help=\"\"\"\n    Set the \"contentType\" parameter for the Ajax request.\n    \"\"\")\n    http_headers = Dict(String, String, help=\"\"\"\n    HTTP headers to set for the Ajax request.\n    \"\"\")\n", "path": "bokeh/models/sources.py"}], "after_files": [{"content": "from __future__ import absolute_import\n\nfrom ..core import validation\nfrom ..core.validation.errors import COLUMN_LENGTHS\nfrom ..core.properties import abstract\nfrom ..core.properties import Any, Int, String, Instance, List, Dict, Bool, Enum, JSON\nfrom ..model import Model\nfrom ..util.dependencies import import_optional\nfrom ..util.deprecate import deprecated\nfrom ..util.serialization import transform_column_source_data\nfrom .callbacks import Callback\n\npd = import_optional('pandas')\n\n@abstract\nclass DataSource(Model):\n    \"\"\" A base class for data source types. ``DataSource`` is\n    not generally useful to instantiate on its own.\n\n    \"\"\"\n\n    selected = Dict(String, Dict(String, Any), default={\n        '0d': {'glyph': None, 'indices': []},\n        '1d': {'indices': []},\n        '2d': {'indices': []}\n    }, help=\"\"\"\n    A dict to indicate selected indices on different dimensions on this DataSource. Keys are:\n\n    - 0d: indicates whether a Line or Patch glyphs have been hit. Value is a\n            dict with the following keys:\n\n            - flag (boolean): true if glyph was with false otherwise\n            - indices (list): indices hit (if applicable)\n\n    - 1d: indicates whether any of all other glyph (except [multi]line or\n            patches) was hit:\n\n            - indices (list): indices that were hit/selected\n\n    - 2d: indicates whether a [multi]line or patches) were hit:\n\n            - indices (list(list)): indices of the lines/patches that were\n                hit/selected\n    \"\"\")\n\n    callback = Instance(Callback, help=\"\"\"\n    A callback to run in the browser whenever the selection is changed.\n    \"\"\")\n\nclass ColumnDataSource(DataSource):\n    \"\"\" Maps names of columns to sequences or arrays.\n\n    If the ColumnDataSource initializer is called with a single argument that\n    is a dict or pandas.DataFrame, that argument is used as the value for the\n    \"data\" attribute. For example::\n\n        ColumnDataSource(mydict) # same as ColumnDataSource(data=mydict)\n        ColumnDataSource(df) # same as ColumnDataSource(data=df)\n\n    .. note::\n        There is an implicit assumption that all the columns in a\n        a given ColumnDataSource have the same length.\n\n    \"\"\"\n\n    data = Dict(String, Any, help=\"\"\"\n    Mapping of column names to sequences of data. The data can be, e.g,\n    Python lists or tuples, NumPy arrays, etc.\n    \"\"\")\n\n    column_names = List(String, help=\"\"\"\n    An list of names for all the columns in this DataSource.\n    \"\"\")\n\n    def __init__(self, *args, **kw):\n        \"\"\" If called with a single argument that is a dict or\n        pandas.DataFrame, treat that implicitly as the \"data\" attribute.\n        \"\"\"\n        if len(args) == 1 and \"data\" not in kw:\n            kw[\"data\"] = args[0]\n        # TODO (bev) invalid to pass args and \"data\", check and raise exception\n        raw_data = kw.pop(\"data\", {})\n        if not isinstance(raw_data, dict):\n            if pd and isinstance(raw_data, pd.DataFrame):\n                raw_data = self._data_from_df(raw_data)\n            else:\n                raise ValueError(\"expected a dict or pandas.DataFrame, got %s\" % raw_data)\n        super(ColumnDataSource, self).__init__(**kw)\n        for name, data in raw_data.items():\n            self.add(data, name)\n\n    @staticmethod\n    def _data_from_df(df):\n        \"\"\" Create a ``dict`` of columns from a Pandas DataFrame,\n        suitable for creating a ColumnDataSource.\n\n        Args:\n            df (DataFrame) : data to convert\n\n        Returns:\n            dict(str, list)\n\n        \"\"\"\n        index = df.index\n        new_data = {}\n        for colname in df:\n            new_data[colname] = df[colname].tolist()\n        if index.name:\n            new_data[index.name] = index.tolist()\n        elif index.names and not all([x is None for x in index.names]):\n            new_data[\"_\".join(index.names)] = index.tolist()\n        else:\n            new_data[\"index\"] = index.tolist()\n        return new_data\n\n    @classmethod\n    def from_df(cls, data):\n        \"\"\" Create a ``dict`` of columns from a Pandas DataFrame,\n        suitable for creating a ColumnDataSource.\n\n        Args:\n            data (DataFrame) : data to convert\n\n        Returns:\n            dict(str, list)\n\n        \"\"\"\n        return cls._data_from_df(data)\n\n    def to_df(self):\n        \"\"\" Convert this data source to pandas dataframe.\n\n        If ``column_names`` is set, use those. Otherwise let Pandas\n        infer the column names. The ``column_names`` property can be\n        used both to order and filter the columns.\n\n        Returns:\n            DataFrame\n\n        \"\"\"\n        if not pd:\n            raise RuntimeError('Pandas must be installed to convert to a Pandas Dataframe')\n        if self.column_names:\n            return pd.DataFrame(self.data, columns=self.column_names)\n        else:\n            return pd.DataFrame(self.data)\n\n    def add(self, data, name=None):\n        \"\"\" Appends a new column of data to the data source.\n\n        Args:\n            data (seq) : new data to add\n            name (str, optional) : column name to use.\n                If not supplied, generate a name go the form \"Series ####\"\n\n        Returns:\n            str:  the column name used\n\n        \"\"\"\n        if name is None:\n            n = len(self.data)\n            while \"Series %d\"%n in self.data:\n                n += 1\n            name = \"Series %d\"%n\n        self.column_names.append(name)\n        self.data[name] = data\n        return name\n\n    def _to_json_like(self, include_defaults):\n        attrs = super(ColumnDataSource, self)._to_json_like(include_defaults=include_defaults)\n        if 'data' in attrs:\n            attrs['data'] = transform_column_source_data(attrs['data'])\n        return attrs\n\n    def remove(self, name):\n        \"\"\" Remove a column of data.\n\n        Args:\n            name (str) : name of the column to remove\n\n        Returns:\n            None\n\n        .. note::\n            If the column name does not exist, a warning is issued.\n\n        \"\"\"\n        try:\n            self.column_names.remove(name)\n            del self.data[name]\n        except (ValueError, KeyError):\n            import warnings\n            warnings.warn(\"Unable to find column '%s' in data source\" % name)\n\n    @deprecated(\"Bokeh 0.11.0\", \"bokeh.io.push_notebook\")\n    def push_notebook(self):\n        \"\"\" Update a data source for a plot in a Jupyter notebook.\n\n        This function can be be used to update data in plot data sources\n        in the Jupyter notebook, without having to use the Bokeh server.\n\n        .. warning::\n            This function has been deprecated. Please use\n            ``bokeh.io.push_notebook()`` which will push all changes\n            (not just data sources) to the last shown plot in a Jupyter\n            notebook.\n\n        Returns:\n            None\n\n        \"\"\"\n        from bokeh.io import push_notebook\n        push_notebook()\n\n    @validation.error(COLUMN_LENGTHS)\n    def _check_column_lengths(self):\n        lengths = set(len(x) for x in self.data.values())\n        if len(lengths) > 1:\n            return str(self)\n\n\n    def stream(self, new_data, rollover=None):\n        import numpy as np\n\n        newkeys = set(new_data.keys())\n        oldkeys = set(self.data.keys())\n        if newkeys != oldkeys:\n            missing = oldkeys - newkeys\n            extra = newkeys - oldkeys\n            if missing and extra:\n                raise ValueError(\"Must stream updates to all existing columns (missing: %s, extra: %s)\" % (\", \".join(sorted(missing)), \", \".join(sorted(extra))))\n            elif missing:\n                raise ValueError(\"Must stream updates to all existing columns (missing: %s)\" % \", \".join(sorted(missing)))\n            else:\n                raise ValueError(\"Must stream updates to all existing columns (extra: %s)\" % \", \".join(sorted(extra)))\n\n        lengths = set()\n        for x in new_data.values():\n            if isinstance(x, np.ndarray):\n                if len(x.shape) != 1:\n                    raise ValueError(\"stream(...) only supports 1d sequences, got ndarray with size %r\" % (x.shape,))\n                lengths.add(x.shape[0])\n            else:\n                lengths.add(len(x))\n\n        if len(lengths) > 1:\n            raise ValueError(\"All streaming column updates must be the same length\")\n\n        self.data._stream(self.document, self, new_data, rollover)\n\nclass GeoJSONDataSource(ColumnDataSource):\n\n    geojson = JSON(help=\"\"\"\n    GeoJSON that contains features for plotting. Currently GeoJSONDataSource can\n    only process a FeatureCollection or GeometryCollection.\n    \"\"\")\n\n\n@abstract\nclass RemoteSource(ColumnDataSource):\n\n    data_url = String(help=\"\"\"\n    The URL to the endpoint for the data.\n    \"\"\")\n\n    polling_interval = Int(help=\"\"\"\n    polling interval for updating data source in milliseconds\n    \"\"\")\n\nclass AjaxDataSource(RemoteSource):\n\n    method = Enum('POST', 'GET', help=\"http method - GET or POST\")\n\n    mode = Enum(\"replace\", \"append\", help=\"\"\"\n    Whether to append new data to existing data (up to ``max_size``),\n    or to replace existing data entirely.\n    \"\"\")\n\n    max_size = Int(help=\"\"\"\n    Maximum size of the data array being kept after each pull requests.\n    Larger than that size, the data will be right shifted.\n    \"\"\")\n\n    if_modified = Bool(False, help=\"\"\"\n    Whether to include an ``If-Modified-Since`` header in AJAX requests\n    to the server. If this header is supported by the server, then only\n    new data since the last request will be returned.\n    \"\"\")\n    content_type = String(default='application/json', help=\"\"\"\n    Set the \"contentType\" parameter for the Ajax request.\n    \"\"\")\n    http_headers = Dict(String, String, help=\"\"\"\n    HTTP headers to set for the Ajax request.\n    \"\"\")\n", "path": "bokeh/models/sources.py"}]}