Duplicated state of panel server

I am building a dashboard and serve it with Panel server. It is located in the docker container and it can be accessed by the IP address and port. Somehow, I found that when I accessed the dashboard with two browser tabs at the same time, both dashboards (the panel widgets objects and the values) are mirroring each others.
Is there any explanation when this will be occurred?
FYI, I am using Panel 0.11.3

Thank you in advances.

I think you are using show instead of servable in your code.

Hi @Hoxbro, thank you for your quick response. I am sorry I could not paste my code here. However, at the end of the code, I added template.servable(); where the template is the Panel template that filled with the others pn.GridSpec(), pn.Card(), etc. When I used template.show(), I got a blank page on the browser when I access it with the IP and port.

It is hard to say what the problem is without any code. Try to reduce you code to a minimal reproducible example.

You have to wrap the template in a function.

def get_tmpl():
     template = pn.template.VanillaTemplate()
     #Make stuff......
     return template
get_tmpl().servable()

Each time a new tab is loaded, the bokeh server will give other template object.

I guess you have the template defined globally, but as said by hoxbro, without the code it is imposible to know.

@nghenzi , thank you for your response.
You are right that I defined it globally before. I tried to used it as a function but it does not help.
Somehow, I could not reproduced the events with the simpler code. I also found that they are not completely mirroring because several parts are independent in the original code.

Please let me checked it a bit. If I can see the problem with a simple code, I will report it again.

1 Like

Hi everyone,

Regarding this issue, somehow I could solve it when I copied all of the python classes that I used into one .ipynb and serve only that one file with Panel. However, when I used, for example from dashboard.model.database import DataBase, to provide the DataBase class, the objects in DataBase class become mirroring.

without code it is impossible to provide some hints. A MRE can help to other people to help you and increase the discussion in the forum.

1 Like

I am trying to created a simple project that reproduced my problem.
.
β”œβ”€β”€ ./README.md
β”œβ”€β”€ ./panel_test
β”‚ β”œβ”€β”€ ./panel_test/init.py
β”‚ β”œβ”€β”€ ./panel_test/pycache
β”‚ β”‚ └── ./panel_test/pycache/init.cpython-37.pyc
β”‚ β”œβ”€β”€ ./panel_test/model
β”‚ β”‚ β”œβ”€β”€ ./panel_test/model/init.py
β”‚ β”‚ β”œβ”€β”€ ./panel_test/model/pycache
β”‚ β”‚ β”‚ β”œβ”€β”€ ./panel_test/model/pycache/init.cpython-37.pyc
β”‚ β”‚ β”‚ └── ./panel_test/model/pycache/selector.cpython-37.pyc
β”‚ β”‚ └── ./panel_test/model/selector.py
β”‚ └── ./panel_test/test.ipynb
β”œβ”€β”€ ./panel_test.egg-info
β”‚ β”œβ”€β”€ ./panel_test.egg-info/PKG-INFO
β”‚ β”œβ”€β”€ ./panel_test.egg-info/SOURCES.txt
β”‚ β”œβ”€β”€ ./panel_test.egg-info/dependency_links.txt
β”‚ └── ./panel_test.egg-info/top_level.txt
β”œβ”€β”€ ./requirements.txt
└── ./setup.py

Inside of setup.py is below.

from setuptools import setup, find_packages

setup(
    name='panel_test',
    version='0.0.0',
    license='proprietary',
    description='For test panel',

    author='Arifin',

#     install_requires=[
#         "requests",
#     ],

    packages=[
        'panel_test',
        'panel_test.model',
    ]
)

The inside of ./panel_test/model/selector.py is below.

import panel as pn
import param

STRING_OPTIONS=[β€˜A’, β€˜B’, β€˜C’]

class StringSelections(param.Parameterized):

strings = pn.widgets.RadioBoxGroup()

def __init__(self, **params):
   super().__init__(**params)
   self.strings.options = STRING_OPTIONS
   self.strings.value = STRING_OPTIONS[0]

Then, I used β€œpip install -e /path/to/the/package/” to install the package to my environment.

./panel_test/test.ipynb

import panel as pn
import param

pn.extension()

from panel_test.model import StringSelections

StringSelections().strings.servable();

then, I serve it using panel as below

panel serve --address=β€œ0.0.0.0” --port=8000 --allow-websocket-origin=IP_ADDRESS:PORT /path/to/test.ipynb --autoreload

I accessed the apps through the Chrome 90.0.4430.212. I used 2 tabs and when I change the selections (for example β€˜B’), both tabs will give β€˜B’ selected.

If I copy and paste inside of selector.py into one of the cell in test.ipynb, commented out the import part(# from panel_test.model import StringSelections), reload the server, the selectors in different tabs will not mirroring each other.

Any idea about it?

Thanks.

I think the problem is in selector.py. If you define strings inside the init of the parameterized class it should work, like self.strings =pn.widgets.radiogroup

That definition work for each instance only when it is a param object. In your case the strings defined as a panel object is a class attribute, not an instance attributte.

Edited: below you can find the two solutions I think it should do the work. I think it is not intended to mixture param classes with panel objects. That is, the second option is better…

import panel as pn
import param

STRING_OPTIONS=['A', 'B', 'C']

class StringSelections(param.Parameterized):
    def __init__(self, **params):
       self.strings = pn.widgets.RadioBoxGroup()
       super().__init__(**params)
       self.strings.options = STRING_OPTIONS
       self.strings.value = STRING_OPTIONS[0]

class Strin(param.Parameterized):    
    strings = param.ListSelector(default = STRING_OPTIONS[0],
                                  objects= STRING_OPTIONS)       

pn.Row(StringSelections().strings, 
      pn.Param(Strin(), widgets={'strings':  pn.widgets.RadioBoxGroup})).servable()

2 Likes

Thank you very much @nghenzi. Your solutions work very well for me!

1 Like