diff --git a/docutranslate/app.py b/docutranslate/app.py index cb04ef0..07f2521 100644 --- a/docutranslate/app.py +++ b/docutranslate/app.py @@ -42,6 +42,7 @@ from fastapi.openapi.docs import ( get_swagger_ui_oauth2_redirect_html, get_redoc_html, ) +from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import HTMLResponse, JSONResponse, FileResponse from fastapi.staticfiles import StaticFiles from pydantic import ( @@ -2394,7 +2395,7 @@ def find_free_port(start_port): port += 1 -def run_app(port: int | None = None): +def run_app(host=None,port: int | None = None,enable_CORS=False,allow_origin_regex=r"^https?://.*$"): initial_port = port or int(os.environ.get("DOCUTRANSLATE_PORT", 8010)) try: port_to_use = find_free_port(initial_port) @@ -2402,7 +2403,15 @@ def run_app(port: int | None = None): print(f"端口 {initial_port} 被占用,将使用端口 {port_to_use} 代替") print(f"正在启动 DocuTranslate WebUI 版本号:{__version__}") app.state.port_to_use = port_to_use - uvicorn.run(app, host=None, port=port_to_use, workers=1) + if enable_CORS: + app.add_middleware( + CORSMiddleware, + allow_origin_regex=allow_origin_regex, + allow_credentials=True, + allow_methods=["*"], + allow_headers=["*"], + ) + uvicorn.run(app, host=host, port=port_to_use, workers=1) except Exception as e: print(f"启动失败: {e}") diff --git a/docutranslate/cli.py b/docutranslate/cli.py index efeb3d6..8bb178e 100644 --- a/docutranslate/cli.py +++ b/docutranslate/cli.py @@ -7,48 +7,78 @@ import sys # 用于检查命令行参数数量 def main(): parser = argparse.ArgumentParser( description="DocuTranslate: 一个文档翻译工具。", - epilog="示例: docutranslate -i (启动图形界面)\ndocutranslate -i -p 8081 (启用端口号8081)" # epilog 会显示在帮助信息的末尾 + # 更新示例,展示如何使用 host 参数 + epilog="示例:\n" + " docutranslate -i (启动图形界面,默认本地访问)\n" + " docutranslate -i --host 0.0.0.0 (允许局域网内其他设备访问)\n" + " docutranslate -i -p 8081 (指定端口号)\n" + " docutranslate -i --cors (启用默认的跨域设置)\n", + formatter_class=argparse.RawDescriptionHelpFormatter ) + parser.add_argument( - "-i", "--interactive", # 添加一个长选项,更友好 - action="store_true", # 当出现 -i 或 --interactive 时,args.interactive 将为 True - help="打开图形化用户界面 (GUI)。" + "-i", "--interactive", + action="store_true", + help="打开图形化用户界面 (GUI) 并启动后端服务。" ) + # --- 新增 host 参数 --- + parser.add_argument( + "--host", + type=str, + default=None, + help="指定服务监听的主机地址。默认为 '127.0.0.1' (仅本地)。若需局域网访问请设为 '0.0.0.0'。" + ) + # --------------------- + parser.add_argument( "-p", "--port", - type=int, # 指定参数类型(例如整数) - default=None, # 默认值(可选) - help="指定端口号(默认:8010)。" + type=int, + default=None, + help="指定服务监听的端口号(默认:8010)。" ) parser.add_argument( - "--version", # 添加一个长选项,更友好 + "--cors", + action="store_true", + help="启用跨域资源共享 (CORS)。如果是前后端分离开发或需跨域调用 API,请开启此选项。" + ) + + parser.add_argument( + "--cors-regex", + type=str, + default=r"^https?://.*$", + help="设置 CORS 允许的 Origin 正则表达式。默认为允许所有 HTTP 和 HTTPS 请求。" + ) + + parser.add_argument( + "--version", action="store_true", help="查看版本号。" ) - # 如果你想在未来添加其他非GUI的命令行功能,可以在这里添加更多参数 - # parser.add_argument("input_file", help="要翻译的文件路径", nargs="?") # nargs="?" 使其可选 - # parser.add_argument("-l", "--language", help="目标语言") - # 检查是否没有提供任何参数 (除了脚本名本身) - # sys.argv[0] 是脚本名, len(sys.argv) == 1 表示只运行了命令本身,没有附加参数 + # 检查是否没有提供任何参数 if len(sys.argv) == 1: - # 如果用户只输入了 'docutranslate' 而没有任何参数 print("欢迎使用 DocuTranslate!") print("请使用 '-i' 或 '--interactive' 选项来启动图形化界面。") print("\n示例:") print(" docutranslate -i") - print(" docutranslate --interactive") + print(" docutranslate -i --host 0.0.0.0 (局域网共享)") print("\n如需查看所有可用选项,请运行:") - sys.exit(0) # 正常退出 + print(" docutranslate --help") + sys.exit(0) args = parser.parse_args() # 调用核心逻辑 - if args.interactive: # 注意这里是 args.interactive,对应 "--interactive" + if args.interactive: from docutranslate.app import run_app - run_app(port=args.port) + run_app( + host=args.host, + port=args.port, + enable_CORS=args.cors, + allow_origin_regex=args.cors_regex + ) elif args.version: from docutranslate import __version__ print(__version__)