314 lines
9.4 KiB
Python
314 lines
9.4 KiB
Python
#!/usr/bin/env python3
|
||
# -*- coding: utf-8 -*-
|
||
"""
|
||
云盘应用启动脚本 - 端口8080版本
|
||
包含完整的API测试功能
|
||
"""
|
||
|
||
import os
|
||
import sys
|
||
from pathlib import Path
|
||
|
||
# 添加当前目录到Python路径
|
||
current_dir = Path(__file__).parent
|
||
sys.path.insert(0, str(current_dir))
|
||
|
||
from fastapi import FastAPI
|
||
from fastapi.middleware.cors import CORSMiddleware
|
||
import uvicorn
|
||
import subprocess
|
||
import time
|
||
import requests
|
||
from typing import Dict, List
|
||
|
||
# 导入应用模块
|
||
try:
|
||
from app.core.config import settings
|
||
from app.api.v1.endpoints import health, auth, files
|
||
APP_AVAILABLE = True
|
||
except ImportError as e:
|
||
print(f"⚠️ App模块导入失败: {e}")
|
||
print("🔧 使用简化模式启动...")
|
||
APP_AVAILABLE = False
|
||
|
||
def create_fastapi_app():
|
||
"""创建FastAPI应用"""
|
||
if APP_AVAILABLE:
|
||
# 使用完整的应用
|
||
app = FastAPI(
|
||
title="云盘应用 API",
|
||
description="现代化的云存储Web应用后端API",
|
||
version="1.0.0",
|
||
docs_url="/docs",
|
||
redoc_url="/redoc"
|
||
)
|
||
|
||
# CORS中间件
|
||
app.add_middleware(
|
||
CORSMiddleware,
|
||
allow_origins=settings.ALLOWED_HOSTS,
|
||
allow_credentials=True,
|
||
allow_methods=["*"],
|
||
allow_headers=["*"],
|
||
)
|
||
|
||
# 包含路由
|
||
app.include_router(health.router, prefix="/api/v1", tags=["health"])
|
||
app.include_router(auth.router, prefix="/api/v1/auth", tags=["authentication"])
|
||
app.include_router(files.router, prefix="/api/v1/files", tags=["files"])
|
||
|
||
@app.get("/")
|
||
async def root():
|
||
return {
|
||
"message": "云盘应用 API",
|
||
"version": "1.0.1",
|
||
"docs": "/docs",
|
||
"health": "/api/v1/health"
|
||
}
|
||
|
||
return app
|
||
else:
|
||
# 创建简化版本的应用
|
||
app = FastAPI(
|
||
title="云盘应用 API (简化版)",
|
||
description="云存储Web应用后端API - 简化版本",
|
||
version="1.0.0",
|
||
docs_url="/docs",
|
||
redoc_url="/redoc"
|
||
)
|
||
|
||
# CORS中间件
|
||
app.add_middleware(
|
||
CORSMiddleware,
|
||
allow_origins=["*"],
|
||
allow_credentials=True,
|
||
allow_methods=["*"],
|
||
allow_headers=["*"],
|
||
)
|
||
|
||
@app.get("/")
|
||
async def root():
|
||
return {
|
||
"message": "云盘应用 API (简化版)",
|
||
"version": "1.0.0",
|
||
"docs": "/docs",
|
||
"health": "/health"
|
||
}
|
||
|
||
@app.get("/health")
|
||
async def health_check():
|
||
return {
|
||
"status": "healthy",
|
||
"message": "服务运行正常",
|
||
"mode": "simplified"
|
||
}
|
||
|
||
@app.get("/api/v1/health")
|
||
async def api_health():
|
||
return {
|
||
"status": "healthy",
|
||
"timestamp": time.time(),
|
||
"version": "1.0.0"
|
||
}
|
||
|
||
return app
|
||
|
||
def test_api_endpoints(base_url: str = "http://localhost:8080") -> Dict[str, any]:
|
||
"""测试API端点"""
|
||
print("\n🧪 开始测试API端点...")
|
||
print("=" * 50)
|
||
|
||
results = {}
|
||
|
||
# 测试端点列表
|
||
endpoints = [
|
||
("/", "根路径"),
|
||
("/health", "健康检查"),
|
||
("/api/v1/health", "API健康检查"),
|
||
("/docs", "API文档"),
|
||
("/redoc", "ReDoc文档"),
|
||
("/openapi.json", "OpenAPI规范")
|
||
]
|
||
|
||
for endpoint, description in endpoints:
|
||
try:
|
||
print(f"📍 测试 {description}: {endpoint}")
|
||
|
||
if endpoint in ["/docs", "/redoc"]:
|
||
# 对于文档端点,只检查HTTP状态
|
||
response = requests.get(f"{base_url}{endpoint}", timeout=5)
|
||
if response.status_code == 200:
|
||
print(f" ✅ {description} - 状态码: {response.status_code}")
|
||
results[endpoint] = {"status": "success", "code": response.status_code}
|
||
else:
|
||
print(f" ❌ {description} - 状态码: {response.status_code}")
|
||
results[endpoint] = {"status": "failed", "code": response.status_code}
|
||
else:
|
||
# 对于API端点,检查响应内容
|
||
response = requests.get(f"{base_url}{endpoint}", timeout=5)
|
||
if response.status_code == 200:
|
||
data = response.json()
|
||
print(f" ✅ {description} - 响应: {data}")
|
||
results[endpoint] = {"status": "success", "data": data}
|
||
else:
|
||
print(f" ❌ {description} - 状态码: {response.status_code}")
|
||
results[endpoint] = {"status": "failed", "code": response.status_code}
|
||
|
||
except requests.exceptions.ConnectionError:
|
||
print(f" ❌ {description} - 连接失败")
|
||
results[endpoint] = {"status": "connection_failed"}
|
||
except requests.exceptions.Timeout:
|
||
print(f" ❌ {description} - 请求超时")
|
||
results[endpoint] = {"status": "timeout"}
|
||
except Exception as e:
|
||
print(f" ❌ {description} - 错误: {e}")
|
||
results[endpoint] = {"status": "error", "error": str(e)}
|
||
|
||
return results
|
||
|
||
def start_server():
|
||
"""启动服务器"""
|
||
print("🚀 启动云盘应用服务...")
|
||
print("=" * 50)
|
||
|
||
# 创建必要目录
|
||
os.makedirs("logs", exist_ok=True)
|
||
os.makedirs("uploads", exist_ok=True)
|
||
|
||
# 创建FastAPI应用
|
||
app = create_fastapi_app()
|
||
|
||
# 获取本机IP
|
||
import socket
|
||
try:
|
||
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||
s.connect(("8.8.8.8", 80))
|
||
local_ip = s.getsockname()[0]
|
||
s.close()
|
||
except:
|
||
local_ip = "127.0.0.1"
|
||
|
||
# 显示启动信息
|
||
print(f"📍 本地访问:")
|
||
print(f" 根路径: http://localhost:8080")
|
||
print(f" API文档: http://localhost:8080/docs")
|
||
print(f" ReDoc: http://localhost:8080/redoc")
|
||
print(f" 健康检查: http://localhost:8080/api/v1/health")
|
||
print("")
|
||
print(f"🌐 网络访问:")
|
||
print(f" 根路径: http://{local_ip}:8080")
|
||
print(f" API文档: http://{local_ip}:8080/docs")
|
||
print(f" ReDoc: http://{local_ip}:8080/redoc")
|
||
print("")
|
||
print(f"🔧 API测试:")
|
||
print(f" 自动测试将在服务启动后执行")
|
||
print("=" * 50)
|
||
print("⏹️ 按 Ctrl+C 停止服务")
|
||
print("")
|
||
|
||
# 启动服务器
|
||
try:
|
||
uvicorn.run(
|
||
app,
|
||
host="0.0.0.0",
|
||
port=8080,
|
||
reload=False,
|
||
access_log=True,
|
||
log_level="info"
|
||
)
|
||
except KeyboardInterrupt:
|
||
print("\n🛑 服务已停止")
|
||
except Exception as e:
|
||
print(f"❌ 启动失败: {e}")
|
||
return False
|
||
|
||
return True
|
||
|
||
def run_with_auto_test():
|
||
"""启动服务器并自动测试"""
|
||
print("🤖 自动模式:启动服务器并进行API测试")
|
||
|
||
# 启动服务器(在后台)
|
||
import subprocess
|
||
import signal
|
||
import threading
|
||
|
||
# 启动服务器进程
|
||
server_process = subprocess.Popen([
|
||
sys.executable, __file__
|
||
], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||
|
||
# 等待服务器启动
|
||
print("⏳ 等待服务器启动...")
|
||
time.sleep(5)
|
||
|
||
try:
|
||
# 测试API端点
|
||
results = test_api_endpoints()
|
||
|
||
# 显示测试结果
|
||
print("\n📊 测试结果汇总:")
|
||
print("=" * 50)
|
||
|
||
success_count = sum(1 for r in results.values() if r.get("status") == "success")
|
||
total_count = len(results)
|
||
|
||
print(f"成功: {success_count}/{total_count}")
|
||
|
||
for endpoint, result in results.items():
|
||
status = result.get("status", "unknown")
|
||
if status == "success":
|
||
print(f" ✅ {endpoint}")
|
||
else:
|
||
print(f" ❌ {endpoint} - {status}")
|
||
|
||
if success_count == total_count:
|
||
print("\n🎉 所有API端点测试通过!")
|
||
else:
|
||
print(f"\n⚠️ {total_count - success_count} 个端点测试失败")
|
||
|
||
finally:
|
||
# 停止服务器
|
||
print("\n🛑 停止服务器...")
|
||
server_process.terminate()
|
||
server_process.wait()
|
||
|
||
if __name__ == "__main__":
|
||
import argparse
|
||
|
||
parser = argparse.ArgumentParser(description="云盘应用启动器 - 端口8080")
|
||
parser.add_argument("--test", action="store_true", help="启动后自动测试API端点")
|
||
parser.add_argument("--auto", action="store_true", help="自动模式:启动并测试")
|
||
args = parser.parse_args()
|
||
|
||
if args.auto:
|
||
run_with_auto_test()
|
||
elif args.test:
|
||
# 先启动,再测试
|
||
print("🚀 启动服务器...")
|
||
app = create_fastapi_app()
|
||
|
||
# 在单独线程中启动服务器
|
||
import threading
|
||
|
||
def run_server():
|
||
uvicorn.run(app, host="0.0.0.0", port=8080, reload=False, log_level="warning")
|
||
|
||
server_thread = threading.Thread(target=run_server, daemon=True)
|
||
server_thread.start()
|
||
|
||
# 等待服务器启动
|
||
time.sleep(3)
|
||
|
||
# 测试API
|
||
test_api_endpoints()
|
||
|
||
print("\n服务器继续运行,按 Ctrl+C 停止...")
|
||
try:
|
||
while True:
|
||
time.sleep(1)
|
||
except KeyboardInterrupt:
|
||
print("\n🛑 服务已停止")
|
||
else:
|
||
# 正常启动
|
||
start_server() |