RuntimeError("Models must be owned by only a single document, %r is already in a doc" % (self))

Hi all,
it’s my first time using bokeh and I’m running into some problem that I cannot solve.
I have a file called “main.py” like this:
from main_view import MainView

def main():
    """Entry Point to setup the web interface. """
    mainView = MainView()
    mainView.setup()


main()

and a second file called “main_view.py” like this:

import sys
from bokeh.layouts import row
from bokeh.models import Button, PreText
from bokeh.io import curdoc
from bokeh.models import Panel


class PakTab:

    def __init__(self):
        self.__firstrow = self.__create_first_row()

    def __create_first_row(self):
        inputPakButton = Button(label="Select Pak dir", button_type="success")
        pakdir = inputPakButton.on_click(self.__callback)
        pakdirText = PreText(text=pakdir, width=500, height=100)
        quitButton = Button(label="Quit")
        quitButton.on_click(self.__quitcallback)
        return row(inputPakButton, pakdirText, quitButton)

    def __create_second_row(self):
        pass

    def __callback(self):
        path = 'ciao'
        print(path)
        return path

    def setup_panel(self):
        return Panel(child=self.__firstrow, title="Inputs")

    @staticmethod
    def __quitcallback():
        sys.exit()


class MainView:

    __paktab = PakTab()

    def __init__(self):
        pass

    @classmethod
    def setup(cls):
        pakTabPanel = cls.__paktab.setup_panel()
        cdoc = curdoc()
        cdoc.add_root(pakTabPanel)
        cdoc.title = "Piririr"

but when I try to run bokeh with

bokeh serve main.py

I get:
RuntimeError(“Models must be owned by only a single document, %r is already in a doc” % (self))

could you please tell me what I’m doing wrong? I read around and I don’t see where I’m re-using objects.
Many thanks
Alberto

You are reusing models here:

The code in main.py is run on every new connection to create a new separate Document for that new session. But Python caches module imports, which means the class attribute initialization on MainView inside main_view.py only happens once, so the PakTab initializer creates and stores a bunch of Bokeh models on itself that are effectively just global variables. This is where Bokeh is unhappy. Every time the app code runs, it needs to generate entirely new set of Bokeh objects. (This is a security concern so that different users don’t unintentionally share state or data.)

There’s any number of ways to avoid this, depending on your requirements. The simplest thing is just to to move that inside __init__ and in general, not create “global” Bokeh objects.