Build an AI E-Commerce Analytics Agent

Build an AI agent that analyzes real sales data using function calling.

Introduction

30 Second Summary

Every online store generates sales data. Extracting useful insights from it usually means writing custom queries, building dashboards, or hiring a data analyst.

In this project, you will build an AI agent that analyzes real e-commerce sales data. Ask plain English questions like "Which products are losing money?" and watch the agent autonomously decide which analysis to run, execute it against a real dataset, and explain the results with specific numbers.

What You'll Build

Picture typing "How did sales change over the holidays?" into a chat box and watching your agent pick the right analysis tool, crunch 3,500 real orders, and hand you a data-backed answer with exact revenue and profit figures.

By the end of this project, you'll have:

  • An agent you can ask plain English business questions and get data-backed answers from a real 3,500-order e-commerce dataset with products, regions, revenue, and profit.
  • A visible window into the agent's decision-making, showing which tool it chose via function calling and what arguments it passed.
  • A deployed web app at a live, shareable URL built with Streamlit that anyone can visit and interact with.
  • Secret Mission: Add a chart generation tool so the agent creates matplotlib visualizations on demand.

Are there any prerequisites?

This project assumes you have Python 3.11 or later and VS Code installed on your computer. No prior Python experience is required.

Before We Start

Before we dive in, let's lock in what you're about to build and why it matters.

Set Up Your Environment

Before you can build your AI agent, you need the right tools in place. That means a project folder, the Python packages your agent depends on, and a connection to the Gemini API.

In this step, you will create a project folder, install all required packages, grab a free Gemini API key, and download the real e-commerce dataset your agent will analyze.

In this step, get ready to:
  • Create a project folder and Python virtual environment.
  • Install packages and set up your Gemini API key.
  • Verify everything works with a quick test.
Create your project folder and virtual environment

Every Python project starts with a dedicated folder and an isolated environment. A virtual environment keeps the packages you install for this project separate from everything else on your machine.

  • Press Cmd+Space (macOS) or the Windows key (Windows) to open your search bar.
  • Type Visual Studio Code and press Enter to open it.
  • Open a new terminal by pressing Ctrl+` (backtick) on both macOS and Windows.

No terminal appeared?

You can also open a terminal from the top menu bar: click Terminal, then New Terminal.

  • Move to your Desktop by running this command:
cd ~/Desktop
  • Create your project folder and move into it by running these commands:
mkdir ecommerce-agent
cd ecommerce-agent

Your terminal prompt now shows ecommerce-agent, confirming you are inside the new folder.

  • Create a Python virtual environment and activate it by running the commands for your operating system:

macOS

python3 -m venv venv
source venv/bin/activate

Windows

python -m venv venv
venv\Scripts\activate

Your terminal prompt now starts with (venv). That means the virtual environment is active and any packages you install will stay inside this project.

  • Check your Python version by running:
python --version

You should see Python 3.11 or higher.

Seeing a version below 3.11?

The packages in this project require Python 3.11 or higher. Visit python.org/downloads and install the latest Python 3.11+ version. After installing, delete the old venv folder and re-create it using the new Python.

On macOS, the system python3 may still point to an older version even after you install a newer one. Use the full path (e.g. python3.11 -m venv venv) or a version manager like pyenv to target the correct version.

Help me fix my Python version for this project.

  • Open this folder in VS Code's workspace so the sidebar shows your project files.
  • Click File in the VS Code menu bar.
  • Click Open Folder.
  • Navigate to your Desktop and select the ecommerce-agent folder.
  • Click Open (macOS) or Select Folder (Windows).

VS Code reloads with your project folder in the Explorer sidebar. If your terminal closed, open a new one by pressing Ctrl+` (backtick).

Do I need to reactivate the virtual environment?

Yes. When VS Code opens a new terminal, the virtual environment is no longer active. Check your prompt for (venv). If it is missing, reactivate by running source venv/bin/activate (macOS) or venv\Scripts\activate (Windows).

Install packages and set up your API key

Your agent needs several packages to work. You will install them all at once, then grab a free API key to connect to Google's Gemini model.

  • Install all required packages by running:
pip install google-genai==2.19.0 streamlit==1.62.0 pandas==3.0.5 matplotlib==3.11.1 python-dotenv==1.1.0

This takes a minute or two. You will see download progress and a success message at the end.

What are these packages?

  • google-genai connects your Python code to the Gemini API so your agent can talk to the LLM.
  • streamlit turns your Python script into a web app with a chat interface.
  • pandas loads and analyzes the e-commerce dataset.
  • matplotlib creates charts and visualizations.
  • python-dotenv loads your API key from a .env file so you never paste secrets directly into code.

Install failed or timed out?

Make sure your terminal prompt starts with (venv). If it does not, reactivate the virtual environment first. If you see permission errors, confirm you are running pip inside the virtual environment, not your system Python.

Help me troubleshoot my pip install errors.

Next, you need a Gemini API key. The free tier gives you free input and output tokens with no credit card required.

  • Open your browser and go to Google AI Studio.
  • Sign in with your Google account.
  • Click Get API key on the landing page.
  • Click Create API key to generate a new key.
  • Copy the key that appears. You will need it in a moment.

Is this free?

Yes. The Gemini API free tier provides free input and output tokens. No credit card or billing setup is required. Google AI Studio automatically creates a project and key for new users after you accept the Terms of Service.

Now store that key in a .env file so your code can load it securely.

  • In the VS Code Explorer sidebar, click the new file icon at the top of the file list.
  • Name the file .env and press Enter.
  • Paste the following line into the file, replacing the placeholder with the key you just copied:
GOOGLE_API_KEY=your-api-key-here

Why a .env file?

A .env file keeps your API key out of your source code. The python-dotenv package reads this file at runtime so your script can use the key without ever hardcoding it.

  • Save .env by pressing Cmd+S (macOS) or Ctrl+S (Windows).

Finally, download the real e-commerce dataset your agent will analyze.

  • Open your browser and go to the E-Commerce Sales and Profit Analysis dataset on Kaggle.
  • Sign in to Kaggle with a free account if prompted.
  • Click the Download button near the top of the dataset page.
  • Unzip the downloaded file if your browser did not unzip it automatically.
  • Find the file named ecommerce_sales_data.csv and move it into your ecommerce-agent folder on your Desktop.
  • Confirm both files are in your project folder by running:
ls

You should see .env, ecommerce_sales_data.csv, and the venv folder listed.

