XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet
公开
关注 0 Fork 0 Star 0
返回提交历史

XFEstudio/gpt4free

Refactor CLI argument parsers for API and MCP modes

Refactor CLI argument parsing for API and MCP modes, enhancing help descriptions and maintaining backward compatibility for deprecated flags.

e7a7dbbe
ayushman bosu roy <ayushmanbosuroy@gmail.com>
提交于

代码差异

1 个文件 +222 -39
Modified g4f/cli/__init__.py +222 -39
@@ -1,8 +1,21 @@
1 1 from __future__ import annotations
2 2
3 """
4 This module defines the command-line interface (CLI) entrypoint for g4f,
5 including:
6 - API server mode
7 - GUI mode
8 - Client mode
9 - MCP (Model Context Protocol) mode
10
11 It provides argument parsers for each mode and executes the appropriate
12 runtime function depending on the CLI arguments.
13 """
14
3 15 import argparse
4 16 from argparse import ArgumentParser
5 17
18 # Local imports (within g4f package)
6 19 from .client import get_parser, run_client_args
7 20 from ..requests import BrowserConfig
8 21 from ..gui.run import gui_parser, run_gui_args
@@ -10,42 +23,168 @@ from ..config import DEFAULT_PORT, DEFAULT_TIMEOUT, DEFAULT_STREAM_TIMEOUT
10 23 from .. import Provider
11 24 from .. import cookies
12 25
13 def get_api_parser():
26
27 # --------------------------------------------------------------
28 # API PARSER
29 # --------------------------------------------------------------
30 def get_api_parser() -> ArgumentParser:
31 """
32 Creates and returns the argument parser used for:
33 g4f api ...
34 """
14 35 api_parser = ArgumentParser(description="Run the API and GUI")
15 api_parser.add_argument("--bind", default=None, help=f"The bind string. (Default: 0.0.0.0:{DEFAULT_PORT})")
16 api_parser.add_argument("--port", "-p", default=None, help=f"Change the port of the server. (Default: {DEFAULT_PORT})")
17 api_parser.add_argument("--debug", "-d", action="store_true", help="Enable verbose logging.")
18 api_parser.add_argument("--gui", "-g", default=None, action="store_true", help="(deprecated)")
19 api_parser.add_argument("--no-gui", "-ng", default=False, action="store_true", help="Start without the gui.")
20 api_parser.add_argument("--model", default=None, help="Default model for chat completion. (incompatible with --reload and --workers)")
21 api_parser.add_argument("--provider", choices=[provider.__name__ for provider in Provider.__providers__ if provider.working],
22 default=None, help="Default provider for chat completion. (incompatible with --reload and --workers)")
23 api_parser.add_argument("--media-provider", choices=[provider.__name__ for provider in Provider.__providers__ if provider.working and bool(getattr(provider, "image_models", False))],
24 default=None, help="Default provider for image generation. (incompatible with --reload and --workers)"),
25 api_parser.add_argument("--proxy", default=None, help="Default used proxy. (incompatible with --reload and --workers)")
26 api_parser.add_argument("--workers", type=int, default=None, help="Number of workers.")
27 api_parser.add_argument("--disable-colors", action="store_true", help="Don't use colors.")
28 api_parser.add_argument("--ignore-cookie-files", action="store_true", help="Don't read .har and cookie files. (incompatible with --reload and --workers)")
29 api_parser.add_argument("--g4f-api-key", type=str, default=None, help="Sets an authentication key for your API. (incompatible with --reload and --workers)")
30 api_parser.add_argument("--ignored-providers", nargs="+", choices=[provider.__name__ for provider in Provider.__providers__ if provider.working],
31 default=[], help="List of providers to ignore when processing request. (incompatible with --reload and --workers)")
32 api_parser.add_argument("--cookie-browsers", nargs="+", choices=[browser.__name__ for browser in cookies.BROWSERS],
33 default=[], help="List of browsers to access or retrieve cookies from. (incompatible with --reload and --workers)")
34 api_parser.add_argument("--reload", action="store_true", help="Enable reloading.")
36
37 api_parser.add_argument(
38 "--bind",
39 default=None,
40 help=f"The bind address (default: 0.0.0.0:{DEFAULT_PORT})."
41 )
42 api_parser.add_argument(
43 "--port", "-p",
44 default=None,
45 help=f"Port for the API server (default: {DEFAULT_PORT})."
46 )
47 api_parser.add_argument(
48 "--debug", "-d",
49 action="store_true",
50 help="Enable verbose logging."
51 )
52
53 # Deprecated GUI flag but kept for compatibility
54 api_parser.add_argument(
55 "--gui", "-g",
56 default=None,
57 action="store_true",
58 help="(deprecated) Use --no-gui instead."
59 )
60
61 api_parser.add_argument(
62 "--no-gui", "-ng",
63 default=False,
64 action="store_true",
65 help="Run API without the GUI."
66 )
67
68 api_parser.add_argument(
69 "--model",
70 default=None,
71 help="Default model for chat completion (incompatible with reload/workers)."
72 )
73
74 # Providers for chat completion
75 api_parser.add_argument(
76 "--provider",
77 choices=[p.__name__ for p in Provider.__providers__ if p.working],
78 default=None,
79 help="Default provider for chat completion."
80 )
81
82 # Providers for image generation
83 api_parser.add_argument(
84 "--media-provider",
85 choices=[
86 p.__name__ for p in Provider.__providers__
87 if p.working and bool(getattr(p, "image_models", False))
88 ],
89 default=None,
90 help="Default provider for image generation."
91 )
92
93 api_parser.add_argument(
94 "--proxy",
95 default=None,
96 help="Default HTTP proxy."
97 )
98
99 api_parser.add_argument(
100 "--workers",
101 type=int,
102 default=None,
103 help="Number of worker processes."
104 )
105
106 api_parser.add_argument(
107 "--disable-colors",
108 action="store_true",
109 help="Disable colorized output."
110 )
111
112 api_parser.add_argument(
113 "--ignore-cookie-files",
114 action="store_true",
115 help="Do not read .har or cookie files."
116 )
117
118 api_parser.add_argument(
119 "--g4f-api-key",
120 type=str,
121 default=None,
122 help="Authentication key for your API."
123 )
124
125 api_parser.add_argument(
126 "--ignored-providers",
127 nargs="+",
128 choices=[p.__name__ for p in Provider.__providers__ if p.working],
129 default=[],
130 help="Providers to ignore during request processing."
131 )
132
133 api_parser.add_argument(
134 "--cookie-browsers",
135 nargs="+",
136 choices=[browser.__name__ for browser in cookies.BROWSERS],
137 default=[],
138 help="Browsers to fetch cookies from."
139 )
140
141 api_parser.add_argument("--reload", action="store_true", help="Enable hot reload.")
35 142 api_parser.add_argument("--demo", action="store_true", help="Enable demo mode.")
36 api_parser.add_argument("--timeout", type=int, default=DEFAULT_TIMEOUT, help="Default timeout for requests in seconds. (incompatible with --reload and --workers)")
37 api_parser.add_argument("--stream-timeout", type=int, default=DEFAULT_STREAM_TIMEOUT, help="Default timeout for streaming requests in seconds. (incompatible with --reload and --workers)")
38 api_parser.add_argument("--ssl-keyfile", type=str, default=None, help="Path to SSL key file for HTTPS.")
39 api_parser.add_argument("--ssl-certfile", type=str, default=None, help="Path to SSL certificate file for HTTPS.")
40 api_parser.add_argument("--log-config", type=str, default=None, help="Custom log config.")
41 api_parser.add_argument("--browser-port", type=int, help="Port for the browser automation tool.")
42 api_parser.add_argument("--browser-host", type=str, default="127.0.0.1", help="Host for the browser automation tool.")
143
144 api_parser.add_argument(
145 "--timeout",
146 type=int,
147 default=DEFAULT_TIMEOUT,
148 help="Default request timeout in seconds."
149 )
150
151 api_parser.add_argument(
152 "--stream-timeout",
153 type=int,
154 default=DEFAULT_STREAM_TIMEOUT,
155 help="Default streaming timeout in seconds."
156 )
157
158 api_parser.add_argument("--ssl-keyfile", type=str, default=None, help="SSL key file.")
159 api_parser.add_argument("--ssl-certfile", type=str, default=None, help="SSL cert file.")
160 api_parser.add_argument("--log-config", type=str, default=None, help="Path to log config.")
161
162 api_parser.add_argument(
163 "--browser-port",
164 type=int,
165 help="Port for browser automation tool."
166 )
167
168 api_parser.add_argument(
169 "--browser-host",
170 type=str,
171 default="127.0.0.1",
172 help="Host for browser automation tool."
173 )
43 174
44 175 return api_parser
45 176
177
178 # --------------------------------------------------------------
179 # API RUNNER
180 # --------------------------------------------------------------
46 181 def run_api_args(args):
182 """
183 Runs the API server using the parsed CLI arguments.
184 """
47 185 from g4f.api import AppConfig, run_api
48 186
187 # Apply configuration
49 188 AppConfig.set_config(
50 189 ignore_cookie_files=args.ignore_cookie_files,
51 190 ignored_providers=args.ignored_providers,
@@ -60,12 +199,16 @@ def run_api_args(args):
60 199 stream_timeout=args.stream_timeout
61 200 )
62 201
202 # Browser automation config
63 203 if args.browser_port:
64 204 BrowserConfig.port = args.browser_port
65 205 BrowserConfig.host = args.browser_host
206
207 # Custom cookie browsers
66 208 if args.cookie_browsers:
67 cookies.BROWSERS = [cookies[browser] for browser in args.cookie_browsers]
209 cookies.BROWSERS = [cookies[b] for b in args.cookie_browsers]
68 210
211 # Launch server
69 212 run_api(
70 213 bind=args.bind,
71 214 port=args.port,
@@ -78,22 +221,49 @@ def run_api_args(args):
78 221 log_config=args.log_config,
79 222 )
80 223
81 def get_mcp_parser():
224
225 # --------------------------------------------------------------
226 # MCP PARSER
227 # --------------------------------------------------------------
228 def get_mcp_parser() -> ArgumentParser:
229 """
230 Parser for:
231 g4f mcp ...
232 """
82 233 mcp_parser = ArgumentParser(description="Run the MCP (Model Context Protocol) server")
83 234 mcp_parser.add_argument("--debug", "-d", action="store_true", help="Enable verbose logging.")
84 mcp_parser.add_argument("--http", action="store_true", help="Use HTTP transport instead of stdio.")
85 mcp_parser.add_argument("--host", default="0.0.0.0", help="Host to bind HTTP server to (default: 0.0.0.0)")
86 mcp_parser.add_argument("--port", type=int, default=8765, help="Port to bind HTTP server to (default: 8765)")
87 mcp_parser.add_argument("--origin", type=str, default=None, help="Origin URL for CORS (default: None)")
235 mcp_parser.add_argument("--http", action="store_true", help="Use HTTP instead of stdio.")
236 mcp_parser.add_argument("--host", default="0.0.0.0", help="HTTP server host.")
237 mcp_parser.add_argument("--port", type=int, default=8765, help="HTTP server port.")
238 mcp_parser.add_argument("--origin", type=str, default=None, help="CORS origin.")
88 239 return mcp_parser
89 240
241
90 242 def run_mcp_args(args):
243 """
244 Runs the MCP server with the chosen transport method.
245 """
91 246 from ..mcp.server import main as mcp_main
92 mcp_main(http=args.http, host=args.host, port=args.port, origin=args.origin)
247 mcp_main(
248 http=args.http,
249 host=args.host,
250 port=args.port,
251 origin=args.origin
252 )
253
93 254
255 # --------------------------------------------------------------
256 # MAIN ENTRYPOINT
257 # --------------------------------------------------------------
94 258 def main():
259 """
260 Main entry function exposed via CLI (e.g. g4f).
261 Handles selecting: api / gui / client / mcp
262 """
95 263 parser = argparse.ArgumentParser(description="Run gpt4free", exit_on_error=False)
96 subparsers = parser.add_subparsers(dest="mode", help="Mode to run the g4f in.")
264
265 # Create sub-commands
266 subparsers = parser.add_subparsers(dest="mode", help="Mode to run g4f in.")
97 267 subparsers.add_parser("api", parents=[get_api_parser()], add_help=False)
98 268 subparsers.add_parser("gui", parents=[gui_parser()], add_help=False)
99 269 subparsers.add_parser("client", parents=[get_parser()], add_help=False)
@@ -101,6 +271,8 @@ def main():
101 271
102 272 try:
103 273 args = parser.parse_args()
274
275 # Mode routing
104 276 if args.mode == "api":
105 277 run_api_args(args)
106 278 elif args.mode == "gui":
@@ -110,9 +282,20 @@ def main():
110 282 elif args.mode == "mcp":
111 283 run_mcp_args(args)
112 284 else:
113 raise argparse.ArgumentError(None, "No valid mode specified. Use 'api', 'gui', 'client', or 'mcp'.")
285 # No mode provided
286 raise argparse.ArgumentError(
287 None,
288 "No valid mode specified. Use 'api', 'gui', 'client', or 'mcp'."
289 )
290
114 291 except argparse.ArgumentError:
292 # Fallback chain:
293 # 1. Try client mode
115 294 try:
116 run_client_args(get_parser(exit_on_error=False).parse_args(), exit_on_error=False)
295 run_client_args(
296 get_parser(exit_on_error=False).parse_args(),
297 exit_on_error=False
298 )
117 299 except argparse.ArgumentError:
118 run_api_args(get_api_parser().parse_args())
300 # 2. Try API mode with default arguments
301 run_api_args(get_api_parser().parse_args())