返回提交历史
Modified
g4f/api/__init__.py
+41
-5
Modified
g4f/cli.py
+2
-0
XFEstudio/gpt4free
add authorization for g4f API
112ca638
代码差异
2 个文件
+43
-5
@@ -3,11 +3,14 @@ from __future__ import annotations
3
3
import logging
4
4
import json
5
5
import uvicorn
6
import secrets
6
7
7
8
from fastapi import FastAPI, Response, Request
8
9
from fastapi.responses import StreamingResponse, RedirectResponse, HTMLResponse, JSONResponse
9
10
from fastapi.exceptions import RequestValidationError
10
from starlette.status import HTTP_422_UNPROCESSABLE_ENTITY
11
from fastapi.security import APIKeyHeader
12
from starlette.exceptions import HTTPException
13
from starlette.status import HTTP_422_UNPROCESSABLE_ENTITY, HTTP_401_UNAUTHORIZED, HTTP_403_FORBIDDEN
11
14
from fastapi.encoders import jsonable_encoder
12
15
from pydantic import BaseModel
13
16
from typing import Union, Optional
@@ -17,10 +20,13 @@ import g4f.debug
17
20
from g4f.client import AsyncClient
18
21
from g4f.typing import Messages
19
22
20
def create_app() -> FastAPI:
23
global _g4f_api_key
24
25
def create_app():
21
26
app = FastAPI()
22
api = Api(app)
27
api = Api(app, g4f_api_key=_g4f_api_key)
23
28
api.register_routes()
29
api.register_authorization()
24
30
api.register_validation_exception_handler()
25
31
return app
26
32
@@ -43,9 +49,34 @@ def set_list_ignored_providers(ignored: list[str]):
43
49
list_ignored_providers = ignored
44
50
45
51
class Api:
46
def __init__(self, app: FastAPI) -> None:
52
def __init__(self, app: FastAPI, g4f_api_key=None) -> None:
47
53
self.app = app
48
54
self.client = AsyncClient()
55
self.g4f_api_key = g4f_api_key
56
print(g4f_api_key)
57
self.get_g4f_api_key = APIKeyHeader(name="g4f-api-key")
58
59
def register_authorization(self):
60
@self.app.middleware("http")
61
async def authorization(request: Request, call_next):
62
if self.g4f_api_key and request.url.path in ["/v1/chat/completions", "/v1/completions"]:
63
try:
64
user_g4f_api_key = await self.get_g4f_api_key(request)
65
except HTTPException as e:
66
if e.status_code == 403:
67
print(e)
68
return JSONResponse(
69
status_code=HTTP_401_UNAUTHORIZED,
70
content=jsonable_encoder({"detail": "G4F API key required"}),
71
)
72
if not secrets.compare_digest(self.g4f_api_key, user_g4f_api_key):
73
return JSONResponse(
74
status_code=HTTP_403_FORBIDDEN,
75
content=jsonable_encoder({"detail": "Invalid G4F API key"}),
76
)
77
78
response = await call_next(request)
79
return response
49
80
50
81
def register_validation_exception_handler(self):
51
82
@self.app.exception_handler(RequestValidationError)
@@ -153,8 +184,13 @@ def run_api(
153
184
bind: str = None,
154
185
debug: bool = False,
155
186
workers: int = None,
187
g4f_api_key: str = None,
156
188
use_colors: bool = None
157
189
) -> None:
190
191
global _g4f_api_key
192
_g4f_api_key = g4f_api_key
193
158
194
print(f'Starting server... [g4f v-{g4f.version.utils.current_version}]' + (" (debug)" if debug else ""))
159
195
if use_colors is None:
160
196
use_colors = debug
@@ -162,4 +198,4 @@ def run_api(
162
198
host, port = bind.split(":")
163
199
if debug:
164
200
g4f.debug.logging = True
165
uvicorn.run("g4f.api:create_app", host=host, port=int(port), workers=workers, use_colors=use_colors, factory=True)#
201
uvicorn.run("g4f.api:create_app", host=host, port=int(port), workers=workers, use_colors=use_colors, factory=True)
@@ -16,6 +16,7 @@ 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.")
19
20
api_parser.add_argument("--ignored-providers", nargs="+", choices=[provider for provider in Provider.__map__],
20
21
default=[], help="List of providers to ignore when processing request.")
21
22
subparsers.add_parser("gui", parents=[gui_parser()], add_help=False)
@@ -42,6 +43,7 @@ def run_api_args(args):
42
43
bind=args.bind,
43
44
debug=args.debug,
44
45
workers=args.workers,
46
g4f_api_key=args.g4f_api_key,
45
47
use_colors=not args.disable_colors
46
48
)
47
49