2025-06-22 01:01:58 +02:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
|
"""
|
2025-06-22 20:03:38 +02:00
|
|
|
🚀 N8N Workflows Search Engine Launcher
|
|
|
|
|
Start the advanced search system with optimized performance.
|
2025-06-22 01:01:58 +02:00
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
import sys
|
|
|
|
|
import os
|
2025-06-22 20:03:38 +02:00
|
|
|
import argparse
|
2025-06-22 01:01:58 +02:00
|
|
|
from pathlib import Path
|
|
|
|
|
|
2025-06-22 20:03:38 +02:00
|
|
|
|
2025-06-22 01:01:58 +02:00
|
|
|
def print_banner():
|
2025-06-22 20:03:38 +02:00
|
|
|
"""Print application banner."""
|
2025-06-22 01:01:58 +02:00
|
|
|
print("🚀 n8n-workflows Advanced Search Engine")
|
|
|
|
|
print("=" * 50)
|
|
|
|
|
|
2025-06-22 20:03:38 +02:00
|
|
|
|
|
|
|
|
def check_requirements() -> bool:
|
|
|
|
|
"""Check if required dependencies are installed."""
|
|
|
|
|
missing_deps = []
|
|
|
|
|
|
2025-06-22 01:01:58 +02:00
|
|
|
try:
|
|
|
|
|
import sqlite3
|
2025-06-22 20:03:38 +02:00
|
|
|
except ImportError:
|
|
|
|
|
missing_deps.append("sqlite3")
|
|
|
|
|
|
|
|
|
|
try:
|
2025-06-22 01:01:58 +02:00
|
|
|
import uvicorn
|
2025-06-22 20:03:38 +02:00
|
|
|
except ImportError:
|
|
|
|
|
missing_deps.append("uvicorn")
|
|
|
|
|
|
|
|
|
|
try:
|
2025-06-22 01:01:58 +02:00
|
|
|
import fastapi
|
2025-06-22 20:03:38 +02:00
|
|
|
except ImportError:
|
|
|
|
|
missing_deps.append("fastapi")
|
|
|
|
|
|
|
|
|
|
if missing_deps:
|
|
|
|
|
print(f"❌ Missing dependencies: {', '.join(missing_deps)}")
|
2025-06-22 01:01:58 +02:00
|
|
|
print("💡 Install with: pip install -r requirements.txt")
|
|
|
|
|
return False
|
2025-06-22 20:03:38 +02:00
|
|
|
|
|
|
|
|
print("✅ Dependencies verified")
|
|
|
|
|
return True
|
2025-06-22 01:01:58 +02:00
|
|
|
|
2025-06-22 20:03:38 +02:00
|
|
|
|
|
|
|
|
def setup_directories():
|
|
|
|
|
"""Create necessary directories."""
|
|
|
|
|
directories = ["database", "static", "workflows"]
|
|
|
|
|
|
|
|
|
|
for directory in directories:
|
|
|
|
|
os.makedirs(directory, exist_ok=True)
|
|
|
|
|
|
|
|
|
|
print("✅ Directories verified")
|
|
|
|
|
|
|
|
|
|
|
2025-11-03 11:45:46 +02:00
|
|
|
def setup_database(force_reindex: bool = False, skip_index: bool = False) -> str:
|
2025-06-22 20:03:38 +02:00
|
|
|
"""Setup and initialize the database."""
|
2025-06-22 01:01:58 +02:00
|
|
|
from workflow_db import WorkflowDatabase
|
2025-11-03 11:45:46 +02:00
|
|
|
|
2025-06-22 01:01:58 +02:00
|
|
|
db_path = "database/workflows.db"
|
2025-11-03 11:45:46 +02:00
|
|
|
|
2025-06-22 01:01:58 +02:00
|
|
|
print(f"🔄 Setting up database: {db_path}")
|
|
|
|
|
db = WorkflowDatabase(db_path)
|
2025-11-03 11:45:46 +02:00
|
|
|
|
|
|
|
|
# Skip indexing in CI mode or if explicitly requested
|
|
|
|
|
if skip_index:
|
|
|
|
|
print("⏭️ Skipping workflow indexing (CI mode)")
|
|
|
|
|
stats = db.get_stats()
|
|
|
|
|
print(f"✅ Database ready: {stats['total']} workflows")
|
|
|
|
|
return db_path
|
|
|
|
|
|
2025-06-22 20:03:38 +02:00
|
|
|
# Check if database has data or force reindex
|
2025-06-22 01:01:58 +02:00
|
|
|
stats = db.get_stats()
|
2025-06-22 20:03:38 +02:00
|
|
|
if stats['total'] == 0 or force_reindex:
|
2025-06-22 01:01:58 +02:00
|
|
|
print("📚 Indexing workflows...")
|
|
|
|
|
index_stats = db.index_all_workflows(force_reindex=True)
|
|
|
|
|
print(f"✅ Indexed {index_stats['processed']} workflows")
|
2025-11-03 11:45:46 +02:00
|
|
|
|
2025-06-22 20:03:38 +02:00
|
|
|
# Show final stats
|
|
|
|
|
final_stats = db.get_stats()
|
|
|
|
|
print(f"📊 Database contains {final_stats['total']} workflows")
|
2025-06-22 01:01:58 +02:00
|
|
|
else:
|
|
|
|
|
print(f"✅ Database ready: {stats['total']} workflows")
|
2025-11-03 11:45:46 +02:00
|
|
|
|
2025-06-22 01:01:58 +02:00
|
|
|
return db_path
|
|
|
|
|
|
2025-06-22 20:03:38 +02:00
|
|
|
|
|
|
|
|
def start_server(host: str = "127.0.0.1", port: int = 8000, reload: bool = False):
|
|
|
|
|
"""Start the FastAPI server."""
|
|
|
|
|
print(f"🌐 Starting server at http://{host}:{port}")
|
|
|
|
|
print(f"📊 API Documentation: http://{host}:{port}/docs")
|
|
|
|
|
print(f"🔍 Workflow Search: http://{host}:{port}/api/workflows")
|
2025-06-22 01:01:58 +02:00
|
|
|
print()
|
|
|
|
|
print("Press Ctrl+C to stop the server")
|
|
|
|
|
print("-" * 50)
|
|
|
|
|
|
|
|
|
|
# Configure database path
|
|
|
|
|
os.environ['WORKFLOW_DB_PATH'] = "database/workflows.db"
|
|
|
|
|
|
2025-06-22 20:03:38 +02:00
|
|
|
# Start uvicorn with better configuration
|
2025-06-22 01:01:58 +02:00
|
|
|
import uvicorn
|
2025-06-22 20:03:38 +02:00
|
|
|
uvicorn.run(
|
|
|
|
|
"api_server:app",
|
|
|
|
|
host=host,
|
|
|
|
|
port=port,
|
|
|
|
|
reload=reload,
|
|
|
|
|
log_level="info",
|
|
|
|
|
access_log=False # Reduce log noise
|
|
|
|
|
)
|
|
|
|
|
|
2025-06-22 01:01:58 +02:00
|
|
|
|
|
|
|
|
def main():
|
2025-06-22 20:03:38 +02:00
|
|
|
"""Main entry point with command line arguments."""
|
2025-08-31 16:17:41 +03:00
|
|
|
sys.stdout.reconfigure(encoding='utf-8')
|
2025-06-22 20:03:38 +02:00
|
|
|
parser = argparse.ArgumentParser(
|
|
|
|
|
description="N8N Workflows Search Engine",
|
|
|
|
|
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
|
|
|
epilog="""
|
|
|
|
|
Examples:
|
|
|
|
|
python run.py # Start with default settings
|
|
|
|
|
python run.py --port 3000 # Start on port 3000
|
|
|
|
|
python run.py --host 0.0.0.0 # Accept external connections
|
|
|
|
|
python run.py --reindex # Force database reindexing
|
|
|
|
|
python run.py --dev # Development mode with auto-reload
|
|
|
|
|
"""
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
parser.add_argument(
|
|
|
|
|
"--host",
|
|
|
|
|
default="127.0.0.1",
|
|
|
|
|
help="Host to bind to (default: 127.0.0.1)"
|
|
|
|
|
)
|
|
|
|
|
parser.add_argument(
|
|
|
|
|
"--port",
|
|
|
|
|
type=int,
|
|
|
|
|
default=8000,
|
|
|
|
|
help="Port to bind to (default: 8000)"
|
|
|
|
|
)
|
|
|
|
|
parser.add_argument(
|
|
|
|
|
"--reindex",
|
|
|
|
|
action="store_true",
|
|
|
|
|
help="Force database reindexing"
|
|
|
|
|
)
|
|
|
|
|
parser.add_argument(
|
2025-11-03 11:45:46 +02:00
|
|
|
"--dev",
|
|
|
|
|
action="store_true",
|
2025-06-22 20:03:38 +02:00
|
|
|
help="Development mode with auto-reload"
|
|
|
|
|
)
|
2025-11-03 11:45:46 +02:00
|
|
|
parser.add_argument(
|
|
|
|
|
"--skip-index",
|
|
|
|
|
action="store_true",
|
|
|
|
|
help="Skip workflow indexing (useful for CI/testing)"
|
|
|
|
|
)
|
|
|
|
|
|
2025-06-22 20:03:38 +02:00
|
|
|
args = parser.parse_args()
|
2025-11-03 11:45:46 +02:00
|
|
|
|
|
|
|
|
# Also check environment variable for CI mode
|
|
|
|
|
ci_mode = os.environ.get('CI', '').lower() in ('true', '1', 'yes')
|
|
|
|
|
skip_index = args.skip_index or ci_mode
|
2025-06-22 20:03:38 +02:00
|
|
|
|
2025-06-22 01:01:58 +02:00
|
|
|
print_banner()
|
|
|
|
|
|
|
|
|
|
# Check dependencies
|
|
|
|
|
if not check_requirements():
|
|
|
|
|
sys.exit(1)
|
|
|
|
|
|
2025-06-22 20:03:38 +02:00
|
|
|
# Setup directories
|
|
|
|
|
setup_directories()
|
|
|
|
|
|
2025-06-22 01:01:58 +02:00
|
|
|
# Setup database
|
|
|
|
|
try:
|
2025-11-03 11:45:46 +02:00
|
|
|
setup_database(force_reindex=args.reindex, skip_index=skip_index)
|
2025-06-22 01:01:58 +02:00
|
|
|
except Exception as e:
|
|
|
|
|
print(f"❌ Database setup error: {e}")
|
|
|
|
|
sys.exit(1)
|
|
|
|
|
|
|
|
|
|
# Start server
|
|
|
|
|
try:
|
2025-06-22 20:03:38 +02:00
|
|
|
start_server(
|
|
|
|
|
host=args.host,
|
|
|
|
|
port=args.port,
|
|
|
|
|
reload=args.dev
|
|
|
|
|
)
|
2025-06-22 01:01:58 +02:00
|
|
|
except KeyboardInterrupt:
|
|
|
|
|
print("\n👋 Server stopped!")
|
|
|
|
|
except Exception as e:
|
|
|
|
|
print(f"❌ Server error: {e}")
|
|
|
|
|
sys.exit(1)
|
|
|
|
|
|
2025-06-22 20:03:38 +02:00
|
|
|
|
2025-06-22 01:01:58 +02:00
|
|
|
if __name__ == "__main__":
|
|
|
|
|
main()
|