gpt4free

Форк
0
/
__init__.py 
198 строк · 7.9 Кб
1
import ast
2
import logging
3
import time
4
import json
5
import random
6
import string
7
import uvicorn
8
import nest_asyncio
9

10
from fastapi           import FastAPI, Response, Request
11
from fastapi.responses import StreamingResponse
12
from typing            import List, Union, Any, Dict, AnyStr
13
#from ._tokenizer       import tokenize
14

15
import g4f
16
from .. import debug
17

18
debug.logging = True
19

20
class Api:
21
    def __init__(self, engine: g4f, debug: bool = True, sentry: bool = False,
22
                 list_ignored_providers: List[str] = None) -> None:
23
        self.engine = engine
24
        self.debug = debug
25
        self.sentry = sentry
26
        self.list_ignored_providers = list_ignored_providers
27

28
        self.app = FastAPI()
29
        nest_asyncio.apply()
30

31
        JSONObject = Dict[AnyStr, Any]
32
        JSONArray = List[Any]
33
        JSONStructure = Union[JSONArray, JSONObject]
34

35
        @self.app.get("/")
36
        async def read_root():
37
            return Response(content=json.dumps({"info": "g4f API"}, indent=4), media_type="application/json")
38

39
        @self.app.get("/v1")
40
        async def read_root_v1():
41
            return Response(content=json.dumps({"info": "Go to /v1/chat/completions or /v1/models."}, indent=4), media_type="application/json")
42

43
        @self.app.get("/v1/models")
44
        async def models():
45
            model_list = []
46
            for model in g4f.Model.__all__():
47
                model_info = (g4f.ModelUtils.convert[model])
48
                model_list.append({
49
                'id': model,
50
                'object': 'model',
51
                'created': 0,
52
                'owned_by': model_info.base_provider}
53
                )
54
            return Response(content=json.dumps({
55
                'object': 'list',
56
                'data': model_list}, indent=4), media_type="application/json")
57

58
        @self.app.get("/v1/models/{model_name}")
59
        async def model_info(model_name: str):
60
            try:
61
                model_info = (g4f.ModelUtils.convert[model_name])
62

63
                return Response(content=json.dumps({
64
                    'id': model_name,
65
                    'object': 'model',
66
                    'created': 0,
67
                    'owned_by': model_info.base_provider
68
                }, indent=4), media_type="application/json")
69
            except:
70
                return Response(content=json.dumps({"error": "The model does not exist."}, indent=4), media_type="application/json")
71

72
        @self.app.post("/v1/chat/completions")
73
        async def chat_completions(request: Request, item: JSONStructure = None):
74
            item_data = {
75
                'model': 'gpt-3.5-turbo',
76
                'stream': False,
77
            }
78

79
            # item contains byte keys, and dict.get suppresses error
80
            item_data.update({
81
                key.decode('utf-8') if isinstance(key, bytes) else key: str(value)
82
                for key, value in (item or {}).items()
83
            })
84
            # messages is str, need dict
85
            if isinstance(item_data.get('messages'), str):
86
                item_data['messages'] = ast.literal_eval(item_data.get('messages'))
87

88
            model = item_data.get('model')
89
            stream = True if item_data.get("stream") == "True" else False
90
            messages = item_data.get('messages')
91
            provider = item_data.get('provider', '').replace('g4f.Provider.', '')
92
            provider = provider if provider and provider != "Auto" else None
93

94
            try:
95
                response = g4f.ChatCompletion.create(
96
                    model=model,
97
                    stream=stream,
98
                    messages=messages,
99
                    provider = provider,
100
                    ignored=self.list_ignored_providers
101
                )
102
            except Exception as e:
103
                logging.exception(e)
104
                content = json.dumps({
105
                    "error": {"message": f"An error occurred while generating the response:\n{e}"},
106
                    "model": model,
107
                    "provider": g4f.get_last_provider(True)
108
                })
109
                return Response(content=content, status_code=500, media_type="application/json")
110
            completion_id = ''.join(random.choices(string.ascii_letters + string.digits, k=28))
111
            completion_timestamp = int(time.time())
112

113
            if not stream:
114
                #prompt_tokens, _ = tokenize(''.join([message['content'] for message in messages]))
115
                #completion_tokens, _ = tokenize(response)
116

117
                json_data = {
118
                    'id': f'chatcmpl-{completion_id}',
119
                    'object': 'chat.completion',
120
                    'created': completion_timestamp,
121
                    'model': model,
122
                    'provider': g4f.get_last_provider(True),
123
                    'choices': [
124
                        {
125
                            'index': 0,
126
                            'message': {
127
                                'role': 'assistant',
128
                                'content': response,
129
                            },
130
                            'finish_reason': 'stop',
131
                        }
132
                    ],
133
                    'usage': {
134
                        'prompt_tokens': 0, #prompt_tokens,
135
                        'completion_tokens': 0, #completion_tokens,
136
                        'total_tokens': 0, #prompt_tokens + completion_tokens,
137
                    },
138
                }
139

140
                return Response(content=json.dumps(json_data, indent=4), media_type="application/json")
141

142
            def streaming():
143
                try:
144
                    for chunk in response:
145
                        completion_data = {
146
                            'id': f'chatcmpl-{completion_id}',
147
                            'object': 'chat.completion.chunk',
148
                            'created': completion_timestamp,
149
                            'model': model,
150
                            'provider': g4f.get_last_provider(True),
151
                            'choices': [
152
                                {
153
                                    'index': 0,
154
                                    'delta': {
155
                                        'role': 'assistant',
156
                                        'content': chunk,
157
                                    },
158
                                    'finish_reason': None,
159
                                }
160
                            ],
161
                        }
162
                        yield f'data: {json.dumps(completion_data)}\n\n'
163
                        time.sleep(0.03)
164
                    end_completion_data = {
165
                        'id': f'chatcmpl-{completion_id}',
166
                        'object': 'chat.completion.chunk',
167
                        'created': completion_timestamp,
168
                        'model': model,
169
                        'provider': g4f.get_last_provider(True),
170
                        'choices': [
171
                            {
172
                                'index': 0,
173
                                'delta': {},
174
                                'finish_reason': 'stop',
175
                            }
176
                        ],
177
                    }
178
                    yield f'data: {json.dumps(end_completion_data)}\n\n'
179
                except GeneratorExit:
180
                    pass
181
                except Exception as e:
182
                    logging.exception(e)
183
                    content = json.dumps({
184
                        "error": {"message": f"An error occurred while generating the response:\n{e}"},
185
                        "model": model,
186
                        "provider": g4f.get_last_provider(True),
187
                    })
188
                    yield f'data: {content}'
189

190
            return StreamingResponse(streaming(), media_type="text/event-stream")
191

192
        @self.app.post("/v1/completions")
193
        async def completions():
194
            return Response(content=json.dumps({'info': 'Not working yet.'}, indent=4), media_type="application/json")
195

196
    def run(self, ip):
197
        split_ip = ip.split(":")
198
        uvicorn.run(app=self.app, host=split_ip[0], port=int(split_ip[1]), use_colors=False)
199

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.