Missing a file?

If .env does not appear, check that you created it in the ecommerce-agent folder and not a parent folder. If ecommerce_sales_data.csv is missing, make sure you moved it out of the unzipped folder and directly into ecommerce-agent.

Help me get the right files into my project folder.

Verify everything works

All the pieces are in place. Before you move on, confirm that every package imports correctly and your API key is accessible.

Before you run this, what do you think will happen? Will the import succeed, or will something be missing?

  • Test that everything is wired up by running:
python -c "from google import genai; print('Ready!')"

You should see Ready! printed in your terminal. That single line proves Python can import the Gemini SDK inside your virtual environment.

Not seeing Ready! ?

If you get ModuleNotFoundError, your terminal is likely running outside the virtual environment. Check that your prompt starts with (venv). If not, reactivate it and re-run the command.

If you see a different import error, try reinstalling the packages with pip install google-genai==2.19.0 and check for any error messages during the install.

Help me debug why my imports are failing.

Your environment is locked and loaded. Next up, you will talk to Gemini directly and see it respond to your questions.

Talk to Gemini and See It Respond

Your environment is ready. Every package is installed, your API key is saved, and the dataset is sitting in your project folder. Now it's time to see if your connection to Gemini actually works.

In this step, you'll write a short Python script that sends a question to the Gemini API and prints the response. You'll also discover a critical limitation that the rest of this project is built to solve.

In this step, get ready to:
  • Send a question to Gemini and see a real response in your terminal.
  • Discover what happens when you ask Gemini about your specific store data.
Create and run your first Gemini script

Before building anything complex, you need to confirm the LLM connection works. A simple script that sends one question and prints the answer is the fastest way to prove it.

  • Create a new file called test_chat.py in your project folder by running this command:
touch test_chat.py
  • Confirm the file exists by running:
ls

You should see test_chat.py alongside your .env file and ecommerce_sales_data.csv.

  • Open test_chat.py in VS Code by clicking on it in the Explorer sidebar.
  • Add the following code to test_chat.py to load your API key and send a question to Gemini:
import os
from dotenv import load_dotenv
from google import genai

# Load your API key from the .env file
load_dotenv()

# Create a Gemini client
client = genai.Client(api_key=os.getenv("GOOGLE_API_KEY"))

# Send a business question to Gemini
response = client.models.generate_content(
    model="gemini-2.0-flash",
    contents="What metrics should an e-commerce store track?"
)

# Print the response
print(response.text)

What does this code do?

  • load_dotenv() reads your .env file and loads GOOGLE_API_KEY into the environment so your script can use it.
  • genai.Client() creates a connection to Google's Gemini API using your key.
  • generate_content() sends your question to the gemini-2.0-flash model and returns whatever it comes up with.
  • Save test_chat.py.

Before you run this, what do you think Gemini will say about e-commerce metrics? Take a guess.

  • Run your script by entering this command in the terminal:
python test_chat.py

You should see a detailed response from Gemini listing metrics like revenue, conversion rate, customer lifetime value, and more. The exact wording varies each time you run it, but the key thing is you got a real answer back from the API.

Not seeing a response?

  • If you see an AuthenticationError or InvalidApiKey, open your .env file and confirm your key is pasted correctly with no extra spaces.
  • If you see ModuleNotFoundError, make sure your virtual environment is activated. You should see the environment name in parentheses at the start of your terminal prompt.
  • If you see a region availability error, the Gemini free tier may not be available in your country. Check the Google AI Studio dashboard for details.

Help me debug my Gemini API connection error.

Ask Gemini about your specific store data

Gemini answered a general business question perfectly. But your project is about analyzing your specific e-commerce dataset. What happens when you ask about data Gemini has never seen?

  • In test_chat.py, find this line:
    contents="What metrics should an e-commerce store track?"
  • Replace the question string so the line looks like this:
    contents="What were the top selling products in my store last quarter?"
  • Save test_chat.py.

Before you run this, do you think Gemini will be able to answer accurately? It has never seen your CSV file. What do you expect to happen?

  • Run the script again by entering this command:
python test_chat.py

Gemini confidently lists product names and sales numbers. The problem is every single number is fabricated. It has no access to your ecommerce_sales_data.csv file, so it invents plausible-sounding data instead of admitting it doesn't know.

Why does Gemini make things up?

This behavior is called hallucination. LLMs generate text that sounds correct based on patterns in their training data. When asked about something they have no information on, they fill in the blanks with plausible guesses instead of saying "I don't know."

This is the core problem your project solves. By the end, your AI agent will answer these same questions using real numbers from the actual dataset.

✔️ Awesome, I've got everything!

Great. Double check you've saved test_chat.py with the updated question.

ⓧ I'd like to double check the full code

Here is the full test_chat.py file. Make sure yours matches:

import os
from dotenv import load_dotenv
from google import genai

# Load your API key from the .env file
load_dotenv()

# Create a Gemini client
client = genai.Client(api_key=os.getenv("GOOGLE_API_KEY"))

# Send a business question to Gemini
response = client.models.generate_content(
    model="gemini-2.0-flash",
    contents="What were the top selling products in my store last quarter?"
)

# Print the response
print(response.text)

You've proven two things. Gemini is smart enough to answer general business questions, but it's completely unreliable when it comes to your actual data. Next up, you'll load that real dataset and build the analysis tools that give the AI something real to work with.

Load Real E-Commerce Data

In the last step, you asked Gemini about your store's sales data and watched it confidently make up numbers. It has no access to your actual records.

This step solves that problem. You'll load a real 3,500-order e-commerce dataset with pandas and write four analysis functions that extract actual business insights. These functions become the tools your AI agent calls autonomously in the next step.

In this step, get ready to:
  • Load the e-commerce dataset into a pandas DataFrame.
  • Write four analysis functions that turn raw data into formatted business insights.
  • Run everything and see real revenue, profit, and performance numbers from the dataset.
Create tools.py and load the dataset

The ecommerce_sales_data.csv file you downloaded has 3,500 orders with columns for dates, regions, categories, products, quantities, revenue, and profit. First, you need a function that reads this file into a structure Python can analyze.

  • In VS Code, create a new file called tools.py in your project folder.
  • Add the following code to load the dataset:
import pandas as pd


def load_data(filepath="ecommerce_sales_data.csv"):
    # Read the CSV file into a pandas DataFrame
    df = pd.read_csv(filepath)
    # Convert Order Date from text to datetime for time-based analysis
    df["Order Date"] = pd.to_datetime(df["Order Date"])
    return df

