mirror of
https://github.com/xtekky/gpt4free.git
synced 2025-10-13 12:03:45 +08:00
Add AppConfig class, update readme
This commit is contained in:
20
README.md
20
README.md
@@ -862,8 +862,8 @@ A list of all contributors is available [here](https://github.com/xtekky/gpt4fre
|
|||||||
<a href="https://github.com/Commenter123321" target="_blank"><img src="https://avatars.githubusercontent.com/u/36051603?v=4&s=45" width="45" title="Commenter123321"></a>
|
<a href="https://github.com/Commenter123321" target="_blank"><img src="https://avatars.githubusercontent.com/u/36051603?v=4&s=45" width="45" title="Commenter123321"></a>
|
||||||
<a href="https://github.com/DanielShemesh" target="_blank"><img src="https://avatars.githubusercontent.com/u/20585236?v=4&s=45" width="45" title="DanielShemesh"></a>
|
<a href="https://github.com/DanielShemesh" target="_blank"><img src="https://avatars.githubusercontent.com/u/20585236?v=4&s=45" width="45" title="DanielShemesh"></a>
|
||||||
<a href="https://github.com/Luneye" target="_blank"><img src="https://avatars.githubusercontent.com/u/73485421?v=4&s=45" width="45" title="Luneye"></a>
|
<a href="https://github.com/Luneye" target="_blank"><img src="https://avatars.githubusercontent.com/u/73485421?v=4&s=45" width="45" title="Luneye"></a>
|
||||||
<a href="https://github.com/enganese" target="_blank"><img src="https://avatars.githubusercontent.com/u/69082498?v=4&s=45" width="45" title="enganese"></a>
|
|
||||||
<a href="https://github.com/ezerinz" target="_blank"><img src="https://avatars.githubusercontent.com/u/100193740?v=4&s=45" width="45" title="ezerinz"></a>
|
<a href="https://github.com/ezerinz" target="_blank"><img src="https://avatars.githubusercontent.com/u/100193740?v=4&s=45" width="45" title="ezerinz"></a>
|
||||||
|
<a href="https://github.com/enganese" target="_blank"><img src="https://avatars.githubusercontent.com/u/69082498?v=4&s=45" width="45" title="enganese"></a>
|
||||||
<a href="https://github.com/Lin-jun-xiang" target="_blank"><img src="https://avatars.githubusercontent.com/u/63782903?v=4&s=45" width="45" title="Lin-jun-xiang"></a>
|
<a href="https://github.com/Lin-jun-xiang" target="_blank"><img src="https://avatars.githubusercontent.com/u/63782903?v=4&s=45" width="45" title="Lin-jun-xiang"></a>
|
||||||
<a href="https://github.com/nullstreak" target="_blank"><img src="https://avatars.githubusercontent.com/u/139914347?v=4&s=45" width="45" title="nullstreak"></a>
|
<a href="https://github.com/nullstreak" target="_blank"><img src="https://avatars.githubusercontent.com/u/139914347?v=4&s=45" width="45" title="nullstreak"></a>
|
||||||
<a href="https://github.com/valerii-chirkov" target="_blank"><img src="https://avatars.githubusercontent.com/u/81074936?v=4&s=45" width="45" title="valerii-chirkov"></a>
|
<a href="https://github.com/valerii-chirkov" target="_blank"><img src="https://avatars.githubusercontent.com/u/81074936?v=4&s=45" width="45" title="valerii-chirkov"></a>
|
||||||
@@ -871,16 +871,16 @@ A list of all contributors is available [here](https://github.com/xtekky/gpt4fre
|
|||||||
<a href="https://github.com/repollo" target="_blank"><img src="https://avatars.githubusercontent.com/u/2671466?v=4&s=45" width="45" title="repollo"></a>
|
<a href="https://github.com/repollo" target="_blank"><img src="https://avatars.githubusercontent.com/u/2671466?v=4&s=45" width="45" title="repollo"></a>
|
||||||
<a href="https://github.com/hpsj" target="_blank"><img src="https://avatars.githubusercontent.com/u/54535414?v=4&s=45" width="45" title="hpsj"></a>
|
<a href="https://github.com/hpsj" target="_blank"><img src="https://avatars.githubusercontent.com/u/54535414?v=4&s=45" width="45" title="hpsj"></a>
|
||||||
<a href="https://github.com/taiyi747" target="_blank"><img src="https://avatars.githubusercontent.com/u/63543716?v=4&s=45" width="45" title="taiyi747"></a>
|
<a href="https://github.com/taiyi747" target="_blank"><img src="https://avatars.githubusercontent.com/u/63543716?v=4&s=45" width="45" title="taiyi747"></a>
|
||||||
<a href="https://github.com/ostix360" target="_blank"><img src="https://avatars.githubusercontent.com/u/55257054?v=4&s=45" width="45" title="ostix360"></a>
|
|
||||||
<a href="https://github.com/WdR-Tech" target="_blank"><img src="https://avatars.githubusercontent.com/u/143020293?v=4&s=45" width="45" title="WdR-Tech"></a>
|
|
||||||
<a href="https://github.com/HexyeDEV" target="_blank"><img src="https://avatars.githubusercontent.com/u/65314629?v=4&s=45" width="45" title="HexyeDEV"></a>
|
|
||||||
<a href="https://github.com/9fo" target="_blank"><img src="https://avatars.githubusercontent.com/u/71867245?v=4&s=45" width="45" title="9fo"></a>
|
<a href="https://github.com/9fo" target="_blank"><img src="https://avatars.githubusercontent.com/u/71867245?v=4&s=45" width="45" title="9fo"></a>
|
||||||
<a href="https://github.com/eltociear" target="_blank"><img src="https://avatars.githubusercontent.com/u/22633385?v=4&s=45" width="45" title="eltociear"></a>
|
<a href="https://github.com/HexyeDEV" target="_blank"><img src="https://avatars.githubusercontent.com/u/65314629?v=4&s=45" width="45" title="HexyeDEV"></a>
|
||||||
<a href="https://github.com/ramonvc" target="_blank"><img src="https://avatars.githubusercontent.com/u/13617054?v=4&s=45" width="45" title="ramonvc"></a>
|
<a href="https://github.com/WdR-Tech" target="_blank"><img src="https://avatars.githubusercontent.com/u/143020293?v=4&s=45" width="45" title="WdR-Tech"></a>
|
||||||
<a href="https://github.com/naa7" target="_blank"><img src="https://avatars.githubusercontent.com/u/44613678?v=4&s=45" width="45" title="naa7"></a>
|
<a href="https://github.com/ostix360" target="_blank"><img src="https://avatars.githubusercontent.com/u/55257054?v=4&s=45" width="45" title="ostix360"></a>
|
||||||
<a href="https://github.com/zeng-rr" target="_blank"><img src="https://avatars.githubusercontent.com/u/47846202?v=4&s=45" width="45" title="zeng-rr"></a>
|
|
||||||
<a href="https://github.com/editor-syntax" target="_blank"><img src="https://avatars.githubusercontent.com/u/109844019?v=4&s=45" width="45" title="editor-syntax"></a>
|
|
||||||
<a href="https://github.com/devAdityaa" target="_blank"><img src="https://avatars.githubusercontent.com/u/77636021?v=4&s=45" width="45" title="devAdityaa"></a>
|
<a href="https://github.com/devAdityaa" target="_blank"><img src="https://avatars.githubusercontent.com/u/77636021?v=4&s=45" width="45" title="devAdityaa"></a>
|
||||||
|
<a href="https://github.com/editor-syntax" target="_blank"><img src="https://avatars.githubusercontent.com/u/109844019?v=4&s=45" width="45" title="editor-syntax"></a>
|
||||||
|
<a href="https://github.com/zeng-rr" target="_blank"><img src="https://avatars.githubusercontent.com/u/47846202?v=4&s=45" width="45" title="zeng-rr"></a>
|
||||||
|
<a href="https://github.com/naa7" target="_blank"><img src="https://avatars.githubusercontent.com/u/44613678?v=4&s=45" width="45" title="naa7"></a>
|
||||||
|
<a href="https://github.com/ramonvc" target="_blank"><img src="https://avatars.githubusercontent.com/u/13617054?v=4&s=45" width="45" title="ramonvc"></a>
|
||||||
|
<a href="https://github.com/eltociear" target="_blank"><img src="https://avatars.githubusercontent.com/u/22633385?v=4&s=45" width="45" title="eltociear"></a>
|
||||||
<a href="https://github.com/kggn" target="_blank"><img src="https://avatars.githubusercontent.com/u/95663228?v=4&s=45" width="45" title="kggn"></a>
|
<a href="https://github.com/kggn" target="_blank"><img src="https://avatars.githubusercontent.com/u/95663228?v=4&s=45" width="45" title="kggn"></a>
|
||||||
<a href="https://github.com/xiangsx" target="_blank"><img src="https://avatars.githubusercontent.com/u/29322721?v=4&s=45" width="45" title="xiangsx"></a>
|
<a href="https://github.com/xiangsx" target="_blank"><img src="https://avatars.githubusercontent.com/u/29322721?v=4&s=45" width="45" title="xiangsx"></a>
|
||||||
<a href="https://github.com/ggindinson" target="_blank"><img src="https://avatars.githubusercontent.com/u/97807772?v=4&s=45" width="45" title="ggindinson"></a>
|
<a href="https://github.com/ggindinson" target="_blank"><img src="https://avatars.githubusercontent.com/u/97807772?v=4&s=45" width="45" title="ggindinson"></a>
|
||||||
@@ -889,12 +889,14 @@ A list of all contributors is available [here](https://github.com/xtekky/gpt4fre
|
|||||||
<img src="https://avatars.githubusercontent.com/u/12299238?s=45&v=4" width="45" title="xqdoo00o">
|
<img src="https://avatars.githubusercontent.com/u/12299238?s=45&v=4" width="45" title="xqdoo00o">
|
||||||
<img src="https://avatars.githubusercontent.com/u/97126670?s=45&v=4" width="45" title="nathanrchn">
|
<img src="https://avatars.githubusercontent.com/u/97126670?s=45&v=4" width="45" title="nathanrchn">
|
||||||
<img src="https://avatars.githubusercontent.com/u/81407603?v=4&s=45" width="45" title="dsdanielpark">
|
<img src="https://avatars.githubusercontent.com/u/81407603?v=4&s=45" width="45" title="dsdanielpark">
|
||||||
|
<img src="https://avatars.githubusercontent.com/u/55200481?v=4&s=45" width="45" title="missuo">
|
||||||
|
|
||||||
- The [`Vercel.py`](https://github.com/xtekky/gpt4free/blob/main/g4f/Provider/Vercel.py) file contains code from [vercel-llm-api](https://github.com/ading2210/vercel-llm-api) by [@ading2210](https://github.com/ading2210)
|
- The [`Vercel.py`](https://github.com/xtekky/gpt4free/blob/main/g4f/Provider/Vercel.py) file contains code from [vercel-llm-api](https://github.com/ading2210/vercel-llm-api) by [@ading2210](https://github.com/ading2210)
|
||||||
- The [`har_file.py`](https://github.com/xtekky/gpt4free/blob/main/g4f/Provider/openai/har_file.py) has input from [xqdoo00o/ChatGPT-to-API](https://github.com/xqdoo00o/ChatGPT-to-API)
|
- The [`har_file.py`](https://github.com/xtekky/gpt4free/blob/main/g4f/Provider/openai/har_file.py) has input from [xqdoo00o/ChatGPT-to-API](https://github.com/xqdoo00o/ChatGPT-to-API)
|
||||||
- The [`PerplexityLabs.py`](https://github.com/xtekky/gpt4free/blob/main/g4f/Provider/openai/har_file.py) has input from [nathanrchn/perplexityai](https://github.com/nathanrchn/perplexityai)
|
- The [`PerplexityLabs.py`](https://github.com/xtekky/gpt4free/blob/main/g4f/Provider/openai/har_file.py) has input from [nathanrchn/perplexityai](https://github.com/nathanrchn/perplexityai)
|
||||||
- The [`Gemini.py`](https://github.com/xtekky/gpt4free/blob/main/g4f/Provider/needs_auth/Gemini.py) has input from [dsdanielpark/Gemini-API](https://github.com/dsdanielpark/Gemini-API)
|
- The [`Gemini.py`](https://github.com/xtekky/gpt4free/blob/main/g4f/Provider/needs_auth/Gemini.py) has input from [dsdanielpark/Gemini-API](https://github.com/dsdanielpark/Gemini-API)
|
||||||
- The [`MetaAI.py`](https://github.com/xtekky/gpt4free/blob/main/g4f/Provider/MetaAI.py) file contains code from [meta-ai-api](https://github.com/Strvm/meta-ai-api) by [@Strvm](https://github.com/Strvm)
|
- The [`MetaAI.py`](https://github.com/xtekky/gpt4free/blob/main/g4f/Provider/MetaAI.py) file contains code from [meta-ai-api](https://github.com/Strvm/meta-ai-api) by [@Strvm](https://github.com/Strvm)
|
||||||
|
- The [`proofofwork.py`](https://github.com/xtekky/gpt4free/blob/main/g4f/Provider/openai/proofofwork.py) has input from [missuo/FreeGPT35](https://github.com/missuo/FreeGPT35)
|
||||||
|
|
||||||
*Having input implies that the AI's code generation utilized it as one of many sources.*
|
*Having input implies that the AI's code generation utilized it as one of many sources.*
|
||||||
|
|
||||||
|
@@ -19,6 +19,7 @@ import g4f
|
|||||||
import g4f.debug
|
import g4f.debug
|
||||||
from g4f.client import AsyncClient
|
from g4f.client import AsyncClient
|
||||||
from g4f.typing import Messages
|
from g4f.typing import Messages
|
||||||
|
from g4f.cookies import read_cookie_files
|
||||||
|
|
||||||
def create_app():
|
def create_app():
|
||||||
app = FastAPI()
|
app = FastAPI()
|
||||||
@@ -26,13 +27,15 @@ def create_app():
|
|||||||
api.register_routes()
|
api.register_routes()
|
||||||
api.register_authorization()
|
api.register_authorization()
|
||||||
api.register_validation_exception_handler()
|
api.register_validation_exception_handler()
|
||||||
|
if not AppConfig.ignore_cookie_files:
|
||||||
|
read_cookie_files()
|
||||||
return app
|
return app
|
||||||
|
|
||||||
def create_debug_app():
|
def create_app_debug():
|
||||||
g4f.debug.logging = True
|
g4f.debug.logging = True
|
||||||
return create_app()
|
return create_app()
|
||||||
|
|
||||||
class ChatCompletionsConfig(BaseModel):
|
class ChatCompletionsForm(BaseModel):
|
||||||
messages: Messages
|
messages: Messages
|
||||||
model: str
|
model: str
|
||||||
provider: Optional[str] = None
|
provider: Optional[str] = None
|
||||||
@@ -44,17 +47,22 @@ class ChatCompletionsConfig(BaseModel):
|
|||||||
web_search: Optional[bool] = None
|
web_search: Optional[bool] = None
|
||||||
proxy: Optional[str] = None
|
proxy: Optional[str] = None
|
||||||
|
|
||||||
list_ignored_providers: list[str] = None
|
class AppConfig():
|
||||||
|
list_ignored_providers: Optional[list[str]] = None
|
||||||
|
g4f_api_key: Optional[str] = None
|
||||||
|
ignore_cookie_files: bool = False
|
||||||
|
|
||||||
def set_list_ignored_providers(ignored: list[str]):
|
@classmethod
|
||||||
global list_ignored_providers
|
def set_list_ignored_providers(cls, ignored: list[str]):
|
||||||
list_ignored_providers = ignored
|
cls.list_ignored_providers = ignored
|
||||||
|
|
||||||
g4f_api_key: str = None
|
@classmethod
|
||||||
|
def set_g4f_api_key(cls, key: str = None):
|
||||||
|
cls.g4f_api_key = key
|
||||||
|
|
||||||
def set_g4f_api_key(key: str = None):
|
@classmethod
|
||||||
global g4f_api_key
|
def set_ignore_cookie_files(cls, value: bool):
|
||||||
g4f_api_key = key
|
cls.ignore_cookie_files = value
|
||||||
|
|
||||||
class Api:
|
class Api:
|
||||||
def __init__(self, app: FastAPI) -> None:
|
def __init__(self, app: FastAPI) -> None:
|
||||||
@@ -65,7 +73,7 @@ class Api:
|
|||||||
def register_authorization(self):
|
def register_authorization(self):
|
||||||
@self.app.middleware("http")
|
@self.app.middleware("http")
|
||||||
async def authorization(request: Request, call_next):
|
async def authorization(request: Request, call_next):
|
||||||
if g4f_api_key and request.url.path in ["/v1/chat/completions", "/v1/completions"]:
|
if AppConfig.g4f_api_key and request.url.path in ["/v1/chat/completions", "/v1/completions"]:
|
||||||
try:
|
try:
|
||||||
user_g4f_api_key = await self.get_g4f_api_key(request)
|
user_g4f_api_key = await self.get_g4f_api_key(request)
|
||||||
except HTTPException as e:
|
except HTTPException as e:
|
||||||
@@ -74,7 +82,7 @@ class Api:
|
|||||||
status_code=HTTP_401_UNAUTHORIZED,
|
status_code=HTTP_401_UNAUTHORIZED,
|
||||||
content=jsonable_encoder({"detail": "G4F API key required"}),
|
content=jsonable_encoder({"detail": "G4F API key required"}),
|
||||||
)
|
)
|
||||||
if not secrets.compare_digest(g4f_api_key, user_g4f_api_key):
|
if not secrets.compare_digest(AppConfig.g4f_api_key, user_g4f_api_key):
|
||||||
return JSONResponse(
|
return JSONResponse(
|
||||||
status_code=HTTP_403_FORBIDDEN,
|
status_code=HTTP_403_FORBIDDEN,
|
||||||
content=jsonable_encoder({"detail": "Invalid G4F API key"}),
|
content=jsonable_encoder({"detail": "Invalid G4F API key"}),
|
||||||
@@ -108,10 +116,10 @@ class Api:
|
|||||||
|
|
||||||
@self.app.get("/v1/models")
|
@self.app.get("/v1/models")
|
||||||
async def models():
|
async def models():
|
||||||
model_list = dict(
|
model_list = {
|
||||||
(model, g4f.models.ModelUtils.convert[model])
|
model: g4f.models.ModelUtils.convert[model]
|
||||||
for model in g4f.Model.__all__()
|
for model in g4f.Model.__all__()
|
||||||
)
|
}
|
||||||
model_list = [{
|
model_list = [{
|
||||||
'id': model_id,
|
'id': model_id,
|
||||||
'object': 'model',
|
'object': 'model',
|
||||||
@@ -134,7 +142,7 @@ class Api:
|
|||||||
return JSONResponse({"error": "The model does not exist."})
|
return JSONResponse({"error": "The model does not exist."})
|
||||||
|
|
||||||
@self.app.post("/v1/chat/completions")
|
@self.app.post("/v1/chat/completions")
|
||||||
async def chat_completions(config: ChatCompletionsConfig, request: Request = None, provider: str = None):
|
async def chat_completions(config: ChatCompletionsForm, request: Request = None, provider: str = None):
|
||||||
try:
|
try:
|
||||||
config.provider = provider if config.provider is None else config.provider
|
config.provider = provider if config.provider is None else config.provider
|
||||||
if config.api_key is None and request is not None:
|
if config.api_key is None and request is not None:
|
||||||
@@ -145,7 +153,7 @@ class Api:
|
|||||||
config.api_key = auth_header
|
config.api_key = auth_header
|
||||||
response = self.client.chat.completions.create(
|
response = self.client.chat.completions.create(
|
||||||
**config.dict(exclude_none=True),
|
**config.dict(exclude_none=True),
|
||||||
ignored=list_ignored_providers
|
ignored=AppConfig.list_ignored_providers
|
||||||
)
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.exception(e)
|
logging.exception(e)
|
||||||
@@ -171,7 +179,7 @@ class Api:
|
|||||||
async def completions():
|
async def completions():
|
||||||
return Response(content=json.dumps({'info': 'Not working yet.'}, indent=4), media_type="application/json")
|
return Response(content=json.dumps({'info': 'Not working yet.'}, indent=4), media_type="application/json")
|
||||||
|
|
||||||
def format_exception(e: Exception, config: ChatCompletionsConfig) -> str:
|
def format_exception(e: Exception, config: ChatCompletionsForm) -> str:
|
||||||
last_provider = g4f.get_last_provider(True)
|
last_provider = g4f.get_last_provider(True)
|
||||||
return json.dumps({
|
return json.dumps({
|
||||||
"error": {"message": f"{e.__class__.__name__}: {e}"},
|
"error": {"message": f"{e.__class__.__name__}: {e}"},
|
||||||
@@ -193,7 +201,7 @@ def run_api(
|
|||||||
if bind is not None:
|
if bind is not None:
|
||||||
host, port = bind.split(":")
|
host, port = bind.split(":")
|
||||||
uvicorn.run(
|
uvicorn.run(
|
||||||
f"g4f.api:{'create_debug_app' if debug else 'create_app'}",
|
f"g4f.api:{'create_app_debug' if debug else 'create_app'}",
|
||||||
host=host, port=int(port),
|
host=host, port=int(port),
|
||||||
workers=workers,
|
workers=workers,
|
||||||
use_colors=use_colors,
|
use_colors=use_colors,
|
||||||
|
18
g4f/cli.py
18
g4f/cli.py
@@ -4,8 +4,6 @@ import argparse
|
|||||||
|
|
||||||
from g4f import Provider
|
from g4f import Provider
|
||||||
from g4f.gui.run import gui_parser, run_gui_args
|
from g4f.gui.run import gui_parser, run_gui_args
|
||||||
from g4f.cookies import read_cookie_files
|
|
||||||
from g4f import debug
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
parser = argparse.ArgumentParser(description="Run gpt4free")
|
parser = argparse.ArgumentParser(description="Run gpt4free")
|
||||||
@@ -31,18 +29,18 @@ def main():
|
|||||||
exit(1)
|
exit(1)
|
||||||
|
|
||||||
def run_api_args(args):
|
def run_api_args(args):
|
||||||
if args.debug:
|
from g4f.api import AppConfig, run_api
|
||||||
debug.logging = True
|
|
||||||
if not args.ignore_cookie_files:
|
AppConfig.set_ignore_cookie_files(
|
||||||
read_cookie_files()
|
args.ignore_cookie_files
|
||||||
import g4f.api
|
)
|
||||||
g4f.api.set_list_ignored_providers(
|
AppConfig.set_list_ignored_providers(
|
||||||
args.ignored_providers
|
args.ignored_providers
|
||||||
)
|
)
|
||||||
g4f.api.set_g4f_api_key(
|
AppConfig.set_g4f_api_key(
|
||||||
args.g4f_api_key
|
args.g4f_api_key
|
||||||
)
|
)
|
||||||
g4f.api.run_api(
|
run_api(
|
||||||
bind=args.bind,
|
bind=args.bind,
|
||||||
debug=args.debug,
|
debug=args.debug,
|
||||||
workers=args.workers,
|
workers=args.workers,
|
||||||
|
Reference in New Issue
Block a user