159 lines
5.7 KiB
Python
159 lines
5.7 KiB
Python
#!/usr/bin/env python3
|
||
"""
|
||
GasFlux Web API Server using Waitress WSGI server.
|
||
|
||
This is the production server entry point for the GasFlux Web API.
|
||
Includes full GasFlux processing capabilities with task pool management.
|
||
|
||
Features:
|
||
- File upload and processing (.xlsx, .xls)
|
||
- Asynchronous task processing with background workers
|
||
- Task pool management with pagination and filtering
|
||
- Real-time task status monitoring
|
||
- Report generation and file download
|
||
- Health monitoring and statistics
|
||
|
||
API Endpoints:
|
||
- /upload - File upload and processing initiation
|
||
- /task/<task_id> - Task status management
|
||
- /tasks - Task pool management (NEW)
|
||
- /download/<filename> - File download
|
||
- /reports - Report listing
|
||
- /health - Health monitoring
|
||
- /stats - System statistics
|
||
- /config - Configuration info
|
||
- / - Web interface
|
||
|
||
Usage:
|
||
python server_waitress.py
|
||
|
||
Or package with PyInstaller:
|
||
pyinstaller --onefile --name GasFluxAPI server_waitress.py
|
||
"""
|
||
|
||
import os
|
||
|
||
# Set matplotlib backend to Agg to avoid GUI dependencies
|
||
os.environ['MPLBACKEND'] = 'Agg'
|
||
# Also set it via matplotlib if it's already imported
|
||
try:
|
||
import matplotlib
|
||
matplotlib.use('Agg')
|
||
except ImportError:
|
||
pass
|
||
import sys
|
||
from pathlib import Path
|
||
|
||
# 设置控制台编码为 UTF-8(解决 Windows 中文乱码问题)
|
||
import io
|
||
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
|
||
sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8')
|
||
|
||
# Add the project root and src directory to PYTHONPATH
|
||
project_root = Path(__file__).parent.absolute()
|
||
src_dir = project_root / "src"
|
||
|
||
sys.path.insert(0, str(project_root))
|
||
sys.path.insert(0, str(src_dir))
|
||
|
||
# Set environment variables for production
|
||
os.environ['FLASK_APP'] = 'src/gasflux/app.py'
|
||
os.environ['FLASK_ENV'] = 'production'
|
||
|
||
def main():
|
||
"""Main entry point for the GasFlux Web API server."""
|
||
print("Starting GasFlux Web API with Waitress...")
|
||
|
||
try:
|
||
# Import the Flask app
|
||
import gasflux.app as gasflux_app
|
||
from src.gasflux.app import Config
|
||
|
||
app = gasflux_app.app
|
||
print("✓ GasFlux app imported successfully")
|
||
print("✓ Task pool management enabled")
|
||
print("✓ All blueprints loaded: upload, tasks, task_pool, download, reports, health, stats, config, web")
|
||
|
||
# Import waitress
|
||
from waitress import serve
|
||
print("✓ Waitress WSGI server imported")
|
||
|
||
# Server configuration from INI file (with environment variable fallbacks)
|
||
host = Config.HOST
|
||
port = Config.PORT
|
||
threads = Config.THREADS
|
||
connection_limit = Config.CONNECTION_LIMIT
|
||
channel_timeout = Config.CHANNEL_TIMEOUT
|
||
base_url = Config.BASE_URL
|
||
|
||
print(f"Starting Waitress server on {host}:{port}")
|
||
print(f"- Threads: {threads}")
|
||
print(f"- Connection limit: {connection_limit}")
|
||
print(f"- Channel timeout: {channel_timeout}s")
|
||
print(f"- Base URL: {base_url}")
|
||
print(f"- Upload folder: {Config.UPLOAD_FOLDER}")
|
||
print(f"- Output folder: {Config.OUTPUT_FOLDER}")
|
||
print("Press Ctrl+C to stop the server")
|
||
print("=" * 50)
|
||
print("Available API endpoints:")
|
||
print(" POST /upload - Upload files for processing")
|
||
print(" GET /task/<id> - Get task status")
|
||
print(" PUT /task/<id> - Update task status")
|
||
print(" DEL /task/<id> - Delete task")
|
||
print(" GET /tasks - List tasks (paginated)")
|
||
print(" GET /tasks/stats - Task pool statistics")
|
||
print(" GET /tasks/active - Active tasks")
|
||
print(" GET /tasks/queue - Queued tasks")
|
||
print(" GET /download/<file> - Download files")
|
||
print(" GET /reports - List reports")
|
||
print(" GET /health - Health check")
|
||
print(" GET /stats - System stats")
|
||
print(" GET /config - Configuration")
|
||
print(" GET / - Web interface")
|
||
print("=" * 50)
|
||
|
||
# Display configuration source info
|
||
try:
|
||
from src.gasflux.config_reader import config_reader
|
||
print("Configuration loaded from INI file:")
|
||
print(f" - Config file: {config_reader._get_config_file_path() or 'gasflux.ini (default)'}")
|
||
print(f" - Uploads path: {config_reader.uploads_path}")
|
||
print(f" - Outputs path: {config_reader.outputs_path}")
|
||
|
||
# Check API keys
|
||
from src.gasflux.app import app
|
||
with app.app_context():
|
||
from src.gasflux.db import get_db
|
||
db = get_db()
|
||
key_count = db.execute("SELECT COUNT(*) FROM api_keys WHERE revoked = 0").fetchone()[0]
|
||
print(f" - API keys: {key_count} active")
|
||
|
||
if key_count == 0:
|
||
print("\n⚠️ No active API keys found!")
|
||
print(" Run 'python create_api_key.py' to create your first API key")
|
||
print(" Or use bootstrap key in API requests: -H 'X-Admin-Bootstrap-Key: bootstrap_key_2024'")
|
||
except Exception as e:
|
||
print(f"Configuration info error: {e}")
|
||
|
||
print(f"\nFull configuration: {Config.to_dict()}")
|
||
|
||
# Start the server with valid Waitress parameters
|
||
serve(
|
||
app,
|
||
host=host,
|
||
port=port,
|
||
threads=threads,
|
||
connection_limit=connection_limit,
|
||
channel_timeout=channel_timeout,
|
||
)
|
||
|
||
except KeyboardInterrupt:
|
||
print("\nServer stopped by user")
|
||
except Exception as e:
|
||
print(f"✗ Error starting GasFlux app: {e}")
|
||
import traceback
|
||
traceback.print_exc()
|
||
sys.exit(1)
|
||
|
||
if __name__ == "__main__":
|
||
main() |