DEV Community

A0mineTV
A0mineTV

Posted on

Building a Streamlit Inventory Management App with Fragment Decorators 🚀

Introduction

Streamlit provides developers with an easy and intuitive way to build interactive web apps. One of the advanced features of Streamlit is the @st.fragment decorator, which helps modularize apps and improve performance.

In this tutorial, we'll walk you through the creation of an inventory management app with the following functionalities:

  1. Add items to an inventory.
  2. Display the current inventory.
  3. Delete specific items from the inventory.
  4. Avoid adding duplicate items.

Why Use @st.fragment?

The @st.fragment decorator in Streamlit allows developers to encapsulate specific functionalities, leading to modular and reusable code. When used effectively, it helps in reducing unnecessary re-runs and ensures the app remains responsive.

Full Code Example

Below is the complete code for the inventory management app:

import streamlit as st

# Initialize session state if not already set
if "inventory" not in st.session_state:
    st.session_state.inventory = []

@st.fragment
def add_item_fragment():
    """
        Fragment to add a new item to the inventory.
    """
    st.subheader('Add an Item')
    with st.form(key='add_item_form'):
        item_name = st.text_input("Item Name", placeholder="Example: Chair")
        item_quantity = st.number_input('Quantity', min_value=1, step=1, value=1)
        submitted = st.form_submit_button("Add to Inventory")
        if submitted:
            if item_name.strip():
                # Check for duplicates
                if any(item['name'] == item_name.strip() for item in st.session_state.inventory):
                    st.error("This item already exists in the inventory.")
                else:
                    st.session_state.inventory.append({"name": item_name.strip(), "quantity": item_quantity})
                    st.success(f"Item added: {item_name} ({item_quantity})")
                    st.rerun()
            else:
                st.error("Item name cannot be empty.")

@st.fragment
def display_inventory_fragment():
    """
    Fragment to display the inventory items.
    """
    st.subheader('Current Inventory')
    if st.session_state.inventory:
        for idx, item in enumerate(st.session_state.inventory):
            st.write(f"{idx + 1}. **{item['name']}** : {item['quantity']}")

        if st.button("Clear Inventory"):
            st.session_state.inventory = []
            st.success('Inventory cleared')
            st.rerun()
    else:
        st.info('Your inventory is empty.')

@st.fragment
def delete_item_fragment():
    """
    Fragment to delete an item from the inventory.
    """
    st.subheader('Delete an Item')
    if st.session_state.inventory:
        item_to_delete = st.selectbox("Select an item to delete", [item['name'] for item in st.session_state.inventory])
        if st.button("Delete Item"):
            st.session_state.inventory = [item for item in st.session_state.inventory if item['name'] != item_to_delete]
            st.success(f"Item deleted: {item_to_delete}")
            st.rerun()
    else:
        st.warning('No items to delete.')

# Main interface
st.title("Inventory Management App")

# Use fragments
add_item_fragment()
display_inventory_fragment()
delete_item_fragment()
Enter fullscreen mode Exit fullscreen mode

Explanation of the Code

1. Session State Initialization

We use st.session_state to store the inventory, ensuring persistence across user interactions. If the session state is empty, an empty inventory is initialized.

if "inventory" not in st.session_state:
    st.session_state.inventory = []
Enter fullscreen mode Exit fullscreen mode

2. Adding Items to Inventory

The add_item_fragment provides a form for users to input the name and quantity of an item. It includes validation to prevent adding items with empty names or duplicate entries. A success or error message is displayed based on the user's input.

if any(item['name'] == item_name.strip() for item in st.session_state.inventory):
    st.error("This item already exists in the inventory.")
else:
    st.session_state.inventory.append({"name": item_name.strip(), "quantity": item_quantity})
    st.success(f"Item added: {item_name} ({item_quantity})")
    st.rerun()
Enter fullscreen mode Exit fullscreen mode

3. Displaying the Inventory

The display_inventory_fragment iterates over the inventory and lists all items with their quantities. A button is provided to clear the entire inventory.

if st.session_state.inventory:
    for idx, item in enumerate(st.session_state.inventory):
        st.write(f"{idx + 1}. **{item['name']}** : {item['quantity']}")
    if st.button("Clear Inventory"):
        st.session_state.inventory = []
        st.success('Inventory cleared')
        st.rerun()
Enter fullscreen mode Exit fullscreen mode

4. Deleting Items from Inventory

The delete_item_fragment allows users to select an item by its name and delete it. After deletion, the inventory is updated and the app refreshes to reflect the changes.

if st.button("Delete Item"):
    st.session_state.inventory = [item for item in st.session_state.inventory if item['name'] != item_to_delete]
    st.success(f"Item deleted: {item_to_delete}")
    st.rerun()
Enter fullscreen mode Exit fullscreen mode

Key Features of This App

  • Avoid Duplicate Items: Items with the same name are not allowed.
  • Real-Time Updates: The app refreshes immediately after adding, deleting, or clearing items.
  • Modularity: Using @st.fragment ensures clean and reusable code structure.

Potential Improvements

  1. Export and Import Functionality:
    • Add options to export the inventory to a CSV or JSON file and re-import it.
  2. Search Capability:
    • Implement a search bar to filter items in the inventory.
  3. Categories and Units:
    • Allow users to categorize items or specify units (e.g., kilograms, pieces).

Conclusion

This inventory management app demonstrates the power of Streamlit's @st.fragment decorator for modular and efficient app development. By handling duplicate entries and providing real-time feedback, it offers a seamless user experience.

Feel free to customize this app further to suit your needs, and let us know in the comments how you plan to use Streamlit in your projects! 🚀


Happy coding! 🎉

Top comments (0)