File size: 7,686 Bytes
8629355 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 |
#!/usr/bin/env python3
"""
GuPT: Gothenburg University Information Assistant
Main entry point for the restructured RAG application.
This is the modernized version using:
- LCEL (LangChain Expression Language)
- Modular architecture
- Better error handling
- Enhanced logging
"""
import sys
import time
import argparse
from typing import Optional
# Local imports
from config import Config, validate_config
from rag_service import RAGService
from interface import create_interface
def parse_arguments():
"""Parse command line arguments."""
parser = argparse.ArgumentParser(
description="GuPT: Gothenburg University Information Assistant",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
Examples:
python main.py # Launch with default settings
python main.py --no-share # Launch without sharing
python main.py --port 8080 # Launch on port 8080
python main.py --rebuild-db # Force rebuild of vector database
"""
)
# Interface options
parser.add_argument(
"--share",
action="store_true",
default=False,
help="Share the interface via Gradio public link"
)
parser.add_argument(
"--no-share",
action="store_true",
default=False,
help="Explicitly disable sharing (default)"
)
parser.add_argument(
"--port",
type=int,
default=7860,
help="Port to run the interface on (default: 7860)"
)
parser.add_argument(
"--host",
type=str,
default="0.0.0.0",
help="Host to bind to (default: 0.0.0.0)"
)
# Database options
parser.add_argument(
"--rebuild-db",
action="store_true",
help="Force rebuild of the vector database"
)
parser.add_argument(
"--db-path",
type=str,
default=None,
help=f"Custom path for vector database (default: {Config.CHROMA_DB_PATH})"
)
# Debug options
parser.add_argument(
"--debug",
action="store_true",
help="Enable debug mode with verbose output"
)
parser.add_argument(
"--quiet",
action="store_true",
help="Suppress non-essential output"
)
return parser.parse_args()
def print_banner():
"""Print application banner."""
banner = """
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β
β π GuPT - Gothenburg University Information Assistant β
β β
β Built with: LangChain + OpenAI + Gradio β
β β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
"""
print(banner)
def check_prerequisites() -> bool:
"""Check if all prerequisites are met.
Returns:
True if all prerequisites are met, False otherwise
"""
try:
# Validate configuration
validate_config()
print("β
Configuration validated")
# Check if required directories exist
import os
data_dirs = [
Config.COURSES_MD_PATH,
Config.COURSES_PDF_PATH,
Config.PROGRAMS_MD_PATH,
Config.PROGRAMS_PDF_PATH
]
missing_dirs = []
for dir_path in data_dirs:
if not os.path.exists(dir_path):
missing_dirs.append(dir_path)
if missing_dirs:
print("β οΈ Warning: Some data directories are missing:")
for dir_path in missing_dirs:
print(f" - {dir_path}")
print(" The system will create them automatically if needed.")
print("β
Prerequisites check completed")
return True
except Exception as e:
print(f"β Prerequisites check failed: {str(e)}")
return False
def initialize_rag_service(args) -> Optional[RAGService]:
"""Initialize the RAG service.
Args:
args: Parsed command line arguments
Returns:
Initialized RAG service or None if failed
"""
try:
print("π§ Initializing RAG service...")
# Create RAG service
rag_service = RAGService()
print("π Loading documents and vector store...")
start_time = time.time()
# Handle database rebuild
if args.rebuild_db:
print("π Rebuilding vector database...")
import shutil
import os
if os.path.exists(Config.CHROMA_DB_PATH):
shutil.rmtree(Config.CHROMA_DB_PATH)
print(f" Removed existing database at {Config.CHROMA_DB_PATH}")
# Load documents
num_chunks = rag_service.load_documents()
load_time = time.time() - start_time
print(f"β
RAG service initialized successfully!")
print(f" π Processed {num_chunks} document chunks")
print(f" β±οΈ Loading time: {load_time:.2f} seconds")
return rag_service
except Exception as e:
print(f"β Failed to initialize RAG service: {str(e)}")
return None
def main():
"""Main entry point."""
# Parse arguments
args = parse_arguments()
# Set up quiet mode
if args.quiet:
import os
# Redirect stdout to devnull for quiet mode
# We'll still print important messages to stderr
pass
# Print banner unless in quiet mode
if not args.quiet:
print_banner()
try:
# Check prerequisites
if not check_prerequisites():
print("β Prerequisites check failed. Please fix the issues and try again.")
sys.exit(1)
# Initialize RAG service
rag_service = initialize_rag_service(args)
if not rag_service:
print("β Failed to initialize RAG service. Exiting.")
sys.exit(1)
# Create and launch interface
print("π Creating Gradio interface...")
interface_wrapper = create_interface(rag_service)
# Determine share setting
share = args.share and not args.no_share
# Launch parameters
launch_params = {
"share": share,
"server_name": args.host,
"server_port": args.port,
"show_error": True,
"quiet": args.quiet
}
print(f"π Launching interface...")
if not args.quiet:
print(f" π Local URL: http://{args.host}:{args.port}")
if share:
print(f" π Public sharing: Enabled")
else:
print(f" π Public sharing: Disabled")
# Launch the interface
interface_wrapper.create_interface()
interface_wrapper.launch(**launch_params)
except KeyboardInterrupt:
print("\nπ Shutting down gracefully...")
sys.exit(0)
except Exception as e:
print(f"β Unexpected error: {str(e)}")
if args.debug:
import traceback
traceback.print_exc()
sys.exit(1)
if __name__ == "__main__":
main() |