Passing selections from drop-down lists to callable functions

Hi

I am new to Anvil and Python, so apologies if this question is too basic or obvious. I have spent hours getting nowhere with this and would be very grateful for any pointers.

I am building a web app to visualise the results of machine learning experiments with Plotly. I would like to set some of the Plotly parameters, such as colour categories for the scatter plot points, from drop-down lists. The Plotly scatter plot is defined on the server.

On the client-side for the drop-down list I have:

  def classes_dd_change(self, **event_args):
        anvil.server.call('select_classes', self.classes_dd.selected_value)

And on the server-side I have:

@anvil.server.callable
def select_classes(classes):
    if classes == "choice_A":
        colour_cats = 'exp_A'   # where 'exp_A' is a column in a dataframe
    elif classes == "choice_B":
        colour_cats = 'exp_B'   # where 'exp_B' is a column in a dataframe
    return colour_cats   
colour_cats = select_classes(classes) # Error here

@anvil.server.callable
def create_plot():
   fig = px.scatter(...
      color=color_cats,...

This returns “NameError: name ‘classes’ is not defined”.

Many thanks in advance for any guidance.

SC

Welcome to the forum!

That line and the select_classes function aren’t needed. It looks like you’re trying to set some variable for create_plot to use later, but that isn’t the way server functions work in Anvil. You need to pass all the information needed for a function into it, so you’d need to pass the classes into create_plot from the client.

Let’s say you have a button to generate the plot on the client. That button should call create_plot on the server, passing in self.classes_dd.selected_value.

The background for why is that Anvil server functions don’t run in a persistent environment. Every server call spins up a new Python environment that doesn’t share anything from old server calls.

Many thanks. That is very useful, and I think it explains why my attempted solutions outside of Anvil (i.e. with Pycharm) got me know where. I will try what you suggest, and rethink how I divide tasks between the client and server.
SC

1 Like

Note that this line is indented the same as

so it is outside of the function. That means that this line will be executed, just like the def statement, when Anvil loads the Server Module. At that point in time, the function select_classes has just been defined (by executing its def statement; function create_plot has yet to be defined (because its def statement has not yet been executed); and odds are that this Server Module has no name classes defined. So when the Server Module tries to execute

colour_cats = select_classes(classes)

it can’t find a value for classes, to pass to select_classes, because classes itself is not defined.

Does this make sense?

Many thanks. It is beginning to make sense. Both answers have been very helpful. I think it may also be easier if I put the plot on the client-side and just call the server to pull over data and images.