返回提交历史
Modified
g4f/api/__init__.py
+33
-24
Modified
g4f/cli.py
+6
-4
XFEstudio/gpt4free
Fix workers argument in api
26d5fcd2
代码差异
2 个文件
+39
-28
@@ -20,14 +20,18 @@ import g4f.debug
20
20
from g4f.client import AsyncClient
21
21
from g4f.typing import Messages
22
22
23
def create_app(g4f_api_key:str = None):
23
def create_app():
24
24
app = FastAPI()
25
api = Api(app, g4f_api_key=g4f_api_key)
25
api = Api(app)
26
26
api.register_routes()
27
27
api.register_authorization()
28
28
api.register_validation_exception_handler()
29
29
return app
30
30
31
def create_debug_app():
32
g4f.debug.logging = True
33
return create_app()
34
31
35
class ChatCompletionsConfig(BaseModel):
32
36
messages: Messages
33
37
model: str
@@ -46,17 +50,22 @@ def set_list_ignored_providers(ignored: list[str]):
46
50
global list_ignored_providers
47
51
list_ignored_providers = ignored
48
52
53
g4f_api_key: str = None
54
55
def set_g4f_api_key(key: str = None):
56
global g4f_api_key
57
g4f_api_key = key
58
49
59
class Api:
50
def __init__(self, app: FastAPI, g4f_api_key=None) -> None:
60
def __init__(self, app: FastAPI) -> None:
51
61
self.app = app
52
62
self.client = AsyncClient()
53
self.g4f_api_key = g4f_api_key
54
63
self.get_g4f_api_key = APIKeyHeader(name="g4f-api-key")
55
64
56
65
def register_authorization(self):
57
66
@self.app.middleware("http")
58
67
async def authorization(request: Request, call_next):
59
if self.g4f_api_key and request.url.path in ["/v1/chat/completions", "/v1/completions"]:
68
if g4f_api_key and request.url.path in ["/v1/chat/completions", "/v1/completions"]:
60
69
try:
61
70
user_g4f_api_key = await self.get_g4f_api_key(request)
62
71
except HTTPException as e:
@@ -65,26 +74,22 @@ class Api:
65
74
status_code=HTTP_401_UNAUTHORIZED,
66
75
content=jsonable_encoder({"detail": "G4F API key required"}),
67
76
)
68
if not secrets.compare_digest(self.g4f_api_key, user_g4f_api_key):
77
if not secrets.compare_digest(g4f_api_key, user_g4f_api_key):
69
78
return JSONResponse(
70
status_code=HTTP_403_FORBIDDEN,
71
content=jsonable_encoder({"detail": "Invalid G4F API key"}),
72
)
73
74
response = await call_next(request)
75
return response
79
status_code=HTTP_403_FORBIDDEN,
80
content=jsonable_encoder({"detail": "Invalid G4F API key"}),
81
)
82
return await call_next(request)
76
83
77
84
def register_validation_exception_handler(self):
78
85
@self.app.exception_handler(RequestValidationError)
79
86
async def validation_exception_handler(request: Request, exc: RequestValidationError):
80
87
details = exc.errors()
81
modified_details = []
82
for error in details:
83
modified_details.append({
84
"loc": error["loc"],
85
"message": error["msg"],
86
"type": error["type"],
87
})
88
modified_details = [{
89
"loc": error["loc"],
90
"message": error["msg"],
91
"type": error["type"],
92
} for error in details]
88
93
return JSONResponse(
89
94
status_code=HTTP_422_UNPROCESSABLE_ENTITY,
90
95
content=jsonable_encoder({"detail": modified_details}),
@@ -180,14 +185,18 @@ def run_api(
180
185
bind: str = None,
181
186
debug: bool = False,
182
187
workers: int = None,
183
use_colors: bool = None,
184
g4f_api_key: str = None
188
use_colors: bool = None
185
189
) -> None:
186
190
print(f'Starting server... [g4f v-{g4f.version.utils.current_version}]' + (" (debug)" if debug else ""))
187
191
if use_colors is None:
188
192
use_colors = debug
189
193
if bind is not None:
190
194
host, port = bind.split(":")
191
if debug:
192
g4f.debug.logging = True
193
uvicorn.run(create_app(g4f_api_key), host=host, port=int(port), workers=workers, use_colors=use_colors)
195
uvicorn.run(
196
f"g4f.api:{'create_debug_app' if debug else 'create_app'}",
197
host=host, port=int(port),
198
workers=workers,
199
use_colors=use_colors,
200
factory=True,
201
reload=debug
202
)
@@ -16,9 +16,9 @@ def main():
16
16
api_parser.add_argument("--workers", type=int, default=None, help="Number of workers.")
17
17
api_parser.add_argument("--disable-colors", action="store_true", help="Don't use colors.")
18
18
api_parser.add_argument("--ignore-cookie-files", action="store_true", help="Don't read .har and cookie files.")
19
api_parser.add_argument("--g4f-api-key", type=str, default=None, help="Sets an authentication key for your API.")
20
api_parser.add_argument("--ignored-providers", nargs="+", choices=[provider for provider in Provider.__map__],
21
default=[], help="List of providers to ignore when processing request.")
19
api_parser.add_argument("--g4f-api-key", type=str, default=None, help="Sets an authentication key for your API. (incompatible with --debug and --workers)")
20
api_parser.add_argument("--ignored-providers", nargs="+", choices=[provider.__name__ for provider in Provider.__providers__ if provider.working],
21
default=[], help="List of providers to ignore when processing request. (incompatible with --debug and --workers)")
22
22
subparsers.add_parser("gui", parents=[gui_parser()], add_help=False)
23
23
24
24
args = parser.parse_args()
@@ -39,11 +39,13 @@ def run_api_args(args):
39
39
g4f.api.set_list_ignored_providers(
40
40
args.ignored_providers
41
41
)
42
g4f.api.set_g4f_api_key(
43
args.g4f_api_key
44
)
42
45
g4f.api.run_api(
43
46
bind=args.bind,
44
47
debug=args.debug,
45
48
workers=args.workers,
46
g4f_api_key=args.g4f_api_key,
47
49
use_colors=not args.disable_colors
48
50
)
49
51