What does this code do?

pd.read_csv() reads your CSV file and creates a table-like structure called a DataFrame. Each row is an order and each column is a field like Sales Amount or Region.

pd.to_datetime() converts the Order Date column from plain text into proper date objects. This lets pandas do time-based grouping and filtering later.

  • Save tools.py.
  • Confirm the data loads correctly by running this command in your terminal:
python -c "from tools import load_data; df = load_data(); print(f'Loaded {len(df)} orders'); print(df.head())"

You should see Loaded 3500 orders followed by a table showing the first five rows of the dataset, including columns like Order Date, Region, Category, and Sales Amount.

Seeing a FileNotFoundError?

Make sure ecommerce_sales_data.csv is in the same folder as tools.py. The filename must match exactly, including underscores.

If you moved the CSV to a different location, update the default filepath in load_data() to match.

Help me fix a FileNotFoundError when loading my CSV with pandas.

Write the analysis functions

Each analysis function takes a DataFrame, crunches specific metrics, and returns a formatted string summary. You'll write four functions that each answer a different business question.

  • In tools.py, add the get_sales_summary function below load_data:
def get_sales_summary(df):
    # Calculate overall business metrics
    total_orders = len(df)
    total_revenue = df["Sales Amount"].sum()
    total_profit = df["Profit"].sum()
    avg_order_value = df["Sales Amount"].mean()
    profit_margin = (total_profit / total_revenue) * 100

    # Format everything into a readable summary string
    return (
        f"Sales Summary:\n"
        f"- Total Orders: {total_orders:,}\n"
        f"- Total Revenue: ${total_revenue:,.2f}\n"
        f"- Total Profit: ${total_profit:,.2f}\n"
        f"- Average Order Value: ${avg_order_value:,.2f}\n"
        f"- Overall Profit Margin: {profit_margin:.1f}%"
    )

What does this function do?

It calculates five key business metrics from the entire dataset: total orders, revenue, profit, average order value, and profit margin.

The :, format specifier adds commas to large numbers (e.g. 3,500 instead of 3500) and :,.2f adds commas plus two decimal places for dollar amounts.

  • Save tools.py.
  • Test the function by running this command:
python -c "from tools import load_data, get_sales_summary; df = load_data(); print(get_sales_summary(df))"

You should see a sales summary with real numbers for total orders, total revenue, total profit, average order value, and profit margin.

Seeing a KeyError?

Column names must match the CSV headers exactly. Make sure you used "Sales Amount" and "Profit" with those exact capitalizations and spacing.

Help me debug a KeyError in my pandas analysis function.

  • Next, add the get_revenue_by_region function below get_sales_summary:
def get_revenue_by_region(df):
    # Group orders by region and calculate aggregate stats
    region_stats = df.groupby("Region").agg(
        Revenue=("Sales Amount", "sum"),
        Profit=("Profit", "sum"),
        Orders=("Sales Amount", "count"),
    ).sort_values("Revenue", ascending=False)

    # Build a formatted string with one line per region
    lines = ["Revenue by Region:"]
    for region, row in region_stats.iterrows():
        margin = (row["Profit"] / row["Revenue"]) * 100
        lines.append(
            f"- {region}: Revenue=${row['Revenue']:,.2f}, "
            f"Profit=${row['Profit']:,.2f}, "
            f"Orders={row['Orders']:,}, "
            f"Margin={margin:.1f}%"
        )
    return "\n".join(lines)

What does this function do?

.groupby("Region").agg(...) groups all 3,500 orders by their region (North, South, East, West) and calculates total revenue, profit, and order count for each.

It also calculates profit margin per region so you can spot which regions generate the most revenue versus which are the most profitable.

  • Save tools.py.
  • Test the regional breakdown by running:
python -c "from tools import load_data, get_revenue_by_region; df = load_data(); print(get_revenue_by_region(df))"

You should see four regions listed with their revenue, profit, order counts, and margin percentages.

Seeing an empty output or wrong column?

Make sure the column name is "Region" with a capital R. Also verify the .agg() call uses tuples like ("Sales Amount", "sum") for each aggregation.

Help me fix my pandas groupby aggregation.

  • Add the get_top_products function below get_revenue_by_region:
def get_top_products(df, n=5):
    # Group by product and rank by total revenue
    product_stats = df.groupby("Product Name").agg(
        Revenue=("Sales Amount", "sum"),
        Profit=("Profit", "sum"),
        Quantity=("Quantity", "sum"),
    ).sort_values("Revenue", ascending=False).head(n)

    # Format a numbered list of top products
    lines = [f"Top {n} Products by Revenue:"]
    for i, (product, row) in enumerate(product_stats.iterrows(), 1):
        lines.append(
            f"{i}. {product}: Revenue=${row['Revenue']:,.2f}, "
            f"Profit=${row['Profit']:,.2f}, "
            f"Units Sold={row['Quantity']:,}"
        )
    return "\n".join(lines)

What does this function do?

This function accepts an optional parameter n that defaults to 5, letting the caller request any number of top products.

.head(n) slices the revenue-sorted results to keep only the top N. This is the parameter your AI agent will use later when someone asks "What are the top 3 products?"

  • Save tools.py.
  • Test the product ranking by running:
python -c "from tools import load_data, get_top_products; df = load_data(); print(get_top_products(df))"

You should see a numbered list of the top 5 products with their revenue, profit, and units sold.

Seeing a KeyError for Product Name?

The column header includes a space: "Product Name", not "ProductName". Also check that "Quantity" uses a capital Q.

Help me debug a KeyError in my get_top_products function.

  • Add the last analysis function, get_category_performance, below get_top_products:
def get_category_performance(df):
    # Group by category and calculate comprehensive metrics
    cat_stats = df.groupby("Category").agg(
        Revenue=("Sales Amount", "sum"),
        Profit=("Profit", "sum"),
        Orders=("Sales Amount", "count"),
        Avg_Quantity=("Quantity", "mean"),
    ).sort_values("Revenue", ascending=False)

    # Format each category's performance into a readable line
    lines = ["Category Performance:"]
    for category, row in cat_stats.iterrows():
        margin = (row["Profit"] / row["Revenue"]) * 100
        lines.append(
            f"- {category}: Revenue=${row['Revenue']:,.2f}, "
            f"Profit=${row['Profit']:,.2f}, "
            f"Margin={margin:.1f}%, "
            f"Orders={row['Orders']:,}, "
            f"Avg Qty/Order={row['Avg_Quantity']:.1f}"
        )
    return "\n".join(lines)

