gakrchat1 / app.py
extraplus's picture
Upload app.py
6175abf verified
#!/usr/bin/env python3
"""
GAKR AI Chatbot - Startup Script
Handles environment setup and server startup
"""
import os
import sys
import subprocess
import argparse
import socket
from pathlib import Path
def configure_output_encoding():
"""Avoid UnicodeEncodeError on non-UTF terminal encodings."""
try:
if hasattr(sys.stdout, "reconfigure"):
sys.stdout.reconfigure(encoding="utf-8", errors="replace")
if hasattr(sys.stderr, "reconfigure"):
sys.stderr.reconfigure(encoding="utf-8", errors="replace")
except Exception:
pass
def print_banner():
"""Print startup banner"""
print("""
+--------------------------------------------------------------+
| |
| GAKR AI Chatbot Platform |
| |
| Powered by NVIDIA API + Web Search |
| |
+--------------------------------------------------------------+
""")
def check_python_version():
"""Check if Python version is compatible"""
if sys.version_info < (3, 8):
print("❌ Error: Python 3.8 or higher is required")
print(f" Current version: {sys.version_info.major}.{sys.version_info.minor}")
return False
print(f"✅ Python {sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}")
return True
def check_dependencies():
"""Check if required dependencies are installed"""
backend_dir = Path(__file__).parent / "backend"
req_file = backend_dir / "requirements.txt"
if not req_file.exists():
print("⚠️ requirements.txt not found")
return False
print("📦 Checking dependencies...")
# Try to import key modules
try:
import fastapi
print(" ✓ FastAPI")
except ImportError:
print(" ✗ FastAPI (not installed)")
return False
try:
import httpx
print(" ✓ httpx")
except ImportError:
print(" ✗ httpx (not installed)")
return False
try:
import PyPDF2
print(" ✓ PyPDF2")
except ImportError:
print(" ✗ PyPDF2 (not installed)")
return False
try:
import docx # noqa: F401
print(" ✓ python-docx")
except ImportError:
print(" ✗ python-docx (not installed)")
return False
try:
from PIL import Image # noqa: F401
print(" ✓ Pillow")
except ImportError:
print(" ✗ Pillow (not installed)")
return False
try:
import openpyxl # noqa: F401
print(" ✓ openpyxl")
except ImportError:
print(" ✗ openpyxl (not installed)")
return False
try:
import xlrd # noqa: F401
print(" ✓ xlrd")
except ImportError:
print(" ⚠️ xlrd (not installed, legacy .xls parsing disabled)")
try:
import pytesseract
try:
pytesseract.get_tesseract_version()
print(" ✓ pytesseract + Tesseract OCR")
except Exception:
print(" ⚠️ pytesseract installed, but Tesseract OCR binary not detected")
except ImportError:
print(" ⚠️ pytesseract (not installed, image OCR disabled)")
except Exception as e:
print(f" ⚠️ pytesseract unavailable ({type(e).__name__}: {e})")
print(" Image OCR disabled; server will continue without OCR.")
return True
def setup_directories():
"""Create necessary directories"""
base_dir = Path(__file__).parent
dirs = [
base_dir / "data",
base_dir / "data" / "uploads"
]
for d in dirs:
d.mkdir(parents=True, exist_ok=True)
print("✅ Directories initialized")
def is_port_available(host, port):
"""Check whether a TCP port is available for binding"""
bind_host = host if host and host != "0.0.0.0" else "0.0.0.0"
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
try:
sock.bind((bind_host, int(port)))
return True
except OSError:
return False
def find_available_port(host, start_port, max_tries=50):
"""Find first available port starting from start_port"""
port = int(start_port)
for _ in range(max_tries):
if is_port_available(host, port):
return port
port += 1
return None
def start_server(host, port, reload):
"""Start the FastAPI server"""
backend_dir = Path(__file__).parent / "backend"
requested_port = int(port)
selected_port = find_available_port(host, requested_port)
if selected_port is None:
print(f"\n❌ No available port found from {requested_port} to {requested_port + 49}")
print(" Stop existing server processes or pass a different --port value.")
return 1
if selected_port != requested_port:
print(f"\n⚠️ Port {requested_port} is already in use. Switching to port {selected_port}.")
port = selected_port
print(f"\n🚀 Starting server on http://{host}:{port}")
print(" Press Ctrl+C to stop\n")
cmd = [
sys.executable, "-m", "uvicorn",
"main:app",
"--host", host,
"--port", str(port),
]
if reload:
cmd.append("--reload")
try:
result = subprocess.run(cmd, cwd=backend_dir)
return result.returncode
except KeyboardInterrupt:
print("\n\n👋 Server stopped")
return 0
def main():
configure_output_encoding()
parser = argparse.ArgumentParser(description="GAKR AI Chatbot Server")
default_port = int(os.getenv("PORT", "7860"))
parser.add_argument("--host", default="0.0.0.0", help="Host to bind (default: 0.0.0.0)")
parser.add_argument("--port", type=int, default=default_port, help=f"Port to run on (default: {default_port})")
parser.add_argument("--reload", action="store_true", help="Enable auto-reload for development")
parser.add_argument("--skip-checks", action="store_true", help="Skip dependency checks")
args = parser.parse_args()
print_banner()
# Check Python version
if not check_python_version():
sys.exit(1)
# Setup directories
setup_directories()
# Check dependencies
if not args.skip_checks:
if not check_dependencies():
print("\n❌ Please install dependencies first:")
print(" pip install -r backend/requirements.txt")
sys.exit(1)
# Start server
exit_code = start_server(args.host, args.port, args.reload)
if exit_code != 0:
sys.exit(exit_code)
if __name__ == "__main__":
main()