AttributeError: 'DataFrame' object has no attribute 'append' when using st.session_state"

Summary

Hello everyone,

I’m facing a peculiar issue while using st.session_state with Pandas DataFrames. I’ve set up a session state variable as a DataFrame to hold some course information. I’m trying to append a new row to this DataFrame, but I’m getting an AttributeError: 'DataFrame' object has no attribute 'append'.

Steps to Reproduce

Code snippet:

pythonCopy code

import pandas as pd
import streamlit as st

if 'df' not in st.session_state:
    st.session_state.df = pd.DataFrame()

def add_new_course():
    if st.session_state.df.empty:
        st.warning("No data available to add a new course.")
        return
    
    new_row = pd.Series({
        'finish': 95,
        'work': None,
        'exam': None,
        'weight': 3,
        'semester': 'a',
        'type': 'ba',
        'year': 1,
        'course_name': 'Intro to Python',
        'difficulty': None
    })

    st.session_state.df = st.session_state.df.append(new_row, ignore_index=True)
  1. Initialize st.session_state.df as an empty Pandas DataFrame.
  2. Call the add_new_course() function.

Expected behavior:

I expect a new row to be appended to the DataFrame stored in st.session_state.df.

Actual behavior:

I get an AttributeError: 'DataFrame' object has no attribute 'append'. Debugging shows that st.session_state.df is indeed a Pandas DataFrame, making the error message confusing.





Links

Additional information

The error occurs only when I try to append a new row to the DataFrame stored in st.session_state.

Try using Session State API to update the DataFrame directly, without using the append method. You can use the len function to get the current number of rows in the DataFrame, and then assign the new row values to the corresponding index

Your code is mostly correct, but the issue arises in the way you’re using the append method with the Pandas DataFrame in the Streamlit session_state. When you append a new row to a DataFrame, you need to ensure that the data being appended matches the structure of the DataFrame. In your case, the new row is a Pandas Series, which is fine, but you need to ensure that the DataFrame columns are defined correctly.

import pandas as pd
import streamlit as st

if 'df' not in st.session_state:
    st.session_state.df = pd.DataFrame(columns=['finish', 'work', 'exam', 'weight', 'semester', 
                                                'type', 'year', 'course_name', 'difficulty'])

def add_new_course():
    if st.session_state.df.empty:
        st.warning("No data available to add a new course.")
        return
    
    new_row = {
        'finish': 95,
        'work': None,
        'exam': None,
        'weight': 3,
        'semester': 'a',
        'type': 'ba',
        'year': 1,
        'course_name': 'Intro to Python',
        'difficulty': None
    }

    st.session_state.df = st.session_state.df.append(new_row, ignore_index=True)