What does this function do?

This breaks performance down by the three product categories: Electronics, Accessories, and Office.

It includes an Avg_Quantity metric using .mean() to show the average number of items per order in each category. This helps identify bulk-purchase patterns versus single-item purchases.

  • Save tools.py.
  • Test the category breakdown by running:
python -c "from tools import load_data, get_category_performance; df = load_data(); print(get_category_performance(df))"

You should see three categories listed with their revenue, profit, margin, orders, and average quantity per order.

Only seeing one or two categories?

Verify the column name is "Category" with a capital C. If your CSV downloaded incompletely, re-download it from Kaggle.

Help me debug my get_category_performance function output.

Run all the tools together

Now you'll add a __main__ block that loads the data once and runs every analysis function in sequence. This is how you'll verify everything works end to end.

  • At the bottom of tools.py, add this block:
if __name__ == "__main__":
    df = load_data()
    print(f"Loaded {len(df)} orders\n")
    print(get_sales_summary(df))
    print()
    print(get_revenue_by_region(df))
    print()
    print(get_top_products(df))
    print()
    print(get_category_performance(df))

What does this block do?

if __name__ == "__main__" means this code only runs when you execute tools.py directly. When another file imports functions from tools.py later, this block is skipped.

It loads the dataset once into df, then passes that same DataFrame to every analysis function and prints the results.

  • Save tools.py.

Before you run this, predict: how many total orders do you think the dataset has, and how many regions will appear in the breakdown?

  • Run the full analysis by executing:
python tools.py

You should see 3,500 orders loaded, followed by a sales summary, revenue broken down across four regions, the top five products ranked by revenue, and performance metrics for three product categories.

Seeing a NameError or ImportError?

Make sure all five functions (load_data, get_sales_summary, get_revenue_by_region, get_top_products, get_category_performance) are defined above the if __name__ block. Python reads files top to bottom, so any function called before its definition causes a NameError.

Help me fix NameError or ImportError in my tools.py analysis script.

✔️ Awesome, I've got everything!

Great. Double check you've saved tools.py and that python tools.py prints all four analysis summaries.

ⓧ I'd like to double check the full code

Your tools.py should contain the following blocks in this exact order. Scroll up and confirm each one is present in your file:

  • import pandas as pd at the top.
  • load_data() function that reads the CSV and converts Order Date to datetime.
  • get_sales_summary(df) function returning total orders, revenue, profit, average order value, and margin.
  • get_revenue_by_region(df) function returning per-region revenue, profit, orders, and margin.
  • get_top_products(df, n=5) function returning the top N products ranked by revenue.
  • get_category_performance(df) function returning per-category revenue, profit, margin, orders, and average quantity.
  • if __name__ == "__main__" block that loads data and prints all four analyses.

Your analysis toolkit is ready and producing real business insights from 3,500 orders. Next up, you'll wire these functions to Gemini using function calling so the AI agent can choose which tool to run based on your questions.

Wire the Agent with Function Calling

You now have four analysis functions that pull real insights from 3,500 orders. You also have a Gemini connection that can chat, but hallucinates when asked about your data.

Function calling bridges that gap. You tell Gemini what tools exist, and it autonomously decides which one to call based on the user's question. The result is an AI agent that answers business questions with real numbers instead of guesses.

In this step, get ready to:
  • Define function declarations that tell Gemini what analysis tools are available.
  • Build an agent loop that sends questions to Gemini, handles tool calls, and returns data-backed answers.
  • Test the agent with different business questions and watch it pick the right tool each time.
Create the agent file with tool mappings

The agent needs three things to work: a connection to Gemini, a dictionary that maps tool names to actual Python functions, and a system prompt that tells Gemini how to behave.

  • Create a new file called agent.py in your project folder and paste the following code:
import json
import os
from dotenv import load_dotenv
from google import genai
from google.genai import types
from tools import load_data, get_sales_summary, get_revenue_by_region, get_top_products, get_category_performance

# Load environment variables and create Gemini client
load_dotenv()
client = genai.Client(api_key=os.getenv("GOOGLE_API_KEY"))

# Load the dataset once so every tool can use it
df = load_data()

# Map each tool name to a lambda that calls the real function with the dataframe
TOOL_FUNCTIONS = {
    "get_sales_summary": lambda: get_sales_summary(df),
    "get_revenue_by_region": lambda: get_revenue_by_region(df),
    "get_top_products": lambda n=5: get_top_products(df, n=int(n)),
    "get_category_performance": lambda: get_category_performance(df),
}

# Tell Gemini what role it plays and what data it has access to
SYSTEM_PROMPT = (
    "You are an AI business intelligence agent for an e-commerce company. "
    "You have access to tools that analyze real sales data with 3,500 orders "
    "across multiple products, categories, and regions from 2022-2024. "
    "When a user asks a business question, use the appropriate tool to get "
    "real data, then provide a clear, actionable answer based on the results. "
    "Always cite specific numbers from the data. If the question cannot be "
    "answered with the available tools, say so honestly."
)

What does this code do?

The imports bring in everything from tools.py plus the Gemini SDK. The client and dataframe are created once at module level so they're ready for every question.

TOOL_FUNCTIONS is a dictionary that maps each tool name (a string like "get_sales_summary") to a lambda that calls the real function with df already filled in. This is how the agent will execute the right function when Gemini asks for it.

SYSTEM_PROMPT gives Gemini its persona. It tells the model to use the tools for real data and cite specific numbers instead of guessing.

  • Save agent.py.
  • Confirm the imports work by running this command in your terminal:
python agent.py

You should see no errors and no output. The script loads the data and sets up the mappings, then exits because there is nothing to run yet.

Seeing an import error?

  • Make sure agent.py is in the same folder as tools.py and ecommerce_sales_data.csv. The import won't find tools if they're in different directories.
  • Confirm your virtual environment is activated. You should see its name in parentheses at the start of your terminal prompt.

Help me debug my agent.py import error

Now the agent knows which functions exist and how to call them. The next piece is telling Gemini about these tools in a format it understands.

  • Add the tool declarations below the SYSTEM_PROMPT in agent.py:
