XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet
公开
关注 0 Fork 0 Star 1
返回提交历史

XFEstudio/gpt4free

Update __init__.py

1e0b09b8
ThatLukinhasGuy <139662282+thatlukinhasguy1@users.noreply.github.com>
提交于

代码差异

1 个文件 +141 -200
Modified g4f/api/__init__.py +141 -200
@@ -1,227 +1,168 @@
1 import typing
2 from .. import BaseProvider
3 import g4f; g4f.debug.logging = True
1 from fastapi import FastAPI, Response, Request
2 from fastapi.middleware.cors import CORSMiddleware
3 from typing import List, Union, Any, Dict, AnyStr
4 from ._tokenizer import tokenize
5 import sqlite3
6 import g4f
4 7 import time
5 8 import json
6 9 import random
7 10 import string
8 import logging
9
10 from typing import Union
11 from loguru import logger
12 from waitress import serve
13 from ._logging import hook_logging
14 from ._tokenizer import tokenize
15 from flask_cors import CORS
16 from werkzeug.serving import WSGIRequestHandler
17 from werkzeug.exceptions import default_exceptions
18 from werkzeug.middleware.proxy_fix import ProxyFix
19
20 from flask import (
21 Flask,
22 jsonify,
23 make_response,
24 request,
11 import uvicorn
12 import nest_asyncio
13
14 app = FastAPI()
15 nest_asyncio.apply()
16
17 origins = [
18 "http://localhost",
19 "http://localhost:1337",
20 ]
21
22 app.add_middleware(
23 CORSMiddleware,
24 allow_origins=origins,
25 allow_credentials=True,
26 allow_methods=["*"],
27 allow_headers=["*"],
25 28 )
26 29
27 class Api:
28 __default_ip = '127.0.0.1'
29 __default_port = 1337
30
31 def __init__(self, engine: g4f, debug: bool = True, sentry: bool = False,
32 list_ignored_providers:typing.List[typing.Union[str, BaseProvider]]=None) -> None:
33 self.engine = engine
34 self.debug = debug
35 self.sentry = sentry
36 self.list_ignored_providers = list_ignored_providers
37 self.log_level = logging.DEBUG if debug else logging.WARN
38
39 hook_logging(level=self.log_level, format='[%(asctime)s] %(levelname)s in %(module)s: %(message)s')
40 self.logger = logging.getLogger('waitress')
41
42 self.app = Flask(__name__)
43 self.app.wsgi_app = ProxyFix(self.app.wsgi_app, x_port=1)
44 self.app.after_request(self.__after_request)
45
46 def run(self, bind_str, threads=8):
47 host, port = self.__parse_bind(bind_str)
48
49 CORS(self.app, resources={r'/v1/*': {'supports_credentials': True, 'expose_headers': [
50 'Content-Type',
51 'Authorization',
52 'X-Requested-With',
53 'Accept',
54 'Origin',
55 'Access-Control-Request-Method',
56 'Access-Control-Request-Headers',
57 'Content-Disposition'], 'max_age': 600}})
58
59 self.app.route('/v1/models', methods=['GET'])(self.models)
60 self.app.route('/v1/models/<model_id>', methods=['GET'])(self.model_info)
61
62 self.app.route('/v1/chat/completions', methods=['POST'])(self.chat_completions)
63 self.app.route('/v1/completions', methods=['POST'])(self.completions)
64
65 for ex in default_exceptions:
66 self.app.register_error_handler(ex, self.__handle_error)
67
68 if not self.debug:
69 self.logger.warning(f'Serving on http://{host}:{port}')
70
71 WSGIRequestHandler.protocol_version = 'HTTP/1.1'
72 serve(self.app, host=host, port=port, ident=None, threads=threads)
73
74 def __handle_error(self, e: Exception):
75 self.logger.error(e)
76
77 return make_response(jsonify({
78 'code': e.code,
79 'message': str(e.original_exception if self.debug and hasattr(e, 'original_exception') else e.name)}), 500)
80
81 @staticmethod
82 def __after_request(resp):
83 resp.headers['X-Server'] = f'g4f/{g4f.version}'
30 JSONObject = Dict[AnyStr, Any]
31 JSONArray = List[Any]
32 JSONStructure = Union[JSONArray, JSONObject]
33
34 @app.get("/")
35 async def read_root():
36 return Response(content=json.dumps({"info": "G4F API"}, indent=4), media_type="application/json")
37
38 @app.get("/v1")
39 async def read_root_v1():
40 return Response(content=json.dumps({"info": "Go to /v1/chat/completions or /v1/models."}, indent=4), media_type="application/json")
41
42 @app.get("/v1/models")
43 async def models():
44 model_list = [{
45 'id': model,
46 'object': 'model',
47 'created': 0,
48 'owned_by': 'g4f'} for model in g4f.Model.__all__()]
49
50 return Response(content=json.dumps({
51 'object': 'list',
52 'data': model_list}, indent=4), media_type="application/json")
53
54 @app.get("/v1/models/{model_name}")
55 async def model_info(model_name: str):
56 try:
57 model_info = (g4f.ModelUtils.convert[model_name])
84 58
85 return resp
86
87 def __parse_bind(self, bind_str):
88 sections = bind_str.split(':', 2)
89 if len(sections) < 2:
90 try:
91 port = int(sections[0])
92 return self.__default_ip, port
93 except ValueError:
94 return sections[0], self.__default_port
95
96 return sections[0], int(sections[1])
97
98 async def home(self):
99 return 'Hello world | https://127.0.0.1:1337/v1'
59 return Response(content=json.dumps({
60 'id': model_name,
61 'object': 'model',
62 'created': 0,
63 'owned_by': model_info.base_provider
64 }, indent=4), media_type="application/json")
65 except:
66 return Response(content=json.dumps({"error": "The model does not exist."}, indent=4), media_type="application/json")
67
68 @app.post("/v1/chat/completions")
69 async def chat_completions(request: Request, item: JSONStructure = None):
70
71 item_data = {
72 'model': 'gpt-3.5-turbo',
73 'stream': False,
74 }
100 75
101 async def chat_completions(self):
102 model = request.json.get('model', 'gpt-3.5-turbo')
103 stream = request.json.get('stream', False)
104 messages = request.json.get('messages')
105
106 logger.info(f'model: {model}, stream: {stream}, request: {messages[-1]["content"]}')
76 item_data.update(item or {})
77 model = item_data.get('model')
78 stream = item_data.get('stream')
79 messages = item_data.get('messages')
80
81 try:
82 response = g4f.ChatCompletion.create(model=model, stream=stream, messages=messages)
83 except:
84 return Response(content=json.dumps({"error": "An error occurred while generating the response."}, indent=4), media_type="application/json")
85
86 completion_id = ''.join(random.choices(string.ascii_letters + string.digits, k=28))
87 completion_timestamp = int(time.time())
88
89 if not stream:
90 prompt_tokens, _ = tokenize(''.join([message['content'] for message in messages]))
91 completion_tokens, _ = tokenize(response)
92
93 json_data = {
94 'id': f'chatcmpl-{completion_id}',
95 'object': 'chat.completion',
96 'created': completion_timestamp,
97 'model': model,
98 'choices': [
99 {
100 'index': 0,
101 'message': {
102 'role': 'assistant',
103 'content': response,
104 },
105 'finish_reason': 'stop',
106 }
107 ],
108 'usage': {
109 'prompt_tokens': prompt_tokens,
110 'completion_tokens': completion_tokens,
111 'total_tokens': prompt_tokens + completion_tokens,
112 },
113 }
107 114
108 config = None
109 proxy = None
115 return Response(content=json.dumps(json_data, indent=4), media_type="application/json")
110 116
117 def streaming():
111 118 try:
112 config = json.load(open("config.json","r",encoding="utf-8"))
113 proxy = config["proxy"]
119 for chunk in response:
120 completion_data = {
121 'id': f'chatcmpl-{completion_id}',
122 'object': 'chat.completion.chunk',
123 'created': completion_timestamp,
124 'model': model,
125 'choices': [
126 {
127 'index': 0,
128 'delta': {
129 'content': chunk,
130 },
131 'finish_reason': None,
132 }
133 ],
134 }
114 135
115 except Exception:
116 pass
136 content = json.dumps(completion_data, separators=(',', ':'))
137 yield f'data: {content}\n\n'
138 time.sleep(0.03)
117 139
118 if proxy != None:
119 response = self.engine.ChatCompletion.create(model=model,
120 stream=stream, messages=messages,
121 ignored=self.list_ignored_providers,
122 proxy=proxy)
123 else:
124 response = self.engine.ChatCompletion.create(model=model,
125 stream=stream, messages=messages,
126 ignored=self.list_ignored_providers)
127
128 completion_id = ''.join(random.choices(string.ascii_letters + string.digits, k=28))
129 completion_timestamp = int(time.time())
130
131 if not stream:
132 prompt_tokens, _ = tokenize(''.join([message['content'] for message in messages]))
133 completion_tokens, _ = tokenize(response)
134
135 return {
140 end_completion_data = {
136 141 'id': f'chatcmpl-{completion_id}',
137 'object': 'chat.completion',
142 'object': 'chat.completion.chunk',
138 143 'created': completion_timestamp,
139 144 'model': model,
140 145 'choices': [
141 146 {
142 147 'index': 0,
143 'message': {
144 'role': 'assistant',
145 'content': response,
146 },
148 'delta': {},
147 149 'finish_reason': 'stop',
148 150 }
149 151 ],
150 'usage': {
151 'prompt_tokens': prompt_tokens,
152 'completion_tokens': completion_tokens,
153 'total_tokens': prompt_tokens + completion_tokens,
154 },
155 152 }
156 153
157 def streaming():
158 try:
159 for chunk in response:
160 completion_data = {
161 'id': f'chatcmpl-{completion_id}',
162 'object': 'chat.completion.chunk',
163 'created': completion_timestamp,
164 'model': model,
165 'choices': [
166 {
167 'index': 0,
168 'delta': {
169 'content': chunk,
170 },
171 'finish_reason': None,
172 }
173 ],
174 }
154 content = json.dumps(end_completion_data, separators=(',', ':'))
155 yield f'data: {content}\n\n'
175 156
176 content = json.dumps(completion_data, separators=(',', ':'))
177 yield f'data: {content}\n\n'
178 time.sleep(0.03)
157 except GeneratorExit:
158 pass
179 159
180 end_completion_data = {
181 'id': f'chatcmpl-{completion_id}',
182 'object': 'chat.completion.chunk',
183 'created': completion_timestamp,
184 'model': model,
185 'choices': [
186 {
187 'index': 0,
188 'delta': {},
189 'finish_reason': 'stop',
190 }
191 ],
192 }
193
194 content = json.dumps(end_completion_data, separators=(',', ':'))
195 yield f'data: {content}\n\n'
196
197 logger.success(f'model: {model}, stream: {stream}')
198
199 except GeneratorExit:
200 pass
160 return Response(content=json.dumps(streaming(), indent=4), media_type="application/json")
201 161
202 return self.app.response_class(streaming(), mimetype='text/event-stream')
203
204 async def completions(self):
205 return 'not working yet', 500
206
207 async def model_info(self, model_name):
208 model_info = (g4f.ModelUtils.convert[model_name])
209
210 return jsonify({
211 'id' : model_name,
212 'object' : 'model',
213 'created' : 0,
214 'owned_by' : model_info.base_provider
215 })
216
217 async def models(self):
218 model_list = [{
219 'id' : model,
220 'object' : 'model',
221 'created' : 0,
222 'owned_by' : 'g4f'} for model in g4f.Model.__all__()]
223
224 return jsonify({
225 'object': 'list',
226 'data': model_list})
227
162 @app.post("/v1/completions")
163 async def completions():
164 return Response(content=json.dumps({'info': 'Not working yet.'}, indent=4), media_type="application/json")
165
166 def run(ip):
167 split_ip = ip.split(":")
168 uvicorn.run(app, host=split_ip[0], port=int(split_ip[1]), use_colors=False, loop='asyncio')