返回提交历史
Modified
g4f/cli/__init__.py
+222
-39
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
代码差异
1 个文件
+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())