# Each declaration tells Gemini a tool's name, purpose, and parameters
tool_declarations = [
    {
        "name": "get_sales_summary",
        "description": "Get an overall summary of sales performance including total orders, revenue, profit, average order value, and profit margin.",
        "parameters": {"type": "object", "properties": {}},
    },
    {
        "name": "get_revenue_by_region",
        "description": "Get revenue, profit, and order count broken down by geographic region (North, South, East, West).",
        "parameters": {"type": "object", "properties": {}},
    },
    {
        "name": "get_top_products",
        "description": "Get the top N best-selling products ranked by total revenue.",
        "parameters": {
            "type": "object",
            "properties": {
                "n": {
                    "type": "integer",
                    "description": "Number of top products to return. Defaults to 5.",
                },
            },
        },
    },
    {
        "name": "get_category_performance",
        "description": "Get performance metrics for each product category (Electronics, Accessories, Office) including revenue, profit, margin, and average quantity per order.",
        "parameters": {"type": "object", "properties": {}},
    },
]

What are tool declarations?

Tool declarations are how you describe your functions to Gemini. Each one has a name, a plain-English description, and a parameters schema listing what arguments the function accepts.

Gemini reads these descriptions to decide which tool fits the user's question. The better the description, the more accurately Gemini picks the right tool. Three of the four tools take no parameters (just the dataframe, which is handled internally). Only get_top_products accepts an optional n argument.

  • Save agent.py and run it again to confirm there are no syntax errors:
python agent.py

Again, no output means no errors. The declarations are loaded and ready.

Build the agent loop

With the tools declared, the agent needs a function that sends the user's question to Gemini along with the tool list, detects when Gemini wants to call a tool, executes it, and sends the result back for a final answer.

  • Add the first half of the ask_agent function below tool_declarations in agent.py. This part sends the question to Gemini with the tool declarations and gets the initial response:
def ask_agent(question):
    """Send a question to the agent and return the response with tool call info."""
    # Package the tool declarations and system prompt into a config
    tools = types.Tool(function_declarations=tool_declarations)
    config = types.GenerateContentConfig(
        tools=[tools],
        system_instruction=SYSTEM_PROMPT,
    )

    # Send the user's question to Gemini
    contents = [question]
    response = client.models.generate_content(
        model="gemini-2.0-flash",
        contents=contents,
        config=config,
    )

    # Extract the first part of the response
    part = response.candidates[0].content.parts[0]
    tool_info = None

What does this code do?

types.Tool(function_declarations=tool_declarations) packages your tool list into the format the Gemini API expects. The GenerateContentConfig bundles the tools and system instruction together.

The call to generate_content sends the question plus all four tool declarations to gemini-2.0-flash. Gemini reads the question, reads the tool descriptions, and decides whether to call a tool or answer directly. The response part could be either a function_call (Gemini wants to use a tool) or plain text (Gemini answered on its own).

  • Now add the function call handling logic directly below the previous code, still inside the ask_agent function. Make sure this code is indented under the function definition:
    # If Gemini wants to call a tool, execute it and send the result back
    if part.function_call:
        fc = part.function_call
        func_name = fc.name
        func_args = dict(fc.args) if fc.args else {}

        tool_info = {"name": func_name, "args": func_args}
        print(f"  [Agent chose tool: {func_name}({func_args})]")

        # Look up and execute the matching Python function
        if func_name in TOOL_FUNCTIONS:
            result = TOOL_FUNCTIONS[func_name](**func_args)
        else:
            result = f"Error: Unknown tool '{func_name}'"

        # Send the tool result back to Gemini for a final natural language answer
        contents.append(response.candidates[0].content)
        fn_response_part = types.Part.from_function_response(
            name=fc.name,
            response={"result": result},
            id=fc.id,
        )
        contents.append(types.Content(role="user", parts=[fn_response_part]))

        final_response = client.models.generate_content(
            model="gemini-2.0-flash",
            contents=contents,
            config=config,
        )
        answer = final_response.text
    else:
        answer = part.text

    return answer, tool_info

What does this code do?

When Gemini returns a function_call, it includes the tool name and arguments it chose. The code looks up that name in TOOL_FUNCTIONS and runs the matching Python function with the provided arguments.

The result (real numbers from the dataset) gets sent back to Gemini via Part.from_function_response. The id=fc.id parameter maps the response back to the original function call so Gemini knows which tool produced this data. Gemini then writes a final human-readable answer grounded in those real numbers.

If Gemini answered without calling a tool (for example, a greeting), the else branch simply returns the text directly.

Add the interactive loop and test the agent
  • Add the interactive terminal loop at the bottom of agent.py, outside the ask_agent function (no indentation):
if __name__ == "__main__":
    print("E-Commerce Business Intelligence Agent")
    print("Type 'quit' to exit.\n")

    while True:
        question = input("You: ").strip()
        if question.lower() in ("quit", "exit", "q"):
            break
        if not question:
            continue

        answer, tool_info = ask_agent(question)
        print(f"\nAgent: {answer}\n")

What does this code do?

This creates a simple input loop. It prompts with You:, takes your question, passes it to ask_agent, and prints the response. Type quit to exit. This lets you keep asking questions without restarting the script each time.

  • Save agent.py.

Before you run the agent, think about what should happen when you ask "Which region generates the most revenue?" Which of your four tools do you think Gemini will pick?

  • Run the agent by running this command:
python agent.py
  • When you see the You: prompt, type this question:
Which region generates the most revenue?

You should see the agent choose get_revenue_by_region on its own, print [Agent chose tool: get_revenue_by_region({})], and then respond with the actual revenue numbers from the dataset.

  • Try a few more questions to see the agent pick different tools:
What is our total revenue?
Which products sell the most?
Compare performance across product categories

Watch the bracketed output to see which tool the agent picks each time. It should choose get_sales_summary for the revenue question, get_top_products for the products question, and get_category_performance for the category comparison.

  • Type quit to exit the agent loop.

Agent not responding or throwing an error?

  • If you see an indentation error, make sure the if part.function_call: block and the return statement are indented one level under def ask_agent(question):. The if __name__ block should have zero indentation.
  • If you see an API error, double-check that your .env file contains a valid GOOGLE_API_KEY and that your Gemini API key is still active.
  • If the agent responds but doesn't show which tool it called, check that your print(f" [Agent chose tool: ...") line is inside the if part.function_call: block.

Help me debug my agent.py function calling

✔️ Awesome, I've got everything!

Great. Double check you've saved agent.py and confirmed the agent picks the right tool for different questions.

ⓧ I'd like to double check the full code

