From 02355af09ebda532fdecc094bbb1adf34dab880c Mon Sep 17 00:00:00 2001 From: Nicholas Moore <25497602+nfmoore@users.noreply.github.com> Date: Wed, 10 Dec 2025 10:47:46 +1100 Subject: [PATCH 1/4] Add price comparison example --- nova-act/usecases/price_comparison/README.md | 162 +++++++++++++++++ nova-act/usecases/price_comparison/main.py | 172 ++++++++++++++++++ .../price_comparison/requirements.txt | 19 ++ 3 files changed, 353 insertions(+) create mode 100644 nova-act/usecases/price_comparison/README.md create mode 100644 nova-act/usecases/price_comparison/main.py create mode 100644 nova-act/usecases/price_comparison/requirements.txt diff --git a/nova-act/usecases/price_comparison/README.md b/nova-act/usecases/price_comparison/README.md new file mode 100644 index 00000000..0b8261e2 --- /dev/null +++ b/nova-act/usecases/price_comparison/README.md @@ -0,0 +1,162 @@ +# Price Comparison using Amazon Nova Act + +This project demonstrates automated price comparison across multiple retailers using Amazon Nova Act. It showcases how AI-powered browser agents can intelligently search for products, navigate retail websites, and extract pricing information to help consumers find the best deals. + +## Overview + +This demonstration implements a concurrent price comparison workflow that searches for products across major retailers (e.g. Amazon, Best Buy, Costco, Target) and compiles results into a sortable comparison table. + +### Key Benefits + +- **Automated Price Discovery**: AI agents navigate retail sites and extract current pricing +- **Concurrent Execution**: Parallel searches across multiple retailers reduce total execution time +- **Structured Output**: Results exported to CSV for easy analysis and comparison +- **Flexible Configuration**: Customize product searches and retailer sources + +## Architecture + +The demo consists of two main components: + +1. **Nova Act Browser Agents**: Automated browser sessions that navigate retail websites, handle captchas, and extract product information +2. **Concurrent Execution Engine**: ThreadPoolExecutor manages parallel searches across multiple retailers + +## Prerequisites + +Before running this demo, ensure you have: + +### Development Environment + +- **Python 3.11 or higher** +- **pip** (Python package manager) + +### API Access + +- **Amazon Nova Act API Key** - Visit [Nova Act home page](https://nova.amazon.com/act) to generate your API key + +## Getting Started + +Follow these steps to set up and run the price comparison tool: + +### Step 1: Install Dependencies + +```bash +# Navigate to the project directory +cd nova-act/usecases/price_comparison + +# Create and activate virtual environment +python -m venv venv +source venv/bin/activate # On Windows: venv\Scripts\activate + +# Install dependencies +pip install -r requirements.txt +``` + +### Step 2: Configure API Key + +Set your Nova Act API key as an environment variable: + +```bash +export NOVA_ACT_API_KEY="your-api-key-here" +``` + +### Step 3: Run Price Comparison + +```bash +# Run with default product (iPad Pro 13-inch M4, 256GB Wi-Fi) +python main.py + +# Run with custom product +python main.py --product_name "iPhone 15 Pro Max 256GB" --product_sku "MU793LL/A" + +# Run with custom sources +python main.py --sources '[("Walmart", "https://www.walmart.com"), ("Amazon", "https://www.amazon.com")]' + +# Run in non-headless mode (visible browser) +python main.py --headless=False +``` + +## Usage Examples + +### Default Search + +```bash +python main.py +``` + +Searches for "iPad Pro 13-inch (M4 chip), 256GB Wi-Fi" (SKU: MVX23LL/A) across Amazon, Best Buy, Costco, and Target. + +### Custom Product Search + +```bash +python main.py --product_name "MacBook Air 13-inch M3" --product_sku "MRXN3LL/A" +``` + +### Custom Retailer Sources + +```bash +python main.py --sources '[("Walmart", "https://www.walmart.com"), ("Newegg", "https://www.newegg.com")]' +``` + +### Debug Mode (Visible Browser) + +```bash +python main.py --headless=False +``` + +## Output + +Results are saved to `price_comparison_results.csv` with the following columns: + +| Column | Description | +| ----------------- | ---------------------------------------- | +| Source | Retailer name (Amazon, Best Buy, etc.) | +| Product Name | Matched product name from retailer | +| Product SKU | Search SKU used | +| Price | Current price (sorted lowest to highest) | +| Promotion Details | Any active promotions or discounts | + +## Project Structure + +``` +price_comparison/ +├── README.md # This file +├── main.py # Main application script +└── requirements.txt # Python dependencies +``` + +## How It Works + +1. **Initialization**: Creates Nova Act browser sessions for each retailer +2. **Captcha Handling**: Detects captchas and prompts user to solve if needed +3. **Product Search**: Searches using the product SKU on each retailer site +4. **Result Extraction**: AI agent identifies the most relevant product and extracts pricing +5. **Data Compilation**: Results are aggregated, sorted by price, and exported to CSV + +## Troubleshooting + +### Common Issues + +1. **Captcha Detected** + + - The tool will pause and prompt you to solve the captcha manually + - Press Enter after solving to continue + +2. **Product Not Found** + + - Verify the SKU is valid for the target retailers + - Some products may not be available at all retailers + +3. **Browser Session Errors** + + - Ensure you have a stable internet connection + - Try running in non-headless mode to debug: `--headless=False` + +4. **API Key Issues** + ```bash + export NOVA_ACT_API_KEY="your-api-key-here" + ``` + +## Additional Resources + +- [Amazon Nova Act](https://nova.amazon.com/act) +- [Nova Act Documentation](https://docs.aws.amazon.com/nova/latest/userguide/what-is-nova.html) diff --git a/nova-act/usecases/price_comparison/main.py b/nova-act/usecases/price_comparison/main.py new file mode 100644 index 00000000..1ac63eb6 --- /dev/null +++ b/nova-act/usecases/price_comparison/main.py @@ -0,0 +1,172 @@ +# Copyright 2025 Amazon Inc + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Compare product prices across multiple retailers. + +Searches for a product across Target, Best Buy, and Costco concurrently +and displays pricing and promotion details in a comparison table. + +Usage: + python -m nova_act.samples.price_comparison.py [--product_name ] [--product_sku ] [--sources ] [--headless] + python -m nova_act.samples.price_comparison.py --product_name "iPad Pro 13-inch, 256GB Wi-Fi" --product_sku "MVX23LL/A" + python -m nova_act.samples.price_comparison.py --sources '[("Walmart", "https://www.walmart.com"), ("Amazon", "https://www.amazon.com")]' + python -m nova_act.samples.price_comparison.py --headless +""" + +from concurrent.futures import ThreadPoolExecutor, as_completed + +import fire +import pandas as pd +from nova_act import BOOL_SCHEMA, ActAgentError, NovaAct +from pydantic import BaseModel + +# Global defaults +DEFAULT_PRODUCT_NAME = "iPad Pro 13-inch (M4 chip), 256GB Wi-Fi" +DEFAULT_PRODUCT_SKU = "MVX23LL/A" +DEFAULT_PRODUCT_SOURCES = [ + ("Amazon", "https://www.amazon.com"), + ("Best Buy", "https://www.bestbuy.com"), + ("Costco", "https://www.costco.com"), + ("Target", "https://www.target.com"), +] + + +class ProductPricing(BaseModel): + product_name: str | None + price: float | None + promotion_details: str | None + source: str # Target, Best Buy, or Costco + + +def check_source_price( + product_name: str, + product_sku: str, + source: str, + starting_url: str, + headless: bool = True, +) -> ProductPricing | None: + """Check price for a product at a specific source.""" + + try: + with NovaAct(starting_page=starting_url, headless=headless) as nova: + # Check for captcha + captcha_check = nova.act( + "Is there a captcha on the screen?", schema=BOOL_SCHEMA + ) + if captcha_check.matches_schema and captcha_check.parsed_response: + input(f"Please solve the captcha for {source} and hit return when done") + + # Search using product SKU + nova.act(f"Search for '{product_sku}'.") + + # Extract pricing and details from the most relevant result based on product name + result = nova.act( + f""" + Close any popups if they appear. + Review all search results and determine which one is the most relevant to the product name '{product_name}'. + Select this item to navigate to the product page. + Then, extract the price and any promotion details from the most relevant result that matches the product name '{product_name}'. + If no matching product exists, return None for all fields except source. Do not attempt to re-search using a different keyword combination. + """, + schema=ProductPricing.model_json_schema(), + ) + + if not result.matches_schema: + print(f"Invalid JSON from {source}: {result}") + return None + + pricing = ProductPricing.model_validate(result.parsed_response) + return pricing + + except ActAgentError as exc: + print(f"Could not retrieve pricing from {source}: {exc}") + return None + + +def main( + product_name: str | None = None, + product_sku: str | None = None, + sources: list[tuple[str, str]] = DEFAULT_PRODUCT_SOURCES, + headless: bool = True, +) -> None: + """Search for product prices across multiple sources concurrently.""" + # Validate that both product_name and product_sku are provided together + if (product_name is None) != (product_sku is None): + raise ValueError( + "Both product_name and product_sku must be provided together. " + "You cannot specify only one without the other." + ) + + # Use defaults if neither was provided + if product_name is None: + product_name = DEFAULT_PRODUCT_NAME + product_sku = DEFAULT_PRODUCT_SKU + + all_prices = [] + + print( + f"Searching for '{product_name}' (SKU: {product_sku}) across {len(sources)} sources...\n" + ) + + with ThreadPoolExecutor() as executor: + future_to_source = { + executor.submit( + check_source_price, + product_name, + product_sku, + source_name, + source_url, + headless, + ): source_name + for source_name, source_url in sources + } + + for future in as_completed(future_to_source.keys()): + source = future_to_source[future] + pricing = future.result() + + if pricing is not None: + result_dict = pricing.model_dump() + result_dict["sku"] = product_sku + all_prices.append(result_dict) + else: + all_prices.append( + { + "source": source, + "product_name": None, + "sku": product_sku, + "price": None, + "promotion_details": None, + } + ) + + # Create DataFrame and sort by price + df = pd.DataFrame(all_prices) + df = df.sort_values(by="price", na_position="last") + + # Reorder columns + df = df[["source", "product_name", "sku", "price", "promotion_details"]] + + # Rename columns for better readability in output + df.columns = ["Source", "Product Name", "Product SKU", "Price", "Promotion Details"] + + # Write results to CSV + output_file = "price_comparison_results.csv" + df.to_csv(output_file, index=False) + + print(f"\nResults written to {output_file}") + + +if __name__ == "__main__": + fire.Fire(main) diff --git a/nova-act/usecases/price_comparison/requirements.txt b/nova-act/usecases/price_comparison/requirements.txt new file mode 100644 index 00000000..1852822a --- /dev/null +++ b/nova-act/usecases/price_comparison/requirements.txt @@ -0,0 +1,19 @@ +cryptography +fire +install_playwright +jsonschema +numpy<=2.2.6 +pandas +pillow +playwright>=1.54.0 +pydantic>=2.10.6 +requests +retry +pytz +strands-agents>=0.1.9 +strands-agents-tools +Deprecated +boto3 +boto3-stubs +mypy-boto3-s3 +nova-act==3.0.5.0 From 08ba26dbfcae2352b6c5ca4d78bd0a27bf994d09 Mon Sep 17 00:00:00 2001 From: Nicholas Moore <25497602+nfmoore@users.noreply.github.com> Date: Wed, 10 Dec 2025 10:51:55 +1100 Subject: [PATCH 2/4] Add price comparison use case to agentic workflows readme --- nova-act/README.md | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/nova-act/README.md b/nova-act/README.md index 55d90f60..8f67afc8 100644 --- a/nova-act/README.md +++ b/nova-act/README.md @@ -12,6 +12,7 @@ Nova Act enables developers to build intelligent agents that can interact with w - **Integrate seamlessly** with Python code for testing, assertions, and debugging The SDK works in conjunction with **Amazon Bedrock AgentCore Browser**, a secure, cloud-based browser environment that provides: + - Session isolation and security - Built-in observability (live viewing, CloudTrail logging, session replay) - Containerized ephemeral environments @@ -38,12 +39,14 @@ Automate quality assurance testing for web applications using Nova Act and Agent - **Integration with pytest** for comprehensive test reporting and CI/CD pipelines **Key Benefits:** + - Reduce test maintenance overhead by 40-60% - Execute comprehensive test suites in minutes instead of hours - Eliminate false negatives from UI changes - Scale testing across browsers, devices, and environments effortlessly **What's Included:** + - Sample retail web application for testing - 15 ready-to-use JSON test cases - Pytest framework with parallel execution support @@ -52,15 +55,44 @@ Automate quality assurance testing for web applications using Nova Act and Agent [→ Explore the QA Testing Use Case](./usecases/qa-testing/) +### 💰 [Price Comparison](./usecases/price_comparison/) + +Automate product price comparison across multiple retailers using Nova Act. This use case showcases: + +- **Intelligent product search** that navigates retail websites and finds matching products +- **Concurrent execution** across multiple retailers for faster price discovery +- **Structured data extraction** using Pydantic schemas for reliable pricing information +- **Captcha handling** with user prompts for manual intervention when needed +- **CSV export** for easy analysis and comparison of results + +**Key Benefits:** + +- Compare prices across Amazon, Best Buy, Costco, Target, and more in minutes +- Reduce manual price checking effort by automating browser navigation +- Get structured output with product names, prices, and promotion details +- Easily customize product searches and retailer sources via CLI arguments + +**What's Included:** + +- Ready-to-run price comparison script +- Support for custom product SKUs and retailer sources +- Pydantic-based data validation for extracted pricing +- ThreadPoolExecutor for parallel retailer searches +- Complete setup and usage instructions + +[→ Explore the Price Comparison Use Case](./usecases/price_comparison/) + ## Why Agentic Workflows? Traditional automation approaches face significant challenges: + - **High maintenance overhead**: Scripts break with UI changes, requiring constant updates - **Limited scalability**: Manual testing is time-intensive and incomplete - **Technical barriers**: Creating automation requires specialized programming knowledge - **Brittleness**: Automation relies on specific selectors that fail when components change Agentic AI with Nova Act addresses these challenges by: + - **Adapting dynamically** to interface changes without manual updates - **Mimicking human interaction** patterns for realistic testing - **Enabling non-technical users** to create tests through simple JSON definitions @@ -81,6 +113,7 @@ This project is licensed under the MIT-0 License. See the [LICENSE](../LICENSE) ## Support For questions, issues, or feature requests: + - Open an issue in this repository - Refer to the [official Nova Act documentation](https://github.com/aws/nova-act) - Contact AWS Support for enterprise assistance From ead4ec8ce80ae2d4c51ecdf1630a284f52b17a2d Mon Sep 17 00:00:00 2001 From: Nicholas Moore <25497602+nfmoore@users.noreply.github.com> Date: Wed, 10 Dec 2025 10:56:30 +1100 Subject: [PATCH 3/4] Update price comparison example docstring usagae examples --- nova-act/usecases/price_comparison/main.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/nova-act/usecases/price_comparison/main.py b/nova-act/usecases/price_comparison/main.py index 1ac63eb6..98be7fa9 100644 --- a/nova-act/usecases/price_comparison/main.py +++ b/nova-act/usecases/price_comparison/main.py @@ -14,14 +14,14 @@ """Compare product prices across multiple retailers. -Searches for a product across Target, Best Buy, and Costco concurrently +Searches for a product across Amazon, Best Buy, Costco, and Target concurrently and displays pricing and promotion details in a comparison table. Usage: - python -m nova_act.samples.price_comparison.py [--product_name ] [--product_sku ] [--sources ] [--headless] - python -m nova_act.samples.price_comparison.py --product_name "iPad Pro 13-inch, 256GB Wi-Fi" --product_sku "MVX23LL/A" - python -m nova_act.samples.price_comparison.py --sources '[("Walmart", "https://www.walmart.com"), ("Amazon", "https://www.amazon.com")]' - python -m nova_act.samples.price_comparison.py --headless + python main.py [--product_name ] [--product_sku ] [--sources ] [--headless] + python main.py --product_name "iPad Pro 13-inch, 256GB Wi-Fi" --product_sku "MVX23LL/A" + python main.py --sources '[("Walmart", "https://www.walmart.com"), ("Amazon", "https://www.amazon.com")]' + python main.py --headless=False """ from concurrent.futures import ThreadPoolExecutor, as_completed From b0a70345a90a6cede4683cbb42b475bdd8f954e2 Mon Sep 17 00:00:00 2001 From: Nicholas Moore <25497602+nfmoore@users.noreply.github.com> Date: Wed, 17 Dec 2025 10:36:07 +1100 Subject: [PATCH 4/4] Update to nova-act 3.0.67.0 and refactor API calls - Upgrade nova-act dependency from 3.0.5.0 to 3.0.67.0 - Replace nova.act() calls with nova.act_get() for improved API consistency - Comment out Amazon source from default product sources list - Update captcha detection to use new act_get() method - Update product search to use new act_get() method - Update pricing extraction to use new act_get() method - Align with latest nova-act API changes for better response handling --- nova-act/usecases/price_comparison/main.py | 8 ++++---- nova-act/usecases/price_comparison/requirements.txt | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/nova-act/usecases/price_comparison/main.py b/nova-act/usecases/price_comparison/main.py index 98be7fa9..08f4747b 100644 --- a/nova-act/usecases/price_comparison/main.py +++ b/nova-act/usecases/price_comparison/main.py @@ -35,7 +35,7 @@ DEFAULT_PRODUCT_NAME = "iPad Pro 13-inch (M4 chip), 256GB Wi-Fi" DEFAULT_PRODUCT_SKU = "MVX23LL/A" DEFAULT_PRODUCT_SOURCES = [ - ("Amazon", "https://www.amazon.com"), + # ("Amazon", "https://www.amazon.com"), ("Best Buy", "https://www.bestbuy.com"), ("Costco", "https://www.costco.com"), ("Target", "https://www.target.com"), @@ -61,17 +61,17 @@ def check_source_price( try: with NovaAct(starting_page=starting_url, headless=headless) as nova: # Check for captcha - captcha_check = nova.act( + captcha_check = nova.act_get( "Is there a captcha on the screen?", schema=BOOL_SCHEMA ) if captcha_check.matches_schema and captcha_check.parsed_response: input(f"Please solve the captcha for {source} and hit return when done") # Search using product SKU - nova.act(f"Search for '{product_sku}'.") + nova.act_get(f"Search for '{product_sku}'.") # Extract pricing and details from the most relevant result based on product name - result = nova.act( + result = nova.act_get( f""" Close any popups if they appear. Review all search results and determine which one is the most relevant to the product name '{product_name}'. diff --git a/nova-act/usecases/price_comparison/requirements.txt b/nova-act/usecases/price_comparison/requirements.txt index 1852822a..cfb05637 100644 --- a/nova-act/usecases/price_comparison/requirements.txt +++ b/nova-act/usecases/price_comparison/requirements.txt @@ -16,4 +16,4 @@ Deprecated boto3 boto3-stubs mypy-boto3-s3 -nova-act==3.0.5.0 +nova-act==3.0.67.0