create script for test data
This commit is contained in:
459
backend/create_test_data.py
Normal file
459
backend/create_test_data.py
Normal file
@@ -0,0 +1,459 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Script to create comprehensive test data for the Grocery Tracker application.
|
||||
This includes shops, groceries, and shopping events with realistic data.
|
||||
"""
|
||||
|
||||
import requests
|
||||
import json
|
||||
import random
|
||||
import argparse
|
||||
import sys
|
||||
from datetime import datetime, timedelta
|
||||
from typing import List, Dict, Any
|
||||
|
||||
BASE_URL = "http://localhost:8000"
|
||||
|
||||
# Test data definitions
|
||||
SHOPS_DATA = [
|
||||
{"name": "Whole Foods Market", "city": "San Francisco", "address": "1765 California St"},
|
||||
{"name": "Safeway", "city": "San Francisco", "address": "2020 Market St"},
|
||||
{"name": "Trader Joe's", "city": "Berkeley", "address": "1885 University Ave"},
|
||||
{"name": "Berkeley Bowl", "city": "Berkeley", "address": "2020 Oregon St"},
|
||||
{"name": "Rainbow Grocery", "city": "San Francisco", "address": "1745 Folsom St"},
|
||||
{"name": "Mollie Stone's Market", "city": "Palo Alto", "address": "164 S California Ave"},
|
||||
{"name": "Costco Wholesale", "city": "San Mateo", "address": "2300 S Norfolk St"},
|
||||
{"name": "Target", "city": "Mountain View", "address": "1200 El Camino Real"},
|
||||
{"name": "Sprouts Farmers Market", "city": "Sunnyvale", "address": "1077 E El Camino Real"},
|
||||
{"name": "Lucky Supermarket", "city": "San Jose", "address": "1717 Tully Rd"},
|
||||
]
|
||||
|
||||
GROCERIES_DATA = [
|
||||
# Fruits
|
||||
{"name": "Organic Bananas", "category": "Fruits", "organic": True, "weight": 1.0, "weight_unit": "lb"},
|
||||
{"name": "Gala Apples", "category": "Fruits", "organic": False, "weight": 2.0, "weight_unit": "lb"},
|
||||
{"name": "Organic Strawberries", "category": "Fruits", "organic": True, "weight": 1.0, "weight_unit": "lb"},
|
||||
{"name": "Avocados", "category": "Fruits", "organic": False, "weight": None, "weight_unit": "piece"},
|
||||
{"name": "Organic Blueberries", "category": "Fruits", "organic": True, "weight": 0.5, "weight_unit": "lb"},
|
||||
{"name": "Lemons", "category": "Fruits", "organic": False, "weight": None, "weight_unit": "piece"},
|
||||
{"name": "Organic Oranges", "category": "Fruits", "organic": True, "weight": 3.0, "weight_unit": "lb"},
|
||||
{"name": "Grapes", "category": "Fruits", "organic": False, "weight": 2.0, "weight_unit": "lb"},
|
||||
{"name": "Organic Pears", "category": "Fruits", "organic": True, "weight": 2.0, "weight_unit": "lb"},
|
||||
{"name": "Pineapple", "category": "Fruits", "organic": False, "weight": None, "weight_unit": "piece"},
|
||||
|
||||
# Vegetables
|
||||
{"name": "Organic Spinach", "category": "Vegetables", "organic": True, "weight": 5.0, "weight_unit": "oz"},
|
||||
{"name": "Carrots", "category": "Vegetables", "organic": False, "weight": 2.0, "weight_unit": "lb"},
|
||||
{"name": "Organic Broccoli", "category": "Vegetables", "organic": True, "weight": None, "weight_unit": "piece"},
|
||||
{"name": "Red Bell Peppers", "category": "Vegetables", "organic": False, "weight": None, "weight_unit": "piece"},
|
||||
{"name": "Organic Kale", "category": "Vegetables", "organic": True, "weight": 1.0, "weight_unit": "bunch"},
|
||||
{"name": "Tomatoes", "category": "Vegetables", "organic": False, "weight": 2.0, "weight_unit": "lb"},
|
||||
{"name": "Organic Sweet Potatoes", "category": "Vegetables", "organic": True, "weight": 3.0, "weight_unit": "lb"},
|
||||
{"name": "Cucumbers", "category": "Vegetables", "organic": False, "weight": None, "weight_unit": "piece"},
|
||||
{"name": "Organic Lettuce", "category": "Vegetables", "organic": True, "weight": None, "weight_unit": "head"},
|
||||
{"name": "Onions", "category": "Vegetables", "organic": False, "weight": 3.0, "weight_unit": "lb"},
|
||||
|
||||
# Dairy
|
||||
{"name": "Organic Whole Milk", "category": "Dairy", "organic": True, "weight": 1.0, "weight_unit": "gallon"},
|
||||
{"name": "Greek Yogurt", "category": "Dairy", "organic": False, "weight": 32.0, "weight_unit": "oz"},
|
||||
{"name": "Organic Eggs", "category": "Dairy", "organic": True, "weight": None, "weight_unit": "dozen"},
|
||||
{"name": "Cheddar Cheese", "category": "Dairy", "organic": False, "weight": 8.0, "weight_unit": "oz"},
|
||||
{"name": "Organic Butter", "category": "Dairy", "organic": True, "weight": 1.0, "weight_unit": "lb"},
|
||||
{"name": "Cream Cheese", "category": "Dairy", "organic": False, "weight": 8.0, "weight_unit": "oz"},
|
||||
{"name": "Organic Yogurt", "category": "Dairy", "organic": True, "weight": 6.0, "weight_unit": "oz"},
|
||||
|
||||
# Meat & Seafood
|
||||
{"name": "Organic Chicken Breast", "category": "Meat & Seafood", "organic": True, "weight": 2.0, "weight_unit": "lb"},
|
||||
{"name": "Ground Beef", "category": "Meat & Seafood", "organic": False, "weight": 1.0, "weight_unit": "lb"},
|
||||
{"name": "Wild Salmon Fillet", "category": "Meat & Seafood", "organic": False, "weight": 1.5, "weight_unit": "lb"},
|
||||
{"name": "Organic Ground Turkey", "category": "Meat & Seafood", "organic": True, "weight": 1.0, "weight_unit": "lb"},
|
||||
{"name": "Shrimp", "category": "Meat & Seafood", "organic": False, "weight": 1.0, "weight_unit": "lb"},
|
||||
{"name": "Organic Chicken Thighs", "category": "Meat & Seafood", "organic": True, "weight": 2.0, "weight_unit": "lb"},
|
||||
|
||||
# Pantry
|
||||
{"name": "Organic Brown Rice", "category": "Pantry", "organic": True, "weight": 2.0, "weight_unit": "lb"},
|
||||
{"name": "Whole Wheat Bread", "category": "Pantry", "organic": False, "weight": 24.0, "weight_unit": "oz"},
|
||||
{"name": "Organic Quinoa", "category": "Pantry", "organic": True, "weight": 1.0, "weight_unit": "lb"},
|
||||
{"name": "Olive Oil", "category": "Pantry", "organic": False, "weight": 500.0, "weight_unit": "ml"},
|
||||
{"name": "Organic Pasta", "category": "Pantry", "organic": True, "weight": 1.0, "weight_unit": "lb"},
|
||||
{"name": "Black Beans", "category": "Pantry", "organic": False, "weight": 15.0, "weight_unit": "oz"},
|
||||
{"name": "Organic Oats", "category": "Pantry", "organic": True, "weight": 18.0, "weight_unit": "oz"},
|
||||
{"name": "Peanut Butter", "category": "Pantry", "organic": False, "weight": 18.0, "weight_unit": "oz"},
|
||||
{"name": "Organic Honey", "category": "Pantry", "organic": True, "weight": 12.0, "weight_unit": "oz"},
|
||||
{"name": "Canned Tomatoes", "category": "Pantry", "organic": False, "weight": 14.5, "weight_unit": "oz"},
|
||||
|
||||
# Beverages
|
||||
{"name": "Organic Orange Juice", "category": "Beverages", "organic": True, "weight": 64.0, "weight_unit": "oz"},
|
||||
{"name": "Sparkling Water", "category": "Beverages", "organic": False, "weight": 1.0, "weight_unit": "l"},
|
||||
{"name": "Organic Green Tea", "category": "Beverages", "organic": True, "weight": None, "weight_unit": "box"},
|
||||
{"name": "Coffee Beans", "category": "Beverages", "organic": False, "weight": 12.0, "weight_unit": "oz"},
|
||||
{"name": "Almond Milk", "category": "Beverages", "organic": False, "weight": 32.0, "weight_unit": "oz"},
|
||||
{"name": "Organic Apple Juice", "category": "Beverages", "organic": True, "weight": 64.0, "weight_unit": "oz"},
|
||||
|
||||
# Frozen
|
||||
{"name": "Organic Frozen Berries", "category": "Frozen", "organic": True, "weight": 10.0, "weight_unit": "oz"},
|
||||
{"name": "Frozen Pizza", "category": "Frozen", "organic": False, "weight": 12.0, "weight_unit": "oz"},
|
||||
{"name": "Organic Frozen Vegetables", "category": "Frozen", "organic": True, "weight": 16.0, "weight_unit": "oz"},
|
||||
{"name": "Ice Cream", "category": "Frozen", "organic": False, "weight": 48.0, "weight_unit": "oz"},
|
||||
{"name": "Frozen Fish Fillets", "category": "Frozen", "organic": False, "weight": 1.0, "weight_unit": "lb"},
|
||||
|
||||
# Snacks
|
||||
{"name": "Organic Granola Bars", "category": "Snacks", "organic": True, "weight": 8.0, "weight_unit": "oz"},
|
||||
{"name": "Potato Chips", "category": "Snacks", "organic": False, "weight": 5.0, "weight_unit": "oz"},
|
||||
{"name": "Organic Nuts", "category": "Snacks", "organic": True, "weight": 6.0, "weight_unit": "oz"},
|
||||
{"name": "Crackers", "category": "Snacks", "organic": False, "weight": 7.0, "weight_unit": "oz"},
|
||||
{"name": "Organic Popcorn", "category": "Snacks", "organic": True, "weight": 3.0, "weight_unit": "oz"},
|
||||
]
|
||||
|
||||
# Price ranges for different categories (min, max)
|
||||
PRICE_RANGES = {
|
||||
"Fruits": (1.99, 8.99),
|
||||
"Vegetables": (0.99, 6.99),
|
||||
"Dairy": (2.49, 12.99),
|
||||
"Meat & Seafood": (4.99, 24.99),
|
||||
"Pantry": (1.99, 15.99),
|
||||
"Beverages": (1.99, 8.99),
|
||||
"Frozen": (2.99, 9.99),
|
||||
"Snacks": (1.49, 7.99),
|
||||
}
|
||||
|
||||
def parse_arguments():
|
||||
"""Parse command line arguments."""
|
||||
parser = argparse.ArgumentParser(description='Create test data for Grocery Tracker')
|
||||
parser.add_argument('--events', type=int, default=30, help='Number of shopping events to create (default: 30)')
|
||||
parser.add_argument('--days', type=int, default=90, help='Number of days back to generate events (default: 90)')
|
||||
parser.add_argument('--url', type=str, default=BASE_URL, help='API base URL (default: http://localhost:8000)')
|
||||
parser.add_argument('--shops-only', action='store_true', help='Create only shops')
|
||||
parser.add_argument('--groceries-only', action='store_true', help='Create only groceries')
|
||||
parser.add_argument('--events-only', action='store_true', help='Create only shopping events (requires existing shops and groceries)')
|
||||
parser.add_argument('--verbose', '-v', action='store_true', help='Verbose output')
|
||||
parser.add_argument('--dry-run', action='store_true', help='Show what would be created without actually creating it')
|
||||
return parser.parse_args()
|
||||
|
||||
def check_api_connection(base_url: str) -> bool:
|
||||
"""Check if the API server is accessible."""
|
||||
try:
|
||||
response = requests.get(f"{base_url}/", timeout=5)
|
||||
return response.status_code == 200
|
||||
except requests.exceptions.RequestException:
|
||||
return False
|
||||
|
||||
def create_shops(base_url: str, verbose: bool = False, dry_run: bool = False) -> List[Dict[str, Any]]:
|
||||
"""Create shops and return the created shop objects."""
|
||||
print("🏪 Creating shops...")
|
||||
created_shops = []
|
||||
|
||||
if dry_run:
|
||||
print(" [DRY RUN] Would create the following shops:")
|
||||
for shop_data in SHOPS_DATA:
|
||||
print(f" 📋 {shop_data['name']} in {shop_data['city']}")
|
||||
return []
|
||||
|
||||
for shop_data in SHOPS_DATA:
|
||||
try:
|
||||
if verbose:
|
||||
print(f" 🔄 Creating shop: {shop_data['name']}...")
|
||||
|
||||
response = requests.post(f"{base_url}/shops/", json=shop_data, timeout=10)
|
||||
if response.status_code == 200:
|
||||
shop = response.json()
|
||||
created_shops.append(shop)
|
||||
print(f" ✅ Created shop: {shop['name']} in {shop['city']}")
|
||||
else:
|
||||
print(f" ❌ Failed to create shop {shop_data['name']}: {response.status_code}")
|
||||
if verbose:
|
||||
print(f" Response: {response.text}")
|
||||
except requests.exceptions.RequestException as e:
|
||||
print(f" ❌ Network error creating shop {shop_data['name']}: {e}")
|
||||
except Exception as e:
|
||||
print(f" ❌ Error creating shop {shop_data['name']}: {e}")
|
||||
|
||||
print(f" 📊 Created {len(created_shops)} shops total\n")
|
||||
return created_shops
|
||||
|
||||
def create_groceries(base_url: str, verbose: bool = False, dry_run: bool = False) -> List[Dict[str, Any]]:
|
||||
"""Create groceries and return the created grocery objects."""
|
||||
print("🥬 Creating groceries...")
|
||||
created_groceries = []
|
||||
|
||||
if dry_run:
|
||||
print(" [DRY RUN] Would create the following groceries:")
|
||||
for grocery_data in GROCERIES_DATA:
|
||||
organic_label = "🌱" if grocery_data['organic'] else "🌾"
|
||||
print(f" 📋 {organic_label} {grocery_data['name']} ({grocery_data['category']})")
|
||||
return []
|
||||
|
||||
for grocery_data in GROCERIES_DATA:
|
||||
try:
|
||||
if verbose:
|
||||
print(f" 🔄 Creating grocery: {grocery_data['name']}...")
|
||||
|
||||
response = requests.post(f"{base_url}/groceries/", json=grocery_data, timeout=10)
|
||||
if response.status_code == 200:
|
||||
grocery = response.json()
|
||||
created_groceries.append(grocery)
|
||||
organic_label = "🌱" if grocery['organic'] else "🌾"
|
||||
print(f" ✅ Created grocery: {organic_label} {grocery['name']} ({grocery['category']})")
|
||||
else:
|
||||
print(f" ❌ Failed to create grocery {grocery_data['name']}: {response.status_code}")
|
||||
if verbose:
|
||||
print(f" Response: {response.text}")
|
||||
except requests.exceptions.RequestException as e:
|
||||
print(f" ❌ Network error creating grocery {grocery_data['name']}: {e}")
|
||||
except Exception as e:
|
||||
print(f" ❌ Error creating grocery {grocery_data['name']}: {e}")
|
||||
|
||||
print(f" 📊 Created {len(created_groceries)} groceries total\n")
|
||||
return created_groceries
|
||||
|
||||
def generate_random_price(category: str, organic: bool = False) -> float:
|
||||
"""Generate a random price for a grocery item based on category and organic status."""
|
||||
min_price, max_price = PRICE_RANGES.get(category, (1.99, 9.99))
|
||||
|
||||
# Organic items are typically 20-50% more expensive
|
||||
if organic:
|
||||
min_price *= 1.2
|
||||
max_price *= 1.5
|
||||
|
||||
# Generate random price and round to nearest cent
|
||||
price = random.uniform(min_price, max_price)
|
||||
return round(price, 2)
|
||||
|
||||
def get_existing_data(base_url: str) -> tuple[List[Dict], List[Dict]]:
|
||||
"""Get existing shops and groceries from the API."""
|
||||
try:
|
||||
shops_response = requests.get(f"{base_url}/shops/", timeout=10)
|
||||
groceries_response = requests.get(f"{base_url}/groceries/", timeout=10)
|
||||
|
||||
shops = shops_response.json() if shops_response.status_code == 200 else []
|
||||
groceries = groceries_response.json() if groceries_response.status_code == 200 else []
|
||||
|
||||
return shops, groceries
|
||||
except requests.exceptions.RequestException as e:
|
||||
print(f" ❌ Error fetching existing data: {e}")
|
||||
return [], []
|
||||
|
||||
def create_shopping_events(shops: List[Dict], groceries: List[Dict], base_url: str,
|
||||
num_events: int = 25, days_back: int = 90,
|
||||
verbose: bool = False, dry_run: bool = False) -> List[Dict[str, Any]]:
|
||||
"""Create shopping events with random groceries and realistic data."""
|
||||
print(f"🛒 Creating {num_events} shopping events...")
|
||||
created_events = []
|
||||
|
||||
if not shops:
|
||||
print(" ❌ No shops available. Cannot create shopping events.")
|
||||
return []
|
||||
|
||||
if not groceries:
|
||||
print(" ❌ No groceries available. Cannot create shopping events.")
|
||||
return []
|
||||
|
||||
# Generate events over the specified time period
|
||||
end_date = datetime.now()
|
||||
start_date = end_date - timedelta(days=days_back)
|
||||
|
||||
if dry_run:
|
||||
print(f" [DRY RUN] Would create {num_events} shopping events over {days_back} days")
|
||||
print(f" 📋 Date range: {start_date.strftime('%Y-%m-%d')} to {end_date.strftime('%Y-%m-%d')}")
|
||||
print(f" 📋 Available shops: {len(shops)}")
|
||||
print(f" 📋 Available groceries: {len(groceries)}")
|
||||
return []
|
||||
|
||||
for i in range(num_events):
|
||||
try:
|
||||
if verbose:
|
||||
print(f" 🔄 Creating shopping event {i+1}/{num_events}...")
|
||||
|
||||
# Random shop and date
|
||||
shop = random.choice(shops)
|
||||
event_date = start_date + timedelta(
|
||||
days=random.randint(0, days_back),
|
||||
hours=random.randint(8, 20),
|
||||
minutes=random.randint(0, 59)
|
||||
)
|
||||
|
||||
# Random number of groceries (2-8 items per shopping trip)
|
||||
num_groceries = random.randint(2, 8)
|
||||
selected_groceries = random.sample(groceries, min(num_groceries, len(groceries)))
|
||||
|
||||
# Create grocery items for this event
|
||||
event_groceries = []
|
||||
total_amount = 0.0
|
||||
|
||||
for grocery in selected_groceries:
|
||||
# Random amount based on item type
|
||||
if grocery['weight_unit'] == 'piece':
|
||||
amount = random.randint(1, 4)
|
||||
elif grocery['weight_unit'] == 'dozen':
|
||||
amount = 1
|
||||
elif grocery['weight_unit'] in ['box', 'head', 'bunch']:
|
||||
amount = random.randint(1, 2)
|
||||
elif grocery['weight_unit'] in ['gallon', 'l']:
|
||||
amount = 1
|
||||
else:
|
||||
amount = round(random.uniform(0.5, 3.0), 2)
|
||||
|
||||
# Generate price based on category and organic status
|
||||
price = generate_random_price(grocery['category'], grocery['organic'])
|
||||
|
||||
event_groceries.append({
|
||||
"grocery_id": grocery['id'],
|
||||
"amount": amount,
|
||||
"price": price
|
||||
})
|
||||
|
||||
total_amount += amount * price
|
||||
|
||||
# Round total amount
|
||||
total_amount = round(total_amount, 2)
|
||||
|
||||
# Random notes (30% chance of having notes)
|
||||
notes = None
|
||||
if random.random() < 0.3:
|
||||
note_options = [
|
||||
"Weekly grocery shopping",
|
||||
"Quick lunch ingredients",
|
||||
"Dinner party prep",
|
||||
"Meal prep for the week",
|
||||
"Emergency grocery run",
|
||||
"Organic produce haul",
|
||||
"Bulk shopping trip",
|
||||
"Special occasion shopping",
|
||||
"Holiday meal preparation",
|
||||
"Healthy eating restart",
|
||||
"Stocking up on essentials",
|
||||
"Trying new recipes",
|
||||
]
|
||||
notes = random.choice(note_options)
|
||||
|
||||
# Create the shopping event
|
||||
event_data = {
|
||||
"shop_id": shop['id'],
|
||||
"date": event_date.isoformat(),
|
||||
"total_amount": total_amount,
|
||||
"notes": notes,
|
||||
"groceries": event_groceries
|
||||
}
|
||||
|
||||
response = requests.post(f"{base_url}/shopping-events/", json=event_data, timeout=15)
|
||||
if response.status_code == 200:
|
||||
event = response.json()
|
||||
created_events.append(event)
|
||||
print(f" ✅ Created event #{event['id']}: {shop['name']} - ${total_amount:.2f} ({len(event_groceries)} items)")
|
||||
else:
|
||||
print(f" ❌ Failed to create shopping event: {response.status_code}")
|
||||
if verbose:
|
||||
print(f" Response: {response.text}")
|
||||
except requests.exceptions.RequestException as e:
|
||||
print(f" ❌ Network error creating shopping event {i+1}: {e}")
|
||||
except Exception as e:
|
||||
print(f" ❌ Error creating shopping event {i+1}: {e}")
|
||||
|
||||
print(f" 📊 Created {len(created_events)} shopping events total\n")
|
||||
return created_events
|
||||
|
||||
def print_summary(shops: List[Dict], groceries: List[Dict], events: List[Dict]):
|
||||
"""Print a summary of the created test data."""
|
||||
print("📋 TEST DATA SUMMARY")
|
||||
print("=" * 50)
|
||||
|
||||
print(f"🏪 Shops: {len(shops)}")
|
||||
for shop in shops:
|
||||
print(f" • {shop['name']} ({shop['city']})")
|
||||
|
||||
print(f"\n🥬 Groceries: {len(groceries)}")
|
||||
categories = {}
|
||||
for grocery in groceries:
|
||||
category = grocery['category']
|
||||
if category not in categories:
|
||||
categories[category] = []
|
||||
categories[category].append(grocery)
|
||||
|
||||
for category, items in categories.items():
|
||||
organic_count = sum(1 for item in items if item['organic'])
|
||||
print(f" • {category}: {len(items)} items ({organic_count} organic)")
|
||||
|
||||
print(f"\n🛒 Shopping Events: {len(events)}")
|
||||
if events:
|
||||
total_spent = sum(event.get('total_amount', 0) for event in events)
|
||||
avg_spent = total_spent / len(events) if events else 0
|
||||
print(f" • Total spent: ${total_spent:.2f}")
|
||||
print(f" • Average per trip: ${avg_spent:.2f}")
|
||||
|
||||
# Shop distribution
|
||||
shop_counts = {}
|
||||
for event in events:
|
||||
shop_name = event['shop']['name']
|
||||
shop_counts[shop_name] = shop_counts.get(shop_name, 0) + 1
|
||||
|
||||
print(" • Events per shop:")
|
||||
for shop_name, count in sorted(shop_counts.items(), key=lambda x: x[1], reverse=True):
|
||||
print(f" - {shop_name}: {count} events")
|
||||
|
||||
def main():
|
||||
"""Main function to create all test data."""
|
||||
args = parse_arguments()
|
||||
|
||||
print("🚀 GROCERY TRACKER TEST DATA GENERATOR")
|
||||
print("=" * 50)
|
||||
|
||||
if args.dry_run:
|
||||
print("🔍 DRY RUN MODE - No data will be created")
|
||||
|
||||
print(f"API URL: {args.url}")
|
||||
print(f"Shopping events: {args.events}")
|
||||
print(f"Date range: {args.days} days back")
|
||||
print()
|
||||
|
||||
try:
|
||||
# Test connection
|
||||
if not check_api_connection(args.url):
|
||||
print(f"❌ Cannot connect to the API server at {args.url}")
|
||||
print(" Make sure the backend server is running!")
|
||||
sys.exit(1)
|
||||
|
||||
print("✅ Connected to API server\n")
|
||||
|
||||
shops = []
|
||||
groceries = []
|
||||
events = []
|
||||
|
||||
# Create data based on arguments
|
||||
if args.shops_only:
|
||||
shops = create_shops(args.url, args.verbose, args.dry_run)
|
||||
elif args.groceries_only:
|
||||
groceries = create_groceries(args.url, args.verbose, args.dry_run)
|
||||
elif args.events_only:
|
||||
# Get existing data for events
|
||||
shops, groceries = get_existing_data(args.url)
|
||||
events = create_shopping_events(shops, groceries, args.url, args.events, args.days, args.verbose, args.dry_run)
|
||||
else:
|
||||
# Create all data
|
||||
shops = create_shops(args.url, args.verbose, args.dry_run)
|
||||
groceries = create_groceries(args.url, args.verbose, args.dry_run)
|
||||
if shops and groceries:
|
||||
events = create_shopping_events(shops, groceries, args.url, args.events, args.days, args.verbose, args.dry_run)
|
||||
|
||||
# Print summary
|
||||
if not args.dry_run:
|
||||
print_summary(shops, groceries, events)
|
||||
|
||||
if args.dry_run:
|
||||
print("\n🔍 Dry run completed. Use without --dry-run to actually create the data.")
|
||||
else:
|
||||
print("\n🎉 Test data creation completed successfully!")
|
||||
print("You can now explore the application with realistic data.")
|
||||
|
||||
except KeyboardInterrupt:
|
||||
print("\n❌ Operation cancelled by user.")
|
||||
sys.exit(1)
|
||||
except requests.exceptions.ConnectionError:
|
||||
print(f"❌ Could not connect to the API server at {args.url}")
|
||||
print(" Make sure the backend server is running!")
|
||||
sys.exit(1)
|
||||
except Exception as e:
|
||||
print(f"❌ Unexpected error: {e}")
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user