Your agent.py should contain these sections in order. Scroll through your file and confirm each one is present:

  • Imports (import json, import os, from dotenv, from google, from tools).
  • load_dotenv(), client, and df setup at module level.
  • TOOL_FUNCTIONS dictionary with 4 lambda entries.
  • SYSTEM_PROMPT string.
  • tool_declarations list with 4 declaration dictionaries.
  • def ask_agent(question): function with the API call, function_call handling, and return answer, tool_info at the end.
  • if __name__ == "__main__": block with the interactive while True loop.

Your AI agent now autonomously picks the right analysis tool and returns real numbers from 3,500 orders. Next up, you'll wrap this in a web app and deploy it to a live URL that anyone can interact with.

Build the Streamlit App and Deploy

Your agent works. It picks the right analysis tool, queries real data, and returns meaningful answers in the terminal. One problem: nobody else can use it.

In this step, you'll wrap the agent in a Streamlit web app and deploy it to a live URL that anyone can visit and interact with.

In this step, get ready to:
  • Build a Streamlit chat interface connected to your existing agent logic.
  • Push your project to GitHub and create a requirements file for deployment.
  • Deploy to Streamlit Community Cloud and get a shareable live URL.
Create the Streamlit app

Streamlit turns Python scripts into web apps. You write Python, and Streamlit handles the HTML, CSS, and JavaScript for you.

  • Create a new file called app.py in your project folder and add the setup code by pasting the following:
import os
import streamlit as st
from google import genai
from google.genai import types
from tools import load_data, get_sales_summary, get_revenue_by_region, get_top_products, get_category_performance

# Configure the Streamlit page
st.set_page_config(page_title="E-Commerce BI Agent", page_icon="📊", layout="wide")

# Load API key from environment variable or Streamlit secrets
api_key = os.environ.get("GOOGLE_API_KEY") or st.secrets.get("GOOGLE_API_KEY")
if not api_key:
    st.error("Please set your GOOGLE_API_KEY in .env or Streamlit secrets.")
    st.stop()

client = genai.Client(api_key=api_key)

# Cache data so it only loads once per session
@st.cache_data
def get_data():
    return load_data()

df = get_data()

# Map tool names to their Python functions
TOOL_FUNCTIONS = {
    "get_sales_summary": lambda: get_sales_summary(df),
    "get_revenue_by_region": lambda: get_revenue_by_region(df),
    "get_top_products": lambda n=5: get_top_products(df, n=int(n)),
    "get_category_performance": lambda: get_category_performance(df),
}

What does this code do?

Most of this is familiar from agent.py. The key differences for Streamlit are:

  • st.set_page_config() sets the browser tab title, icon, and layout.
  • The API key is loaded from either an environment variable or Streamlit secrets, so the app works both locally and when deployed.
  • @st.cache_data prevents the CSV from reloading every time the page reruns. Streamlit reruns your entire script on every interaction, so caching keeps it fast.
  • Save app.py.
  • Before running the app, set your API key as an environment variable so Streamlit can access it. Copy the key value from your .env file.

macOS

  • Set the environment variable and start the app by running these commands in your terminal:
export GOOGLE_API_KEY=your-api-key-here
streamlit run app.py

Windows

  • Set the environment variable and start the app by running these commands in your terminal:
$env:GOOGLE_API_KEY="your-api-key-here"
streamlit run app.py

What happens when you run this?

Streamlit starts a local web server and opens a new browser tab at http://localhost:8501. The terminal is now occupied running the server, so you will need to open a second terminal tab for any future commands.

If Streamlit asks for your email in the terminal, you can press Enter to skip it.

You should see a mostly blank page with "E-Commerce BI Agent" in the browser tab title. The page itself has no visible content yet because you have not added any UI elements.

Seeing an error in the browser?

  • If you see "Please set your GOOGLE_API_KEY", your environment variable was not set correctly. Stop the server with Ctrl+C, re-run the export or $env: command with your actual key, then run streamlit run app.py again.
  • If you see a ModuleNotFoundError, make sure your virtual environment is activated in the terminal where you ran the command.

Help me fix my Streamlit app not loading.

  • Add the tool declarations below TOOL_FUNCTIONS in app.py by pasting the following:
tool_declarations = [  # Declare the tools Gemini can choose from
    {
        "name": "get_sales_summary",
        "description": "Get an overall summary of sales performance including total orders, revenue, profit, average order value, and profit margin.",
        "parameters": {"type": "object", "properties": {}},
    },
    {
        "name": "get_revenue_by_region",
        "description": "Get revenue, profit, and order count broken down by geographic region (North, South, East, West).",
        "parameters": {"type": "object", "properties": {}},
    },
    {
        "name": "get_top_products",
        "description": "Get the top N best-selling products ranked by total revenue.",
        "parameters": {
            "type": "object",
            "properties": {
                "n": {
                    "type": "integer",
                    "description": "Number of top products to return. Defaults to 5.",
                },
            },
        },
    },
    {
        "name": "get_category_performance",
        "description": "Get performance metrics for each product category (Electronics, Accessories, Office) including revenue, profit, margin, and average quantity per order.",
        "parameters": {"type": "object", "properties": {}},
    },
]

Why is this identical to agent.py?

The tool declarations are the same list you built in agent.py. Gemini needs the same function descriptions whether the agent runs in a terminal or a web app. The tool names and schemas must match exactly so Gemini can choose the right function.

  • Save app.py. Your browser should auto-refresh with no errors.
  • Add the system prompt and UI elements below tool_declarations in app.py by pasting the following:
SYSTEM_PROMPT = (
    "You are an AI business intelligence agent for an e-commerce company. "
    "You have access to tools that analyze real sales data with 3,500 orders "
    "across multiple products, categories, and regions from 2022-2024. "
    "When a user asks a business question, use the appropriate tool to get "
    "real data, then provide a clear, actionable answer based on the results. "
    "Always cite specific numbers from the data. If the question cannot be "
    "answered with the available tools, say so honestly."
)

# Display the app title and description
st.title("📊 E-Commerce Business Intelligence Agent")
st.markdown(
    "Ask any business question about the e-commerce dataset. "
    "The AI agent will autonomously choose the right analysis tool and return data-backed insights."
)

# Show dataset stats in the sidebar
with st.sidebar:
    st.header("About the Dataset")
    st.metric("Total Orders", f"{len(df):,}")
    st.metric("Total Revenue", f"${df['Sales Amount'].sum():,.0f}")
    st.metric("Total Profit", f"${df['Profit'].sum():,.0f}")
    st.markdown("---")
    st.markdown("**Categories:** Electronics, Accessories, Office")
    st.markdown("**Regions:** North, South, East, West")
    st.markdown("**Period:** 2022-2024")

