Skip to content

Commit

Permalink
Merge pull request #80 from dlimeng/dev
Browse files Browse the repository at this point in the history
dev0.2.0 Support to select GPT3.5/GPT4
  • Loading branch information
dlimeng authored Jul 12, 2023
2 parents 1a96934 + 63a2234 commit 728ba48
Show file tree
Hide file tree
Showing 4 changed files with 137 additions and 9 deletions.
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
long_description=long_description,
long_description_content_type='text/markdown', # This field specifies the format of the `long_description`.
packages=find_packages(),
package_data={'soliduimodelui.webapp': ['static/*', 'static/assets/*']},
# package_data={'soliduimodelui.webapp': ['static/*', 'static/assets/*']},
install_requires=[
'ipykernel>=6,<7',
'snakemq>=1,<2',
Expand Down
5 changes: 5 additions & 0 deletions soliduimodelui/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
DB_HOST=43.138.5.82
DB_PORT=3306
DB_NAME=solidui
DB_USER=root
DB_PASS=SolidUI@123
102 changes: 95 additions & 7 deletions soliduimodelui/webapp/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,16 @@
from flask import Flask, request, jsonify, send_from_directory, Response, Blueprint
from dotenv import load_dotenv
import soliduimodelui.webapp.web_utils as web_utils
# from langchain.prompts import PromptTemplate
# from langchain.llms import OpenAI
# from langchain.chains import LLMChain
from soliduimodelui.kernelprogram.main import APP_PORT as KERNEL_APP_PORT

load_dotenv('.env')

db_host = os.environ.get('DB_HOST')
db_port = int(os.environ.get('DB_PORT'))
db_name = os.environ.get('DB_NAME')
db_user = os.environ.get('DB_USER')
db_pass = os.environ.get('DB_PASS')

APP_PORT = int(os.environ.get("WEB_PORT", 5110))

base_blueprint = Blueprint("baseurl", __name__, url_prefix="/solidui")
Expand All @@ -47,17 +51,101 @@
app = Flask(__name__)
CORS(app)

message_buffer = web_utils.LimitedLengthString()


# type 0:gpt-3.5-turbo 1:gpt-4
async def get_code_gpt(user_prompt, user_key="", model="gpt-3.5-turbo", base_url="https://api.openai.com"):
prompt = f"First, here is a history of what I asked you to do earlier. The actual prompt follows after ENDOFHISTORY. History:\n\n{message_buffer.get_string()}ENDOFHISTORY.\n\nWrite Python code that does the following: \n\n{user_prompt}\n\nNote, the code is going to be executed in a Jupyter Python kernel.\n\nLast instruction, and this is the most important, just return code. No other outputs, as your full response will directly be executed in the kernel. \n\nTeacher mode: if you want to give a download link, just print it as <a href='/solidui/download?file=INSERT_FILENAME_HERE'>Download file</a>. Replace INSERT_FILENAME_HERE with the actual filename. So just print that HTML to stdout. No actual downloading of files!"

data = {
"model": model,
"messages": [
{
"role": "user",
"content": prompt,
},
],
"temperature": 0.7,
}

final_openai_key = user_key

headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {final_openai_key}",
}

response = requests.post(
f"{base_url}/v1/chat/completions",
data=json.dumps(data),
headers=headers,
)

def extract_code(text):
# Match triple backtick blocks first
triple_match = re.search(r'```(?:\w+\n)?(.+?)```', text, re.DOTALL)
if triple_match:
return triple_match.group(1).strip()
else:
# If no triple backtick blocks, match single backtick blocks
single_match = re.search(r'`(.+?)`', text, re.DOTALL)
if single_match:
return single_match.group(1).strip()
# If no code blocks found, return original text
return text

if response.status_code != 200:
return "Error: " + response.text, 500

return extract_code(response.json()["choices"][0]["message"]["content"]), 200

async def get_code(user_prompt, user_key=None, model="gpt-3.5-turbo", type=0):
return 0

@base_blueprint.route('/api/<path:path>', methods=["GET", "POST"])
def proxy_kernel_manager(path):
return web_utils.response_format()
if request.method == "POST":
resp = requests.post(
f'http://localhost:{KERNEL_APP_PORT}/{path}', json=request.get_json())
else:
resp = requests.get(f'http://localhost:{KERNEL_APP_PORT}/{path}')

excluded_headers = ['content-encoding',
'content-length', 'transfer-encoding', 'connection']
headers = [(name, value) for (name, value) in resp.raw.headers.items()
if name.lower() not in excluded_headers]

return web_utils.response_format(code=resp.status_code, data=resp.content)


@base_blueprint.route('/generate', methods=['POST'])
def generate_code():
return web_utils.response_format()
user_prompt = request.json.get('prompt', '')
model = request.json.get('model', None)
result = web_utils.query_model(db_host, db_port, db_name, db_user, db_pass, model)
user_key = result['token']
base_url = result['baseurl']

loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)

code, status = loop.run_until_complete(
get_code_gpt(user_prompt, user_key, model, base_url))
loop.close()

# Append all messages to the message buffer for later use
message_buffer.append(user_prompt + "\n\n")

return web_utils.response_format(code=status, data={'code': code})


@base_blueprint.route('/download')
def download_file():
# Get query argument file
file = request.args.get('file')
# from `workspace/` send the file
# make sure to set required headers to make it download the file
return send_from_directory(os.path.join(os.getcwd(), 'workspace'), file, as_attachment=True)


app.register_blueprint(base_blueprint)

Expand Down
37 changes: 36 additions & 1 deletion soliduimodelui/webapp/web_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,46 @@
# See the License for the specific language governing permissions and
# limitations under the License.

import pymysql

class LimitedLengthString:
def __init__(self, maxlen=2000):
self.data = deque()
self.len = 0
self.maxlen = maxlen

def append(self, string):
self.data.append(string)
self.len += len(string)
while self.len > self.maxlen:
popped = self.data.popleft()
self.len -= len(popped)

def get_string(self):
result = ''.join(self.data)
return result[-self.maxlen:]

def response_format(code=0,msg="success",data={},success=True,failed=False):
return {
"code": code,
"msg": msg,
"data": data,
"success": success,
"failed": failed
}
}


def query_model(db_host='localhost',db_port=3306,db_user='root',db_pass='password',db_name='testdb',model=""):

conn = pymysql.connect(host=db_host,port=db_port,user=db_user,passwd=db_pass,db=db_name)

cursor = conn.cursor()

cursor.execute("SELECT * FROM solidui_model_type WHERE name = %s",model)

result = cursor.fetchone()

cursor.close()
conn.close()

return result

0 comments on commit 728ba48

Please sign in to comment.