返回提交历史
Modified
g4f/Provider/Ai4Chat.py
+2
-1
Modified
g4f/Provider/Mhystical.py
+4
-2
Modified
g4f/Provider/you/har_file.py
+4
-4
Modified
g4f/__init__.py
+9
-0
Modified
g4f/api/__init__.py
+5
-3
Modified
g4f/api/_logging.py
+18
-18
Modified
g4f/gui/server/api.py
+4
-2
Modified
requirements.txt
+0
-1
Modified
setup.py
+1
-1
XFEstudio/gpt4free
Improve logging implementation (#2347)
f38428ab
代码差异
9 个文件
+47
-32
@@ -9,6 +9,7 @@ from ..typing import AsyncResult, Messages
9
9
from .base_provider import AsyncGeneratorProvider, ProviderModelMixin
10
10
from .helper import format_prompt
11
11
12
logger = logging.getLogger(__name__)
12
13
13
14
class Ai4Chat(AsyncGeneratorProvider, ProviderModelMixin):
14
15
label = "AI4Chat"
@@ -84,5 +85,5 @@ class Ai4Chat(AsyncGeneratorProvider, ProviderModelMixin):
84
85
85
86
yield clean_message
86
87
except Exception as e:
87
logging.exception("Error while calling AI 4Chat API: %s", e)
88
logger.exception("Error while calling AI 4Chat API: %s", e)
88
89
yield f"Error: {e}"
@@ -18,6 +18,8 @@ from .helper import format_prompt
18
18
19
19
"""
20
20
21
logger = logging.getLogger(__name__)
22
21
23
class Mhystical(AsyncGeneratorProvider, ProviderModelMixin):
22
24
url = "https://api.mhystical.cc"
23
25
api_endpoint = "https://api.mhystical.cc/v1/completions"
@@ -84,5 +86,5 @@ class Mhystical(AsyncGeneratorProvider, ProviderModelMixin):
84
86
message_content = json_response["choices"][0]["message"]["content"]
85
87
return message_content
86
88
except (KeyError, IndexError, json.JSONDecodeError) as e:
87
logging.error("Error parsing response: %s", e)
88
return "Error: Failed to parse response from API."
89
logger.error("Error parsing response: %s", e)
90
return "Error: Failed to parse response from API."
@@ -11,7 +11,7 @@ from ...cookies import get_cookies_dir
11
11
from ...errors import MissingRequirementsError
12
12
from ... import debug
13
13
14
logging.basicConfig(level=logging.ERROR)
14
logger = logging.getLogger(__name__)
15
15
16
16
class NoValidHarFileError(Exception):
17
17
...
@@ -81,14 +81,14 @@ async def get_telemetry_ids(proxy: str = None) -> list:
81
81
return [await create_telemetry_id(proxy)]
82
82
except NoValidHarFileError as e:
83
83
if debug.logging:
84
logging.error(e)
84
logger.error(e)
85
85
86
86
try:
87
87
from nodriver import start
88
88
except ImportError:
89
89
raise MissingRequirementsError('Add .har file from you.com or install "nodriver" package | pip install -U nodriver')
90
90
if debug.logging:
91
logging.error('Getting telemetry_id for you.com with nodriver')
91
logger.error('Getting telemetry_id for you.com with nodriver')
92
92
93
93
browser = page = None
94
94
try:
@@ -112,4 +112,4 @@ async def get_telemetry_ids(proxy: str = None) -> list:
112
112
await browser.stop()
113
113
except Exception as e:
114
114
if debug.logging:
115
logging.error(e)
115
logger.error(e)
@@ -1,6 +1,7 @@
1
1
from __future__ import annotations
2
2
3
3
import os
4
import logging
4
5
5
6
from . import debug, version
6
7
from .models import Model
@@ -12,6 +13,14 @@ from .providers.types import ProviderType
12
13
from .providers.base_provider import AsyncGeneratorProvider
13
14
from .client.service import get_model_and_provider, get_last_provider
14
15
16
#Configure "g4f" logger
17
logger = logging.getLogger(__name__)
18
log_handler = logging.StreamHandler()
19
log_handler.setFormatter(logging.Formatter(logging.BASIC_FORMAT))
20
logger.addHandler(log_handler)
21
22
logger.setLevel(logging.ERROR)
23
15
24
class ChatCompletion:
16
25
@staticmethod
17
26
def create(model : Union[Model, str],
@@ -22,6 +22,8 @@ from g4f.client import Client, ChatCompletion, ChatCompletionChunk, ImagesRespon
22
22
from g4f.typing import Messages
23
23
from g4f.cookies import read_cookie_files
24
24
25
logger = logging.getLogger(__name__)
26
25
27
def create_app(g4f_api_key: str = None):
26
28
app = FastAPI()
27
29
@@ -200,14 +202,14 @@ class Api:
200
202
except GeneratorExit:
201
203
pass
202
204
except Exception as e:
203
logging.exception(e)
205
logger.exception(e)
204
206
yield f'data: {format_exception(e, config)}\n\n'
205
207
yield "data: [DONE]\n\n"
206
208
207
209
return StreamingResponse(streaming(), media_type="text/event-stream")
208
210
209
211
except Exception as e:
210
logging.exception(e)
212
logger.exception(e)
211
213
return Response(content=format_exception(e, config), status_code=500, media_type="application/json")
212
214
213
215
@self.app.post("/v1/images/generate")
@@ -222,7 +224,7 @@ class Api:
222
224
response_data = [image.to_dict() for image in response.data]
223
225
return JSONResponse({"data": response_data})
224
226
except Exception as e:
225
logging.exception(e)
227
logger.exception(e)
226
228
return Response(content=format_exception(e, config), status_code=500, media_type="application/json")
227
229
228
230
@self.app.post("/v1/completions")
@@ -1,6 +1,6 @@
1
1
import sys,logging
2
2
3
from loguru import logger
3
#from loguru import logger
4
4
5
5
def __exception_handle(e_type, e_value, e_traceback):
6
6
if issubclass(e_type, KeyboardInterrupt):
@@ -9,24 +9,24 @@ def __exception_handle(e_type, e_value, e_traceback):
9
9
10
10
sys.__excepthook__(e_type, e_value, e_traceback)
11
11
12
class __InterceptHandler(logging.Handler):
13
def emit(self, record):
14
try:
15
level = logger.level(record.levelname).name
16
except ValueError:
17
level = record.levelno
18
19
frame, depth = logging.currentframe(), 2
20
while frame.f_code.co_filename == logging.__file__:
21
frame = frame.f_back
22
depth += 1
23
24
logger.opt(depth=depth, exception=record.exc_info).log(
25
level, record.getMessage()
26
)
12
#class __InterceptHandler(logging.Handler):
13
# def emit(self, record):
14
# try:
15
# level = logger.level(record.levelname).name
16
# except ValueError:
17
# level = record.levelno
18
#
19
# frame, depth = logging.currentframe(), 2
20
# while frame.f_code.co_filename == logging.__file__:
21
# frame = frame.f_back
22
# depth += 1
23
24
# logger.opt(depth=depth, exception=record.exc_info).log(
25
# level, record.getMessage()
26
# )
27
27
28
28
def hook_except_handle():
29
29
sys.excepthook = __exception_handle
30
30
31
def hook_logging(**kwargs):
32
logging.basicConfig(handlers=[__InterceptHandler()], **kwargs)
31
#def hook_logging(**kwargs):
32
# logging.basicConfig(handlers=[__InterceptHandler()], **kwargs)
@@ -19,6 +19,8 @@ from g4f.Provider import ProviderType, __providers__, __map__
19
19
from g4f.providers.base_provider import ProviderModelMixin, FinishReason
20
20
from g4f.providers.conversation import BaseConversation
21
21
22
logger = logging.getLogger(__name__)
23
22
24
# Define the directory for generated images
23
25
images_dir = "./generated_images"
24
26
@@ -155,7 +157,7 @@ class Api:
155
157
conversations[provider][conversation_id] = chunk
156
158
yield self._format_json("conversation", conversation_id)
157
159
elif isinstance(chunk, Exception):
158
logging.exception(chunk)
160
logger.exception(chunk)
159
161
yield self._format_json("message", get_error_message(chunk))
160
162
elif isinstance(chunk, ImagePreview):
161
163
yield self._format_json("preview", chunk.to_string())
@@ -165,7 +167,7 @@ class Api:
165
167
elif not isinstance(chunk, FinishReason):
166
168
yield self._format_json("content", str(chunk))
167
169
except Exception as e:
168
logging.exception(e)
170
logger.exception(e)
169
171
yield self._format_json('error', get_error_message(e))
170
172
171
173
async def _copy_images(self, images: list[str], cookies: Optional[Cookies] = None):
@@ -8,7 +8,6 @@ PyExecJS
8
8
duckduckgo-search>=5.0
9
9
nest_asyncio
10
10
werkzeug
11
loguru
12
11
pillow
13
12
platformdirs
14
13
fastapi
@@ -39,7 +39,7 @@ EXTRA_REQUIRE = {
39
39
"pillow", # image
40
40
"cairosvg", # svg image
41
41
"werkzeug", "flask", # gui
42
"loguru", "fastapi", # api
42
"fastapi", # api
43
43
"uvicorn", "nest_asyncio", # api
44
44
"pycryptodome" # openai
45
45
],