What does the sidebar do?

st.sidebar creates a collapsible panel on the left side of the app. st.metric() displays key numbers in a bold, card-style format. Visitors immediately see the scale of the dataset before they ask their first question.

  • Save app.py and check your browser.

You should now see the title, description, and a sidebar showing Total Orders, Total Revenue, and Total Profit pulled from the real dataset.

Sidebar not showing?

  • On narrow browser windows the sidebar may be collapsed. Click the arrow icon in the top-left corner to expand it.
  • If you see an error mentioning Sales Amount, confirm your ecommerce_sales_data.csv file is in the same folder as app.py.

Help me debug my Streamlit sidebar.

  • Add the chat session state and input handler below the sidebar code in app.py by pasting the following:
# Initialize chat history in session state
if "messages" not in st.session_state:
    st.session_state.messages = []

# Replay previous messages on page rerun
for message in st.session_state.messages:
    with st.chat_message(message["role"]):
        st.markdown(message["content"])

# Handle new user input
if prompt := st.chat_input("Ask a business question..."):
    st.session_state.messages.append({"role": "user", "content": prompt})
    with st.chat_message("user"):
        st.markdown(prompt)

    with st.chat_message("assistant"):
        with st.spinner("Analyzing..."):
            tools = types.Tool(function_declarations=tool_declarations)
            config = types.GenerateContentConfig(
                tools=[tools],
                system_instruction=SYSTEM_PROMPT,
            )
            contents = [prompt]
            response = client.models.generate_content(
                model="gemini-2.0-flash",
                contents=contents,
                config=config,
            )
            part = response.candidates[0].content.parts[0]

What is session state?

Streamlit reruns your entire script from top to bottom every time the user interacts with the page. st.session_state is a dictionary that persists between reruns, so chat messages are not lost when the page refreshes.

The := operator (walrus operator) assigns the user's input to prompt and checks if it is not empty, all in one line. The code that follows sends the prompt to Gemini with the same function calling pattern from agent.py.

  • Still inside the with st.spinner("Analyzing..."): block, right after the line part = response.candidates[0].content.parts[0], add the function call handler by pasting the following:
            # Check if Gemini wants to call a tool
            if part.function_call:
                fc = part.function_call
                func_name = fc.name
                func_args = dict(fc.args) if fc.args else {}
                st.caption(f"🔧 Agent called: `{func_name}({func_args})`")
                # Execute the tool and get results
                if func_name in TOOL_FUNCTIONS:
                    result = TOOL_FUNCTIONS[func_name](**func_args)
                else:
                    result = f"Error: Unknown tool '{func_name}'"
                # Send the tool result back to Gemini for a final answer
                contents.append(response.candidates[0].content)
                fn_response_part = types.Part.from_function_response(
                    name=fc.name,
                    response={"result": result},
                    id=fc.id,
                )
                contents.append(types.Content(role="user", parts=[fn_response_part]))
                final_response = client.models.generate_content(
                    model="gemini-2.0-flash",
                    contents=contents,
                    config=config,
                )
                answer = final_response.text
            else:
                answer = part.text
            st.markdown(answer)

    st.session_state.messages.append({"role": "assistant", "content": answer})

What does this code do?

This is the same function calling loop from agent.py, adapted for Streamlit. The key difference is st.caption(), which displays a small line showing which tool the agent chose. Visitors can see the agent's reasoning right in the chat.

After the response is generated, st.markdown(answer) renders it in the chat bubble. The final line saves the answer to st.session_state.messages so it persists across page reruns.

Before you test, what do you think will happen when you type a question into the chat input box?

  • Save app.py and switch to your browser.
  • Type What is our total revenue? into the chat input at the bottom of the page and press Enter.

You should see a spinner that says "Analyzing...", then a caption showing the tool the agent called, followed by a data-backed answer with real revenue numbers from the dataset.

Chat input not appearing?

  • Make sure the indentation in your code matches exactly. The if part.function_call: block must be indented inside with st.spinner. Python is sensitive to whitespace.
  • If you see a "NameError" for answer, make sure the last line st.session_state.messages.append(...) is inside the if prompt block but outside the with st.chat_message("assistant") block.

Help me fix my Streamlit chat interface.

✔️ Awesome, I've got everything!

Great. Double check you have saved app.py and the chat is working before moving on.

ⓧ I'd like to double check the full code

Your app.py should contain these sections in order. Scroll up and confirm each one is present:

  • Imports, page config, API key loading, cached data, and TOOL_FUNCTIONS (first code block).
  • tool_declarations list with all four tool schemas (second code block).
  • SYSTEM_PROMPT, st.title(), st.markdown(), and the st.sidebar block (third code block).
  • Session state initialization, message replay loop, and the st.chat_input handler through part = response.candidates[0].content.parts[0] (fourth code block).
  • The if part.function_call handler, st.markdown(answer), and the final st.session_state.messages.append(...) line (fifth code block).
Prepare for deployment

To deploy your app, Streamlit Community Cloud needs to know which Python packages to install. It also needs your code in a GitHub repository.

  • Create a file called requirements.txt in your project folder and paste the following:
google-genai==2.19.0
streamlit==1.62.0
pandas==3.0.5
matplotlib==3.11.1
python-dotenv==1.1.0

What is requirements.txt?

This file tells Streamlit Community Cloud which packages to install, and at which versions, when it builds your app. Pinning exact versions ensures the deployed app behaves the same as your local one.

  • Save requirements.txt.
  • Confirm the file exists by running this in a new terminal tab (since your first terminal is running Streamlit):
ls

You should see requirements.txt alongside app.py, tools.py, agent.py, and ecommerce_sales_data.csv in the output.

Don't have a GitHub account?

If you do not have a GitHub account, go to github.com and sign up for a free account before continuing.

  • Go to github.com/new in your browser to create a new repository.
  • Enter a repository name (for example, ecommerce-bi-agent).
  • Select Public visibility.
  • Leave all other options unchecked (no README, no .gitignore).
  • Click Create repository.
  • Copy the repository URL shown on the next page. It looks like https://github.com/your-username/ecommerce-bi-agent.git.
  • Initialize a Git repository and push your code by running these commands in your second terminal:
