{"action":"created","issue":{"url":"https://api.github.com/repos/bokeh/bokeh/issues/3930","repository_url":"https://api.github.com/repos/bokeh/bokeh","labels_url":"https://api.github.com/repos/bokeh/bokeh/issues/3930/labels{/name}","comments_url":"https://api.github.com/repos/bokeh/bokeh/issues/3930/comments","events_url":"https://api.github.com/repos/bokeh/bokeh/issues/3930/events","html_url":"https://github.com/bokeh/bokeh/issues/3930","id":136069302,"number":3930,"title":"Custom Formatter cannot be found if connecting directly with bokeh-client","user":{"login":"the-neworder","id":17453385,"avatar_url":"https://avatars.githubusercontent.com/u/17453385?v=3","gravatar_id":"","url":"https://api.github.com/users/the-neworder","html_url":"https://github.com/the-neworder","followers_url":"https://api.github.com/users/the-neworder/followers","following_url":"https://api.github.com/users/the-neworder/following{/other_user}","gists_url":"https://api.github.com/users/the-neworder/gists{/gist_id}","starred_url":"https://api.github.com/users/the-neworder/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/the-neworder/subscriptions","organizations_url":"https://api.github.com/users/the-neworder/orgs","repos_url":"https://api.github.com/users/the-neworder/repos","events_url":"https://api.github.com/users/the-neworder/events{/privacy}","received_events_url":"https://api.github.com/users/the-neworder/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/bokeh/bokeh/labels/type:%20discussion","name":"type: discussion","color":"2659A0"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":6,"created_at":"2016-02-24T14:00:19Z","updated_at":"2016-02-24T17:31:51Z","closed_at":null,"body":"Hi,\r\n\r\nI'd like to control my plots directly with the bokeh-client (without creating a bokeh app). So I first start the server with:\r\n\r\n`bokeh serve`\r\n\r\nThen I execute [custom_datetime_axis.py](https://github.com/bokeh/bokeh/blob/master/examples/plotting/file/custom_datetime_axis.py) where \r\n`output_file(\"custom_datetime_axis.html\", title=\"custom_datetime_axis.py example\")`\r\nis replaced with:\r\n`output_server(\"custom_datetime_axis.html\")`\r\n\r\nThe execution of **custom_datetime_axis.py** fails with the server side message:\r\n\r\n`File \"/usr/local/lib/python2.7/dist-packages/bokeh/model.py\", line 72, in get_class`\r\n`raise KeyError(\"View model name '%s' not found\" % view_model_name)\r\nKeyError: u\"View model name 'DateGapTickFormatter' not found\"\r\n`\r\n\r\nThe reason why this fails is that only the name of a Formatter is sent to the server. The server then expects to have this Formatter available somewhere which is not the case since its custom and has been created in **custom_datetime_axis.py**.\r\n\r\nBy copy and paste the DateGapTickFormatter class to:\r\n`/usr/local/lib/python2.7/dist-packages/bokeh/models/formatters.py`\r\n\r\nThe example works again. This is however the worst possible solution. Is there any clean way to do this?"},"comment":{"url":"https://api.github.com/repos/bokeh/bokeh/issues/comments/188367984","html_url":"https://github.com/bokeh/bokeh/issues/3930#issuecomment-188367984","issue_url":"https://api.github.com/repos/bokeh/bokeh/issues/3930","id":188367984,"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},"created_at":"2016-02-24T17:31:51Z","updated_at":"2016-02-24T17:31:51Z","body":"> I think the long-term solution to this is to allow first-class third-party extensions, that is, you should be able to install a package that provides both the server-side and client-side for a new model.\r\n\r\nThis is also a great idea. I was trying to imagine pickling or serializing models automatically somehow but this seems much simpler and cleaner. "}}