Custom copy tool in bokeh

I am trying to create a copy to clipboard using the new tool and save tool examples provided. This seems to work for the gesture tool but fails for the copy tool as shown here attempting to emulate the examples. This doesn’t display anything in the notebook. I’m looking for pointers on where this code is going wrong and the next steps to explore from the community.

from import Instance
from import output_file, show, output_notebook
from bokeh.models import ColumnDataSource, Tool
from bokeh.plotting import figure
from bokeh.util.compiler import TypeScript


TS_CODE = """
import {ActionTool, ActionToolView} from "models/tools/actions/action_tool"
import * as p from "core/properties"
import {tool_icon_copy_to_clipboard} from "styles/icons.css"

export class CopyToolView extends ActionToolView {
  override model: CopyTool

  async copy(): Promise<void> {
    const blob = await this.plot_view.to_blob()
    const item = new ClipboardItem({[blob.type]: Promise.resolve(blob)})
    await navigator.clipboard.write([item])

  doit(): void {

export namespace CopyTool {
  export type Attrs = p.AttrsOf<Props>

  export type Props = ActionTool.Props

export interface CopyTool extends CopyTool.Attrs {}

export class CopyTool extends ActionTool {
  override properties: CopyTool.Props
  override __view_type__: CopyToolView

  constructor(attrs?: Partial<CopyTool.Attrs>) {

  static {
    this.prototype.default_view = CopyToolView

    this.register_alias("copy", () => new CopyTool())

  override tool_name = "Copy"
  override icon = tool_icon_copy_to_clipboard


class CopyTool(Tool):
    __implementation__ = TypeScript(TS_CODE)

source = ColumnDataSource(data=dict(x=[], y=[]))

plot = figure(x_range=(0, 10), y_range=(0, 10), tools=[CopyTool()])
plot.title.text = "Copy plot to clipboard"
plot.line(range(10), range(10))


Are you calling output_notebook after defining the custom extension? That is what “loads” the custom extension JS definition in to the browser JS runtime.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.