start.pyā¢7.96 kB
#!/usr/bin/env python3
"""Startup script for the Expense Tracker API with MCP Server"""
import sys
import os
import subprocess
import argparse
from pathlib import Path
def check_dependencies():
"""Check if all required dependencies are installed"""
print("š Checking dependencies...")
required_packages = ['fastapi', 'uvicorn', 'pydantic', 'fastapi_mcp']
missing = []
for package in required_packages:
try:
__import__(package)
print(f" ā
{package}")
except ImportError:
print(f" ā {package} - missing")
missing.append(package)
if missing:
print("\nā ļø Missing packages. Install with:")
print(f" pip install {' '.join(missing)}")
return False
print("ā
All dependencies installed\n")
return True
def init_database():
"""Initialize database and add seed data"""
print("šļø Initializing database...")
try:
from store import TransactionStore
from models import TransactionCreate, TransactionType, Category
from datetime import datetime, timedelta
store = TransactionStore()
# Check if database already has data
existing = store.get_all()
if existing:
print(f" ā¹ļø Database already contains {len(existing)} transactions")
print(f" š Database: {store.db_path}\n")
return True
# Add seed data
print(" š Adding seed data...")
base_date = datetime.now() - timedelta(days=7)
seed_transactions = [
# Income
{
"title": "Monthly Salary",
"amount": 5000.00,
"type": TransactionType.INCOME,
"category": Category.SALARY,
"description": "Monthly salary payment",
"tags": ["salary", "monthly"],
"date": base_date + timedelta(days=1)
},
{
"title": "Freelance Work",
"amount": 800.00,
"type": TransactionType.INCOME,
"category": Category.FREELANCE,
"description": "Web design project",
"tags": ["freelance", "design"],
"date": base_date + timedelta(days=3)
},
# Expenses
{
"title": "Grocery Shopping",
"amount": 150.00,
"type": TransactionType.EXPENSE,
"category": Category.FOOD,
"description": "Weekly groceries",
"tags": ["groceries", "weekly"],
"date": base_date + timedelta(days=2)
},
{
"title": "Rent Payment",
"amount": 1200.00,
"type": TransactionType.EXPENSE,
"category": Category.HOUSING,
"description": "Monthly rent",
"tags": ["rent", "monthly"],
"date": base_date + timedelta(days=1)
},
{
"title": "Gas Station",
"amount": 45.00,
"type": TransactionType.EXPENSE,
"category": Category.TRANSPORTATION,
"description": "Fuel",
"tags": ["gas", "car"],
"date": base_date + timedelta(days=4)
},
{
"title": "Restaurant Dinner",
"amount": 75.00,
"type": TransactionType.EXPENSE,
"category": Category.ENTERTAINMENT,
"description": "Dinner with friends",
"tags": ["restaurant", "dining"],
"date": base_date + timedelta(days=5)
}
]
for transaction_data in seed_transactions:
store.create(TransactionCreate(**transaction_data))
print(f" ā
Added {len(seed_transactions)} seed transactions")
print(f" š Database: {store.db_path}\n")
return True
except Exception as e:
print(f" ā Database initialization failed: {e}\n")
return False
def check_environment():
"""Check environment variables"""
print("š Checking environment variables...")
env_file = Path(__file__).parent.parent / '.env'
if env_file.exists():
print(f" ā
.env file found")
else:
print(f" ā ļø .env file not found at {env_file}")
print(f" š” Copy .env.example to .env and add your keys")
print()
def run_api_server(host="localhost", port=8002):
"""Run the API server"""
print("š Starting API Server...")
print(f" š http://{host}:{port}")
print(f" š Docs: http://{host}:{port}/docs\n")
try:
subprocess.run([
sys.executable, "-m", "uvicorn",
"main:app",
f"--host={host}",
f"--port={port}",
"--reload"
])
except KeyboardInterrupt:
print("\nš API server stopped")
def run_mcp_server(host="localhost", port=9002):
"""Run the MCP server"""
print("š§ Starting MCP Server...")
print(f" š http://{host}:{port}")
print(f" š¤ MCP endpoint: http://{host}:{port}/mcp\n")
try:
subprocess.run([
sys.executable, "mcp_server.py"
])
except KeyboardInterrupt:
print("\nš MCP server stopped")
def show_usage():
"""Show usage instructions"""
print("""
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā š° Expense Tracker - Server Manager ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
š Available Commands:
Run API Server:
python start.py --api
Run MCP Server:
python start.py --mcp
Custom ports:
python start.py --api --port 8000
python start.py --mcp --port 9000
Run both (in separate terminals):
Terminal 1: python start.py --api
Terminal 2: python start.py --mcp
š Quick Start:
1. Ensure .env file has your OPENAI_API_KEY
2. Start MCP server: python start.py --mcp
3. Start API server: python start.py --api
4. Run agent: cd ../agent && python agent.py
š Access:
⢠API Docs: http://localhost:8002/docs
⢠MCP Server: http://localhost:9002/mcp
⢠Agent: http://localhost:7777
For help: python start.py --help
""")
def main():
"""Main entry point"""
parser = argparse.ArgumentParser(
description="Expense Tracker Server Manager",
formatter_class=argparse.RawDescriptionHelpFormatter
)
parser.add_argument("--api", action="store_true", help="Run API server")
parser.add_argument("--mcp", action="store_true", help="Run MCP server")
parser.add_argument("--port", type=int, help="Custom port (default: 8002 for API, 9002 for MCP)")
parser.add_argument("--host", default="localhost", help="Host to bind to (default: localhost)")
args = parser.parse_args()
# Always run checks first
print("=" * 60)
print(" š EXPENSE TRACKER - INITIALIZATION")
print("=" * 60 + "\n")
if not check_dependencies():
sys.exit(1)
check_environment()
if not init_database():
sys.exit(1)
print("=" * 60)
print(" ā
READY TO START")
print("=" * 60 + "\n")
# Determine what to run
if args.api:
port = args.port or 8002
run_api_server(args.host, port)
elif args.mcp:
port = args.port or 9002
run_mcp_server(args.host, port)
else:
show_usage()
if __name__ == "__main__":
main()