Spaces:
Runtime error
Runtime error
Upload 5 files
Browse files- LEGAL +26 -0
- LICENSE +21 -0
- README.md +93 -15
- app.py +197 -151
- requirements.txt +4 -4
LEGAL
ADDED
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Legal Notice
|
2 |
+
Reverse Engineering Disclaimer
|
3 |
+
|
4 |
+
DeepInfra-Wrapper is a project developed for educational purposes and is not affiliated with or endorsed by DeepInfra or any associated entities. The use of this project is subject to the following legal notice.
|
5 |
+
Educational Purposes Only
|
6 |
+
|
7 |
+
DeepInfra-Wrapper was created solely for educational and research purposes to explore and understand the functionality of the DeepInfra API. The reverse-engineering efforts undertaken in this project are intended to enhance knowledge and skills related to software development and API interaction.
|
8 |
+
Not Authorized by DeepInfra
|
9 |
+
|
10 |
+
This project, including its codebase and associated documentation, is not authorized by DeepInfra or any affiliated parties. It is an independent initiative that aims to provide a learning resource for individuals interested in working with APIs and Flask applications.
|
11 |
+
Ethical Usage
|
12 |
+
|
13 |
+
Users are expected to adhere to ethical standards when using DeepInfra-Wrapper. The project should be utilized responsibly and in compliance with applicable laws and regulations. Any use of DeepInfra-Wrapper for malicious or unauthorized activities is strictly prohibited.
|
14 |
+
No Warranty
|
15 |
+
|
16 |
+
DeepInfra-Wrapper is distributed "as is" and without any warranty. The authors and contributors of this project make no representations or warranties regarding the accuracy, functionality, or reliability of the code. Users are solely responsible for their use of the project.
|
17 |
+
Legal Implications
|
18 |
+
|
19 |
+
Users of DeepInfra-Wrapper are responsible for ensuring that their use complies with all relevant laws and regulations. Any unauthorized or improper use of the project may result in legal consequences. The authors and contributors disclaim any liability arising from the use of DeepInfra-Wrapper.
|
20 |
+
Open Source License
|
21 |
+
|
22 |
+
DeepInfra-Wrapper is released under the MIT License. Users are encouraged to review and comply with the terms of this license.
|
23 |
+
|
24 |
+
By using DeepInfra-Wrapper, you acknowledge that you have read and understood this legal notice and agree to use the project responsibly and in accordance with applicable laws.
|
25 |
+
|
26 |
+
For any inquiries or concerns related to this legal notice, please contact the project maintainers.
|
LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
MIT License
|
2 |
+
|
3 |
+
Copyright (c) 2023 4sh
|
4 |
+
|
5 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6 |
+
of this software and associated documentation files (the "Software"), to deal
|
7 |
+
in the Software without restriction, including without limitation the rights
|
8 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9 |
+
copies of the Software, and to permit persons to whom the Software is
|
10 |
+
furnished to do so, subject to the following conditions:
|
11 |
+
|
12 |
+
The above copyright notice and this permission notice shall be included in all
|
13 |
+
copies or substantial portions of the Software.
|
14 |
+
|
15 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21 |
+
SOFTWARE.
|
README.md
CHANGED
@@ -1,20 +1,98 @@
|
|
1 |
-
|
2 |
-
title: Test Space
|
3 |
-
emoji: 🌍
|
4 |
-
colorFrom: yellow
|
5 |
-
colorTo: indigo
|
6 |
-
sdk: docker
|
7 |
-
pinned: false
|
8 |
-
license: mit
|
9 |
-
---
|
10 |
|
11 |
-
|
12 |
|
|
|
13 |
|
14 |
-
|
15 |
|
16 |
-
|
17 |
-
2) Create a new app with `shiny create .`
|
18 |
-
3) Then run the app with `shiny run --reload`
|
19 |
|
20 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# DeepInfra-Wrapper
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
+
DeepInfra-Wrapper is a Python Flask project designed to provide a convenient and free interface for utilizing the DeepInfra API through reverse-engineering. It serves as a local and global server host, allowing users to interact with the DeepInfra chat completion models using Python requests.
|
4 |
|
5 |
+
## Features
|
6 |
|
7 |
+
- **Local and Global Server**: Choose between a local server or utilize a global server with Cloudflare integration for enhanced performance.
|
8 |
|
9 |
+
- **Chat Completion**: Easily generate chat completions by sending messages to the DeepInfra API.
|
|
|
|
|
10 |
|
11 |
+
- **Model Selection**: Access a variety of models for different use cases.
|
12 |
+
|
13 |
+
- **Streaming Support**: Enable real-time streaming for dynamic chat interactions.
|
14 |
+
|
15 |
+
## Getting Started
|
16 |
+
|
17 |
+
### Prerequisites
|
18 |
+
|
19 |
+
- Python 3.6 or higher
|
20 |
+
- Flask
|
21 |
+
- Flask-CORS
|
22 |
+
- Flask-Cloudflared
|
23 |
+
- Requests
|
24 |
+
- Fake User Agent
|
25 |
+
|
26 |
+
### Installation
|
27 |
+
|
28 |
+
1. Clone the repository:
|
29 |
+
|
30 |
+
```bash
|
31 |
+
git clone https://github.com/Recentaly/DeepInfra-Wrapper.git
|
32 |
+
```
|
33 |
+
|
34 |
+
2. Install dependencies:
|
35 |
+
|
36 |
+
```bash
|
37 |
+
pip install -r requirements.txt
|
38 |
+
```
|
39 |
+
|
40 |
+
3. Run the Flask application:
|
41 |
+
|
42 |
+
```bash
|
43 |
+
python app.py
|
44 |
+
```
|
45 |
+
|
46 |
+
## Configuration
|
47 |
+
|
48 |
+
Adjust the configuration settings in the `assets/config.json` file to customize your DeepInfra-Wrapper experience.
|
49 |
+
|
50 |
+
```json
|
51 |
+
{
|
52 |
+
"use_global": true
|
53 |
+
}
|
54 |
+
```
|
55 |
+
|
56 |
+
## Usage
|
57 |
+
|
58 |
+
### Chat Completion
|
59 |
+
|
60 |
+
Send a POST request to `/chat/completions` with the following JSON payload (messages must be in OpenAI format):
|
61 |
+
|
62 |
+
```json
|
63 |
+
{
|
64 |
+
"messages": [{"role": "user", "content": "Hello, World!"}],
|
65 |
+
"model": "meta-llama/Llama-2-70b-chat-hf",
|
66 |
+
"max_tokens": 150,
|
67 |
+
"top_p": 1,
|
68 |
+
"stream": true
|
69 |
+
}
|
70 |
+
```
|
71 |
+
|
72 |
+
### Get Models
|
73 |
+
|
74 |
+
Retrieve the available models by sending a GET request to `/models`.
|
75 |
+
|
76 |
+
### Check API Status
|
77 |
+
|
78 |
+
Verify the API status by accessing the root route `/`.
|
79 |
+
|
80 |
+
## Error Handling
|
81 |
+
|
82 |
+
The API gracefully handles errors, such as forbidden requests, providing meaningful error messages.
|
83 |
+
|
84 |
+
## Google Colab
|
85 |
+
|
86 |
+
The server is also usable on [This Google Colab Link](https://colab.research.google.com/drive/15sQ6sjZJYUincL3otypxfH96aCfLQ7HZ?usp=sharing)
|
87 |
+
|
88 |
+
## License
|
89 |
+
|
90 |
+
This project is licensed under the [MIT License](LICENSE).
|
91 |
+
|
92 |
+
## Acknowledgments
|
93 |
+
|
94 |
+
- Special thanks to the DeepInfra team for providing the chat completion models.
|
95 |
+
|
96 |
+
## Contact
|
97 |
+
|
98 |
+
For issues and inquiries, please open an [issue](https://github.com/Recentaly/DeepInfra-Wrapper/issues).
|
app.py
CHANGED
@@ -1,151 +1,197 @@
|
|
1 |
-
|
2 |
-
|
3 |
-
import
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
import
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
)
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# ---------------------------------------- IMPORTS ---------------------------------------- #
|
2 |
+
|
3 |
+
# import flask and flask_cors to host the api
|
4 |
+
from flask import Flask, request, jsonify, render_template
|
5 |
+
from flask_cors import CORS
|
6 |
+
|
7 |
+
# import the api class
|
8 |
+
from assets.source import api, non_streamed_format
|
9 |
+
|
10 |
+
# import addon
|
11 |
+
from assets.source.addons import * # here we only use 'create_cloudflare_tunnel' and 'translate' from the addons
|
12 |
+
|
13 |
+
# logging module for debugging
|
14 |
+
import logging
|
15 |
+
|
16 |
+
# json module to parse json
|
17 |
+
from json import loads
|
18 |
+
|
19 |
+
# ---------------------------------------- CONFIGURE LOCAL SERVER ---------------------------------------- #
|
20 |
+
|
21 |
+
# create flask app
|
22 |
+
app = Flask(__name__)
|
23 |
+
app.template_folder = "assets/templates"
|
24 |
+
|
25 |
+
# enable cors
|
26 |
+
CORS(app)
|
27 |
+
|
28 |
+
# ---------------------------------------- READ FROM CONFIG FILE ---------------------------------------- #
|
29 |
+
with (open("assets/config.json", "r")) as f:
|
30 |
+
|
31 |
+
config_file = loads(f.read())
|
32 |
+
|
33 |
+
# copy constants over
|
34 |
+
DEBUG: bool = config_file.get("DEBUG", False)
|
35 |
+
PORT: int = config_file.get("PORT", 5000)
|
36 |
+
HOST: str = config_file.get("HOST", "0.0.0.0")
|
37 |
+
|
38 |
+
# check if user wants to use a global server too
|
39 |
+
if config_file["use_global"]:
|
40 |
+
|
41 |
+
# create a cloudflare tunnel
|
42 |
+
create_cloudflare_tunnel(PORT)
|
43 |
+
|
44 |
+
# ---------------------------------------- LOGGING CONFIG ---------------------------------------- #
|
45 |
+
|
46 |
+
# set logging level
|
47 |
+
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(message)s')
|
48 |
+
|
49 |
+
# ---------------------------------------- ROUTES ---------------------------------------- #
|
50 |
+
|
51 |
+
# chat generaiton route
|
52 |
+
@app.route("/chat/completions", methods=["POST"])
|
53 |
+
def chat():
|
54 |
+
|
55 |
+
# get request data
|
56 |
+
data = request.get_json()
|
57 |
+
|
58 |
+
# get messages
|
59 |
+
messages = message_translation(data["messages"]) if config_file["use_addons"] else data["messages"]
|
60 |
+
|
61 |
+
# get model
|
62 |
+
model = translate(data["model"]) if config_file["use_addons"] else data["model"]
|
63 |
+
|
64 |
+
# get max tokens
|
65 |
+
max_tokens = data.get("max_tokens", 150)
|
66 |
+
|
67 |
+
# top p and top k
|
68 |
+
top_p = data.get("top_p", 0.99)
|
69 |
+
top_k = data.get("top_k", 50)
|
70 |
+
|
71 |
+
# temperature, frequency penalty and presence penalty
|
72 |
+
temperature = data.get("temperature", 0.6)
|
73 |
+
|
74 |
+
# frequency penalty
|
75 |
+
frequency_penalty = data.get("frequency_penalty", 1)
|
76 |
+
|
77 |
+
# presence penalty
|
78 |
+
presence_penalty = data.get("presence_penalty", 1)
|
79 |
+
|
80 |
+
# streaming function. uses text/event-stream instead of application/json
|
81 |
+
def stream():
|
82 |
+
|
83 |
+
# generate chat
|
84 |
+
for chunk in api.chat(messages,
|
85 |
+
model,
|
86 |
+
stream=True,
|
87 |
+
max_tokens=max_tokens,
|
88 |
+
top_p=top_p,
|
89 |
+
temperature=temperature,
|
90 |
+
frequency_penalty=frequency_penalty,
|
91 |
+
presence_penalty=presence_penalty,
|
92 |
+
top_k=top_k
|
93 |
+
):
|
94 |
+
|
95 |
+
# yield chat
|
96 |
+
#print(chunk)
|
97 |
+
yield chunk + b'\n\n'
|
98 |
+
|
99 |
+
# in the end, return done
|
100 |
+
yield b'data: [DONE]'
|
101 |
+
|
102 |
+
# check if user wants to stream
|
103 |
+
if data.get("stream"):
|
104 |
+
|
105 |
+
# log
|
106 |
+
logging.info(f"Streaming requested for model {model}\n")
|
107 |
+
|
108 |
+
# return stream
|
109 |
+
return app.response_class(stream(), mimetype='text/event-stream')
|
110 |
+
|
111 |
+
# even if not, stream but collect all data to a full string
|
112 |
+
else:
|
113 |
+
|
114 |
+
# log
|
115 |
+
logging.info(f"Non-streaming requested for model {model}\n")
|
116 |
+
|
117 |
+
# pre-init
|
118 |
+
full: str = ""
|
119 |
+
|
120 |
+
# generate chat
|
121 |
+
for chunk in api.chat(messages,
|
122 |
+
model,
|
123 |
+
stream=True,
|
124 |
+
max_tokens=max_tokens,
|
125 |
+
top_p=top_p,
|
126 |
+
temperature=temperature,
|
127 |
+
frequency_penalty=frequency_penalty,
|
128 |
+
presence_penalty=presence_penalty,
|
129 |
+
top_k=top_k
|
130 |
+
):
|
131 |
+
|
132 |
+
try:
|
133 |
+
|
134 |
+
# append chunk
|
135 |
+
full += loads(chunk.decode("utf-8").removeprefix('data: '))["choices"][0]["delta"]["content"]
|
136 |
+
|
137 |
+
except: pass
|
138 |
+
|
139 |
+
# return full
|
140 |
+
return jsonify(non_streamed_format(model, full))
|
141 |
+
|
142 |
+
|
143 |
+
# route to get all models
|
144 |
+
@app.route("/models", methods=["GET"])
|
145 |
+
def get_models():
|
146 |
+
|
147 |
+
# return models
|
148 |
+
return jsonify(api.get_models())
|
149 |
+
|
150 |
+
# root route to check if api is online
|
151 |
+
@app.route("/", methods=["GET"])
|
152 |
+
def root():
|
153 |
+
|
154 |
+
# return root
|
155 |
+
return render_template("index.html")
|
156 |
+
|
157 |
+
# ---------------------------------------- ERROR HANDLING ---------------------------------------- #
|
158 |
+
@app.errorhandler(403)
|
159 |
+
def forbidden(error):
|
160 |
+
|
161 |
+
# return 403
|
162 |
+
return jsonify(
|
163 |
+
|
164 |
+
{"status": False},
|
165 |
+
{'error': [
|
166 |
+
|
167 |
+
{'message': 'Something went wrong, the API was blocked from sending a request to the DeepInfra API. Please try again later.'},
|
168 |
+
{'tpye': 'forbidden'},
|
169 |
+
{'error': f'{error}'}
|
170 |
+
]},
|
171 |
+
{'hint': 'please report issues on the github page'}
|
172 |
+
), 403
|
173 |
+
|
174 |
+
@app.errorhandler(500)
|
175 |
+
def internal_server_error(error):
|
176 |
+
|
177 |
+
# return 500
|
178 |
+
return jsonify(
|
179 |
+
|
180 |
+
{"status": False},
|
181 |
+
{'error': [
|
182 |
+
|
183 |
+
{'message': 'Something went wrong, the API was unable to complete your request. Please try again later.'},
|
184 |
+
{'tpye': 'internal server error'},
|
185 |
+
{'error': f'{error}'}
|
186 |
+
]},
|
187 |
+
{'hint': 'please report issues on the github page'}
|
188 |
+
), 500
|
189 |
+
|
190 |
+
# ---------------------------------------- START API ---------------------------------------- #
|
191 |
+
|
192 |
+
# start the api
|
193 |
+
if __name__ == "__main__":
|
194 |
+
|
195 |
+
app.run(debug=DEBUG, port=PORT, host=HOST)
|
196 |
+
|
197 |
+
# Path: app.py
|
requirements.txt
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
|
2 |
-
|
3 |
-
|
4 |
-
|
|
|
1 |
+
flask
|
2 |
+
flask_cors
|
3 |
+
fake_useragent
|
4 |
+
requests
|