question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Custom Bokeh Model from documentation raises exception

See original GitHub issue

ALL software version info (bokeh, python, notebook, OS, browser, any other relevant packages)

Bokeh: 1.4.0 Python: 3.7.4 Jupyter: 1.0.0 OS: Windows 8.1 Browser: Chrome

Description of expected behavior and the observed behavior

I’m trying to learn how to create custom bokeh models. I started out trying the Custom model in https://docs.bokeh.org/en/latest/docs/user_guide/extensions.html. But it raises the below exception.

image

Expected: It works without exception Actual: Exception

Complete, minimal, self-contained example code that reproduces the issue

I have the file custom.ipynb

from bokeh.core.properties import Instance, String
from bokeh.io import output_file, show
from bokeh.layouts import column
from bokeh.models import HTMLBox, Slider
class Custom(HTMLBox):

    __implementation__ = "custom.ts"

    text = String(default="Custom text")

    slider = Instance(Slider)


slider = Slider(start=0, end=10, step=0.1, value=0, title="value")

custom = Custom(text="Special Slider Display", slider=slider)

layout = column(slider, custom)
show(layout)

and the file custom.ts in the same folder

import { HTMLBox, HTMLBoxView } from "models/layouts/html_box"

import { div } from "core/dom"
import * as p from "core/properties"

export class CustomView extends HTMLBoxView {

    connect_signals(): void {
        super.connect_signals()

        // Set BokehJS listener so that when the Bokeh slider has a change
        // event, we can process the new data.
        this.connect(this.model.slider.change, () => {
            this.render()
            this.invalidate_layout()
        })
    }

    render(): void {
        // BokehjS Views create <div> elements by default, accessible as
        // ``this.el``. Many Bokeh views ignore this default <div>, and instead
        // do things like draw to the HTML canvas. In this case though, we change
        // the contents of the <div>, based on the current slider value.
        super.render()

        this.el.appendChild(div({
            style: {
                padding: '2px',
                color: '#b88d8e',
                backgroundColor: '#2a3153',
            },
        }, `${this.model.text}: ${this.model.slider.value}`))
    }
}

export class Custom extends HTMLBox {
    slider: { value: string }

    // The ``__name__`` class attribute should generally match exactly the name
    // of the corresponding Python class. Note that if using TypeScript, this
    // will be automatically filled in during compilation, so except in some
    // special cases, this shouldn't be generally included manually, to avoid
    // typos, which would prohibit serialization/deserialization of this model.
    static __name__ = "Custom"

    static init_Custom(): void {
        // If there is an associated view, this is typically boilerplate.
        this.prototype.default_view = CustomView

        // The this.define() block adds corresponding "properties" to the JS model.
        // These should normally line up 1-1 with the Python model class. Most property
        // types have counterparts, e.g. bokeh.core.properties.String will be
        // ``p.String`` in the JS implementation. Any time the JS type system is not
        // yet as complete, you can use ``p.Any`` as a "wildcard" property type.
        this.define<Custom.Props>({
            text: [p.String],
            slider: [p.Any],
        })
    }
}

Stack traceback and/or browser JavaScript console output

Compilation failed:

custom.ts:13:33 - error TS2339: Property 'slider' does not exist on type 'HTMLBox'.

13         this.connect(this.model.slider.change, () => {
                                   ~~~~~~
custom.ts:32:26 - error TS2339: Property 'text' does not exist on type 'HTMLBox'.

32         }, `${this.model.text}: ${this.model.slider.value}`))
                            ~~~~
custom.ts:32:46 - error TS2339: Property 'slider' does not exist on type 'HTMLBox'.

32         }, `${this.model.text}: ${this.model.slider.value}`))
                                                ~~~~~~
custom.ts:55:21 - error TS2702: 'Custom' only refers to a type, but is being used as a namespace here.

