返回提交历史
Modified
docs/interference-api.md
+1
-1
Modified
g4f/Provider/PollinationsAI.py
+9
-8
Modified
g4f/Provider/template/BackendApi.py
+1
-1
Modified
g4f/Provider/template/OpenaiTemplate.py
+11
-15
Modified
g4f/api/__init__.py
+4
-4
XFEstudio/gpt4free
Update openai example in docs, add default api_key
fa2344b0
代码差异
5 个文件
+26
-29
@@ -103,7 +103,7 @@ curl -X POST "http://localhost:1337/v1/images/generate" \
103
103
from openai import OpenAI
104
104
105
105
client = OpenAI(
106
api_key="",
106
api_key="secret",
107
107
base_url="http://localhost:1337/v1"
108
108
)
109
109
@@ -157,13 +157,14 @@ class PollinationsAI(AsyncGeneratorProvider, ProviderModelMixin):
157
157
) -> AsyncResult:
158
158
# Load model list
159
159
cls.get_models()
160
if not model and media is not None:
161
has_audio = False
162
for media_data, filename in media:
163
if is_data_an_audio(media_data, filename):
164
has_audio = True
165
break
166
model = next(iter(cls.audio_models)) if has_audio else cls.default_vision_model
160
if not model:
161
has_audio = "audio" in kwargs
162
if not has_audio and media is not None:
163
for media_data, filename in media:
164
if is_data_an_audio(media_data, filename):
165
has_audio = True
166
break
167
model = next(iter(cls.audio_models)) if has_audio else model
167
168
try:
168
169
model = cls.get_model(model)
169
170
except ModelNotFoundError:
@@ -278,7 +279,7 @@ class PollinationsAI(AsyncGeneratorProvider, ProviderModelMixin):
278
279
}
279
280
for media_data, filename in media
280
281
]
281
last_message["content"] = image_content + [{"type": "text", "text": last_message["content"]}]
282
last_message["content"] = image_content + ([{"type": "text", "text": last_message["content"]}] if isinstance(last_message["content"], str) else image_content)
282
283
messages[-1] = last_message
283
284
284
285
async with ClientSession(headers=DEFAULT_HEADERS, connector=get_connector(proxy=proxy)) as session:
@@ -25,7 +25,7 @@ class BackendApi(AsyncGeneratorProvider, ProviderModelMixin):
25
25
debug.log(f"{cls.__name__}: {api_key}")
26
26
if media is not None:
27
27
for i in range(len(media)):
28
media[i] = (to_data_uri(media[i][0]), media[i][1])
28
media[i] = (to_data_uri(media[i][0], media[i][1]), media[i][1])
29
29
async with StreamSession(
30
30
headers={"Accept": "text/event-stream", **cls.headers},
31
31
) as session:
@@ -102,23 +102,19 @@ class OpenaiTemplate(AsyncGeneratorProvider, ProviderModelMixin, RaiseErrorMixin
102
102
if not model and hasattr(cls, "default_vision_model"):
103
103
model = cls.default_vision_model
104
104
last_message = messages[-1].copy()
105
last_message["content"] = [
106
*[
107
{
108
"type": "input_audio",
109
"input_audio": to_input_audio(media_data, filename)
110
}
111
if is_data_an_audio(media_data, filename) else {
112
"type": "image_url",
113
"image_url": {"url": to_data_uri(media_data, filename)}
114
}
115
for media_data, filename in media
116
],
105
image_content = [
117
106
{
118
"type": "text",
119
"text": last_message["content"]
120
} if isinstance(last_message["content"], str) else last_message["content"]
107
"type": "input_audio",
108
"input_audio": to_input_audio(media_data, filename)
109
}
110
if is_data_an_audio(media_data, filename) else {
111
"type": "image_url",
112
"image_url": {"url": to_data_uri(media_data)}
113
}
114
for media_data, filename in media
121
115
]
116
last_message["content"] = image_content + ([{"type": "text", "text": last_message["content"]}] if isinstance(last_message["content"], str) else image_content)
117
122
118
messages[-1] = last_message
123
119
extra_parameters = {key: kwargs[key] for key in extra_parameters if key in kwargs}
124
120
data = filter_none(
@@ -177,7 +177,7 @@ class Api:
177
177
if path.startswith("/v1") or path.startswith("/api/") or (AppConfig.demo and path == '/backend-api/v2/upload_cookies'):
178
178
if user_g4f_api_key is None:
179
179
return ErrorResponse.from_message("G4F API key required", HTTP_401_UNAUTHORIZED)
180
if not secrets.compare_digest(AppConfig.g4f_api_key, user_g4f_api_key):
180
if AppConfig.g4f_api_key is None or not secrets.compare_digest(AppConfig.g4f_api_key, user_g4f_api_key):
181
181
return ErrorResponse.from_message("Invalid G4F API key", HTTP_403_FORBIDDEN)
182
182
elif not AppConfig.demo and not path.startswith("/images/"):
183
183
if user_g4f_api_key is not None:
@@ -305,7 +305,7 @@ class Api:
305
305
try:
306
306
if config.provider is None:
307
307
config.provider = AppConfig.provider if provider is None else provider
308
if credentials is not None:
308
if credentials is not None and credentials.credentials != "secret":
309
309
config.api_key = credentials.credentials
310
310
311
311
conversation = return_conversation = None
@@ -328,7 +328,7 @@ class Api:
328
328
if config.media is not None:
329
329
for image in config.media:
330
330
try:
331
is_data_an_media(image[0])
331
is_data_an_media(image[0], image[1])
332
332
except ValueError as e:
333
333
example = json.dumps({"media": [["data:image/jpeg;base64,...", "filename.jpg"]]})
334
334
return ErrorResponse.from_message(f'The media you send must be a data URIs. Example: {example}', status_code=HTTP_422_UNPROCESSABLE_ENTITY)
@@ -410,7 +410,7 @@ class Api:
410
410
config: ImageGenerationConfig,
411
411
credentials: Annotated[HTTPAuthorizationCredentials, Depends(Api.security)] = None
412
412
):
413
if credentials is not None:
413
if credentials is not None and credentials.credentials != "secret":
414
414
config.api_key = credentials.credentials
415
415
try:
416
416
response = await self.client.images.generate(