git init
git add tools.py agent.py app.py requirements.txt ecommerce_sales_data.csv test_chat.py
git commit -m "Add e-commerce BI agent"
git branch -M main
git remote add origin [[YOUR_REPO_URL="https://github.com/your-username/ecommerce-bi-agent.git"]]
git push -u origin main

Why not git add everything?

The git add command lists specific files to avoid pushing your .env file. That file contains your API key, and pushing secrets to GitHub is a security risk.

Git asking for authentication?

  • GitHub requires authentication for pushing. If prompted, you can authenticate using a GitHub Personal Access Token or by installing the GitHub CLI. See GitHub's authentication docs for setup instructions.
  • If you see "fatal: not a git repository", make sure you are in your project folder when running the commands.

Help me push my code to GitHub.

After the push completes, refresh your GitHub repository page in the browser. You should see all your project files listed.

Deploy to Streamlit Community Cloud

Your code is on GitHub. Now you will deploy it to Streamlit Community Cloud so anyone with the URL can interact with your agent.

  • Go to share.streamlit.io and sign in with your GitHub account.
  • Click Create app in the upper-right corner.
  • When asked "Do you already have an app?" click Yup, I have an app.
  • Select your repository, set the branch to main, and set the main file path to app.py.
  • Click Advanced settings.
  • In the Secrets field, paste the following line (replacing the placeholder with your actual API key from your .env file):
GOOGLE_API_KEY = "your-api-key-here"

What are Streamlit secrets?

Streamlit secrets work like environment variables for deployed apps. Your app.py code reads the key with st.secrets.get("GOOGLE_API_KEY"). This keeps your API key out of your code and out of your GitHub repository.

  • Click Save in the Advanced settings modal.
  • Click Deploy.

Streamlit will clone your repo, install your dependencies from requirements.txt, and start your app. This usually takes 2-3 minutes. You can watch the build logs on the right side of the screen.

Before you test your live app, do you think the deployed agent will behave the same way it did locally?

  • Once the build finishes, your app loads at a URL like https://your-app-name.streamlit.app.
  • Type a question into the chat, such as Compare performance across product categories.

You should see the agent call get_category_performance and respond with revenue, profit, and margin data for Electronics, Accessories, and Office. Your agent is now live on the internet.

App failing to deploy?

  • Check the build logs on the right side. If you see "Error installing requirements", make sure your requirements.txt matches the version numbers listed above exactly.
  • If the app deploys but shows the API key error, click Manage app in the lower-right corner of your app, then click the settings icon to verify your secrets are saved correctly.
  • If you see a "FileNotFoundError" for the CSV, confirm that ecommerce_sales_data.csv was included in your git add command and pushed to GitHub.

Help me fix my Streamlit Community Cloud deployment.

Your app sleeps after 12 hours

Streamlit Community Cloud apps go to sleep after 12 hours of inactivity. When someone visits your URL, the app wakes up automatically. This is normal for free-tier apps and does not affect your deployment.

Your AI agent is live. Anyone with the URL can ask business questions and get data-backed answers. Next up, you will take on an optional Secret Mission to make the agent even more impressive.

Secret mission

Add Chart Generation

Your agent returns numbers, but a real business intelligence tool shows charts. In this mission, you'll add a chart generation tool so the agent can create bar charts and line charts on demand, displayed inline in the Streamlit app.

Clean Up Your Resources

Clean Up Your Resources

This project runs entirely on free resources. The Gemini API free tier, Streamlit Community Cloud, and GitHub all cost nothing to maintain.

Decide whether to keep your resources running, pause them to come back later, or delete them entirely.

Resources you used:

  • Local project folder on your Desktop with Python files (tools.py, agent.py, app.py, test_chat.py, requirements.txt, .env, ecommerce_sales_data.csv) and a Python virtual environment.
  • Streamlit Community Cloud app deployed at a *.streamlit.app URL.
  • GitHub repository with your project code.
  • Google AI Studio API key stored in your .env file and Streamlit secrets.

Keep everything running

No action needed. Choose this if you are still actively building or want to keep your live app URL available for demos and interviews.

  • Your Streamlit Community Cloud app stays live at its URL. The app sleeps after 12 hours of inactivity and wakes up automatically when someone visits.
  • Your GitHub repository remains public with your code.
  • Your Gemini API key remains active on the free tier with no charges.
  • Your local project folder and virtual environment stay on your Desktop.

Pause - I'll come back to this later

Free up local disk space while keeping your cloud resources intact. You can always clone the repo and redeploy later.

  • Your Streamlit app, GitHub repo, and API key all stay active at no cost.
  • Delete only the local project folder to free disk space. Open your terminal and run the commands below.

macOS

cd ~/Desktop
rm -rf ecommerce-agent

Windows

cd ~\Desktop
rmdir /s /q ecommerce-agent

Delete - I don't want to use this again

Remove all project resources completely. Follow each step below.

Delete your Streamlit Community Cloud app
  • Go to share.streamlit.io and sign in.
  • Find your app in the list and click the overflow menu icon (three dots) next to it.
  • Click Delete.
  • Enter the confirmation string and click Delete to confirm.
Delete your GitHub repository
  • Open your repository on GitHub.
  • Click Settings in the top navigation bar.
  • Scroll down to the Danger Zone section at the bottom.
  • Click Delete this repository.
  • Follow the confirmation prompts and type the repository name to confirm deletion.
Delete your Gemini API key
  • Go to Google AI Studio API Keys.
  • Find the API key you created for this project.
  • Click the delete icon next to it and confirm the deletion.
Delete your local project folder
  • Open your terminal and run the commands below to remove the project folder and all its contents, including the virtual environment.

macOS

cd ~/Desktop
rm -rf ecommerce-agent

Windows

cd ~\Desktop
rmdir /s /q ecommerce-agent

Nice Work!

Nice Work!

You just built and deployed a production-grade AI business intelligence agent that anyone can interact with at a live URL. That is a serious piece of work.

You've learned how to:

  • Build a working AI agent that autonomously decides which analysis tool to run against a real 3,500-order e-commerce dataset using Gemini function calling.
  • Write data analysis functions with pandas that extract real business insights like revenue breakdowns, top products, and category performance from raw CSV data.
  • Deploy a live web application with a shareable URL using Streamlit Community Cloud that anyone can visit and interact with.
  • Secret Mission: Extended the agent with chart generation capabilities using matplotlib, turning it into a visual business intelligence tool.

Ready to quiz yourself?