55         this.define<Custom.Props>({
                       ~~~~~~
An exception has occurred, use %tb to see the full traceback.

SystemExit: 1

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:14 (12 by maintainers)

github_iconTop GitHub Comments

1reaction
bryevdvcommented, Jan 19, 2020

If this is in the notebook you will need to call output_notebook again after the custom extension is defined. That is what causes the extension definition to exist on the JS side in the notebook.

On Sunday, January 19, 2020, Marc Skov Madsen notifications@github.com wrote:

Hi @mattpap https://github.com/mattpap

Thanks so much for your helpful suggestions. Unfortunately I’ve not been able to get it to work.

I’ve tried to

  • follow your suggestions
  • just experiment with what feels like a thousand combinations
  • looking at most of the Bokeh and Panel .ts model code and trying things out.
  • I’ve changed PlotlyPlot (an error in the Code) to Custom

I’m stuck.

Any help and especially working could would be much appreciated.

(I am from time to time developing applications in Angular/ TypeScript but I only have the most basic understanding of TypeScript so that might also be what makes it a bit difficult for me.)

The current code looks like

import { HTMLBox, HTMLBoxView } from “models/layouts/html_box” import { div } from "core/dom"import * as p from "core/properties"import { Slider } from “models/widgets/slider” export class CustomView extends HTMLBoxView { model: Custom

connect_signals(): void {
    console.info("connect_signals");
    super.connect_signals()

    this.connect(this.model.properties.slider.change, () => {
        console.info("slider change call back");
        this.render();
    })
}

render(): void {
    console.info("render");
    super.render()

    this.el.appendChild(div({
        style: {
            padding: '2px',
            color: '#b88d8e',
            backgroundColor: '#2a3153',
        },
    }, `${this.model.text}: ${this.model.slider.value}`))
}

} export namespace Custom { export type Attrs = p.AttrsOf<Props> export type Props = HTMLBox.Props & { slider: p.Property<Slider> text: p.Property<string> } } export interface Custom extends Custom.Attrs { } export class Custom extends HTMLBox { properties: Custom.Props

constructor(attrs?: Partial<Custom.Attrs>) {
    super(attrs)
}

static init_Custom(): void {
    this.prototype.default_view = CustomView;

    this.define<Custom.Props>({
        text: [p.String],
        slider: [p.Instance],
    })
}

}

If I run the below code via panel serve custom.py I get

[image: image] https://user-images.githubusercontent.com/42288570/72684000-08eaa400-3add-11ea-8029-75dae92c5dd9.png

import panel as pn from bokeh.core.properties import Instance, String from bokeh.io import output_file, show from bokeh.layouts import column from bokeh.models import HTMLBox, Slider from bokeh.util.compiler import TypeScript

pn.extension()

class Custom(HTMLBox):

__implementation__ = TypeScript(code=None, file="custom.ts")

text = String(default="Custom text")

slider = Instance(Slider)

slider = Slider(start=0, end=10, step=0.1, value=0, title=“value”)

custom = Custom(text=“Special Slider Display”, slider=slider)

layout = column(slider, custom)

app = pn.pane.Bokeh(layout) app.servable()

When I run the below code via jupyter notebook custom.ipynb I get

[image: image] https://user-images.githubusercontent.com/42288570/72684099-e907b000-3add-11ea-9ec6-3185cc2816be.png

[image: image] https://user-images.githubusercontent.com/42288570/72684101-ee64fa80-3add-11ea-8c42-c39a72470b94.png

from bokeh.core.properties import Instance, Stringfrom bokeh.io import output_file, showfrom bokeh.util.compiler import TypeScriptfrom bokeh.layouts import columnfrom bokeh.models import HTMLBox, Sliderfrom bokeh.plotting import output_notebook class Custom(HTMLBox):

__implementation__ = TypeScript("", file="custom.ts")

text = String(default="Custom text")

slider = Instance(Slider)

slider = Slider(start=0, end=10, step=0.1, value=0, title=“value”)

custom = Custom(text=“Special Slider Display”, slider=slider)

layout = column(slider, custom) show(layout)

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/bokeh/bokeh/issues/9587?email_source=notifications&email_token=AAIHJMH5QSAONZDWHT2SOJLQ6R3DLA5CNFSM4KIXLJHKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEJKVZZA#issuecomment-576019684, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAIHJMEVJ5XYLXGROFTEKF3Q6R3DLANCNFSM4KIXLJHA .

0reactions
rsdenijscommented, Mar 5, 2021

@bryevdv running the example from docs failed for me in two environments with latest nodejs v14.16.0 with the same error as was posted here. Not in a notebook. Just python file and starting the server with bokeh serve. It does work with the modified version posted. I also tried to build the extension, but that also failed. When I create a directory and simply run bokeh init + bokeh build I get

Working directory: /Users/myuser/projects/bokeh/testbokeh
Using different version of bokeh, rebuilding from scratch.
Running npm install.
npm ERR! code ETARGET
npm ERR! notarget No matching version found for bokehjs@^2.3.0.
npm ERR! notarget In most cases you or one of your dependencies are requesting
npm ERR! notarget a package version that doesn't exist.
npm ERR! notarget
npm ERR! notarget It was specified as a dependency of 'testbokeh'
npm ERR! notarget

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/myuser/.npm/_logs/2021-03-05T06_08_41_268Z-debug.log
npm install failed with exit code 1.
Read more comments on GitHub >

github_iconTop Results From Across the Web

How do I create and use a custom Bokeh Model in Panel?
Hi I'm trying to learn some of the more advanced features of Bokeh/ Panel in order to eventually contribute a PyDeck/ Deck.gl panel....
Read more >
Source code for bokeh.model
[docs]def get_class(view_model_name): ''' Look up a Bokeh model class, ... Raises: KeyError, if the model cannot be found Example: .. code-block:: python ...
Read more >
Bokeh: Models must be owned by only a single document
It may be because of conflicting objects that has the same name. you need to create completely new objects every time.
Read more >
bokeh.model — CAVE 1.4.1 documentation
The only exception made is if one of the models has a custom ... be useful when querying the document to retrieve specific...
Read more >
Classification — pycaret 2.3.5 documentation - Read the Docs
a custom CV generator object compatible with scikit-learn. ... When set to 'ignore', will skip the model with exceptions and continue. If 'raise' ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found