Button Help Malfunction

I have been struggling to make this button work for my data analyze website. client code below

from anvil import *
import anvil.server
import plotly.graph_objects as go
from ._anvil_designer import Form1Template
class Form1(Form1Template):
    def __init__(self, **properties):
        # Initialize the form and set up variables
        self.init_components(**properties)
        self.columns = None  # To store column names from the dataset
        print("Form initialized.")  # Debugging

    def file_loader_1_change(self, file, **event_args):
        """Triggered when a file is uploaded."""
        if file:
            try:
                # Call the server to process the file and retrieve column names
                self.columns = anvil.server.call('process_file', file)
                alert("Dataset uploaded successfully!", title="Success")
                print(f"Columns in dataset: {self.columns}")  # Debugging
            except Exception as e:
                alert(f"Error uploading dataset: {e}", title="Error")
                print(f"Error: {e}")  # Debugging

    def analyze_button_click(self, **event_args):
        """Analyze a specific row of the dataset."""
        print("Analyze button clicked!")  # Debugging
        alert("Analyze button clicked!", title="Debug")
        
        if not self.columns:
            alert("Please upload a dataset first.", title="Error")
            return

        row_index = input("Enter the row index to analyze:")
        if not row_index.isdigit():
            alert("Invalid row index. Please enter a valid integer.", title="Error")
            return

        try:
            row_index = int(row_index)
            row_data = anvil.server.call('get_row_data', row_index)
            print(f"Row data: {row_data}")  # Debugging
            message = "\n".join([f"{col}: {value}" for col, value in zip(self.columns, row_data)])
            alert(message, title=f"Data for Row {row_index}")
        except Exception as e:
            alert(f"Error analyzing row: {e}", title="Error")
            print(f"Error: {e}")  # Debugging

    def display_button_click(self, **event_args):
        """Compare two variables visually."""
        print("Display button clicked!")  # Debugging
        alert("Display button clicked!", title="Debug")
        
        if not self.columns:
            alert("Please upload a dataset first.", title="Error")
            return

        var1 = input(f"Enter the first variable to compare ({', '.join(self.columns)}):")
        var2 = input(f"Enter the second variable to compare ({', '.join(self.columns)}):")
        if var1 not in self.columns or var2 not in self.columns:
            alert("Invalid column names. Please choose from the available columns.", title="Error")
            return

        try:
            plot_data = anvil.server.call('get_comparison_data', var1, var2)
            print(f"Plot data received: {plot_data}")  # Debugging
            fig = go.Figure(data=go.Scatter(x=plot_data["x"], y=plot_data["y"], mode="markers"))
            fig.update_layout(title=f"Comparison of '{var1}' and '{var2}'",
                              xaxis_title=var1, yaxis_title=var2)
            self.plot_1.data = fig
        except Exception as e:
            alert(f"Error displaying comparison: {e}", title="Error")
            print(f"Error: {e}")  # Debugging         


server code below

import pandas as pd
from anvil import Media
import anvil.server
import pandas as pd
import io
# Global storage for the DataFrame
df_store = {}

@anvil.server.callable
def process_file(file):
    """Reads the uploaded file and stores it in memory."""
    with io.BytesIO(file.get_bytes()) as file_content:
        df = pd.read_csv(file_content)
    df_store['df'] = df
    return list(df.columns)  # Return column names for user selection

@anvil.server.callable
def get_row_data(row_index):
    """Fetches data for a specific row."""
    df = df_store.get('df')
    if df is None:
        raise Exception("No dataset uploaded.")
    if row_index < 0 or row_index >= len(df):
        raise Exception("Row index out of range.")
    return df.iloc[row_index].tolist()

@anvil.server.callable
def get_comparison_data(var1, var2):
    """Fetches data for two variables for comparison."""
    df = df_store.get('df')
    if df is None:
        raise Exception("No dataset uploaded.")
    if var1 not in df.columns or var2 not in df.columns:
        raise Exception("Invalid column names.")
    return {"x": df[var1].tolist(), "y": df[var2].tolist()}




its just not working and i dont know why

Welcome to the forum @ishaansuneja!

The code in your post contains two different button_click code snippets (analyze_button_click and display_button_click). Please clarify which button you are inquiring about, and what happens when you click it – “it just doesn’t work” leaves would-be respondents with many possible failure modes to explore and address.

Also: please edit your post to enclose each block of consecutive lines of code in triple tick marks (```) – doing so will preserve indentation and some automatic formatting that will make your code much easier to read and understand.

3 Likes

@ishaansuneja Thank you for editing your post to make your code more readable.

If you still want help, please identify which of the two buttons you’re asking about and provide more description than “it just doesn’t work”.

While @tomherden is right that you would generally need to provide more detail on exactly what is going wrong for anyone to help, in this particular case I think I’ve spotted the issue in your server code thanks to the formatting with the backticks.

You’re using a global variable to try to keep data in the server between two server calls. That won’t work. In Anvil. each server call spins up a separate Python environment (unless you’re on a high enough paid plan that you have a persistent server, which most people don’t have), so the second server call doesn’t have the global variable from the first call.

You would want to pass all the information need, both the file and the row index, to the server in a single call and do all the processing in that one call.

4 Likes

To cache values of a few Anvil-known types, between server calls, see Sessions and Cookies.

However, cache lifetime may not be guaranteed. And this definitely does not cover third-party types such as dataframes.

3 Likes