Skip to content

Commit

Permalink
Merge pull request #68 from Integration-Automation/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
JE-Chen authored Dec 8, 2023
2 parents fad1b2b + 03c635e commit 97a170f
Show file tree
Hide file tree
Showing 32 changed files with 352 additions and 36 deletions.
7 changes: 6 additions & 1 deletion Dockerfiles/Flask/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,13 @@ COPY Dockerfiles/Flask/bing_cookies.json /ReEdgeGPT_Flask
# You need put your bing_cookies.txt to Dockerfiles/Flask dir
COPY Dockerfiles/Flask/bing_cookies.txt /ReEdgeGPT_Flask
# Flask init
COPY Dockerfiles/Flask/main_flask.py /ReEdgeGPT_Flask
COPY Dockerfiles/Flask/re_edge_gpt_blueprint.py /ReEdgeGPT_Flask
# Swagger
COPY Dockerfiles/Flask/swagger_config.py /ReEdgeGPT_Flask
# Flask
COPY Dockerfiles/Flask/docs /ReEdgeGPT_Flask/docs
# Flask
COPY Dockerfiles/Flask/main_flask.py /ReEdgeGPT_Flask
# Workdir
WORKDIR /ReEdgeGPT_Flask
# Install dependency
Expand Down
Empty file.
Empty file.
Empty file.
16 changes: 16 additions & 0 deletions Dockerfiles/Flask/docs/static/css/index.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
html {
box-sizing: border-box;
overflow: -moz-scrollbars-vertical;
overflow-y: scroll;
}

*,
*:before,
*:after {
box-sizing: inherit;
}

body {
margin: 0;
background: #fafafa;
}
3 changes: 3 additions & 0 deletions Dockerfiles/Flask/docs/static/css/swagger-ui.css

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions Dockerfiles/Flask/docs/static/css/swagger-ui.css.map

Large diffs are not rendered by default.

Empty file.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Empty file.
20 changes: 20 additions & 0 deletions Dockerfiles/Flask/docs/static/javascript/swagger-initializer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
window.onload = function() {
//<editor-fold desc="Changeable Configuration Block">

// the following lines will be replaced by docker/configurator, when it runs in a docker-container
window.ui = SwaggerUIBundle({
url: "https://petstore.swagger.io/v2/swagger.json",
dom_id: '#swagger-ui',
deepLinking: true,
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIStandalonePreset
],
plugins: [
SwaggerUIBundle.plugins.DownloadUrl
],
layout: "StandaloneLayout"
});

//</editor-fold>
};
3 changes: 3 additions & 0 deletions Dockerfiles/Flask/docs/static/javascript/swagger-ui-bundle.js

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions Dockerfiles/Flask/docs/static/javascript/swagger-ui.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions Dockerfiles/Flask/docs/static/javascript/swagger-ui.js.map

Large diffs are not rendered by default.

18 changes: 18 additions & 0 deletions Dockerfiles/Flask/docs/swagger.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from pathlib import Path

from flask import Blueprint, render_template

from config.flask_config import FLASK_PATH

swagger_blueprint = Blueprint(
"swagger_blueprint", __name__, url_prefix="/docs",
template_folder=str(
Path(str(Path.cwd()) + FLASK_PATH.get("swagger_template_folder"))),
static_folder=str(
Path(str(Path.cwd()) + FLASK_PATH.get("swagger_static_folder")))
)


@swagger_blueprint.route("/swagger", methods=["GET"])
async def swagger_doc():
return render_template('swagger_ui.html')
Empty file.
79 changes: 79 additions & 0 deletions Dockerfiles/Flask/docs/templates/oauth2-redirect.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<!doctype html>
<html lang="en-US">
<head>
<title>Swagger UI: OAuth2 Redirect</title>
</head>
<body>
<script>
'use strict';
function run () {
var oauth2 = window.opener.swaggerUIRedirectOauth2;
var sentState = oauth2.state;
var redirectUrl = oauth2.redirectUrl;
var isValid, qp, arr;

if (/code|token|error/.test(window.location.hash)) {
qp = window.location.hash.substring(1).replace('?', '&');
} else {
qp = location.search.substring(1);
}

arr = qp.split("&");
arr.forEach(function (v,i,_arr) { _arr[i] = '"' + v.replace('=', '":"') + '"';});
qp = qp ? JSON.parse('{' + arr.join() + '}',
function (key, value) {
return key === "" ? value : decodeURIComponent(value);
}
) : {};

isValid = qp.state === sentState;

if ((
oauth2.auth.schema.get("flow") === "accessCode" ||
oauth2.auth.schema.get("flow") === "authorizationCode" ||
oauth2.auth.schema.get("flow") === "authorization_code"
) && !oauth2.auth.code) {
if (!isValid) {
oauth2.errCb({
authId: oauth2.auth.name,
source: "auth",
level: "warning",
message: "Authorization may be unsafe, passed state was changed in server. The passed state wasn't returned from auth server."
});
}

if (qp.code) {
delete oauth2.state;
oauth2.auth.code = qp.code;
oauth2.callback({auth: oauth2.auth, redirectUrl: redirectUrl});
} else {
let oauthErrorMsg;
if (qp.error) {
oauthErrorMsg = "["+qp.error+"]: " +
(qp.error_description ? qp.error_description+ ". " : "no accessCode received from the server. ") +
(qp.error_uri ? "More info: "+qp.error_uri : "");
}

oauth2.errCb({
authId: oauth2.auth.name,
source: "auth",
level: "error",
message: oauthErrorMsg || "[Authorization failed]: no accessCode received from the server."
});
}
} else {
oauth2.callback({auth: oauth2.auth, token: qp, isValid: isValid, redirectUrl: redirectUrl});
}
window.close();
}

if (document.readyState !== 'loading') {
run();
} else {
document.addEventListener('DOMContentLoaded', function () {
run();
});
}
</script>
</body>
</html>
25 changes: 25 additions & 0 deletions Dockerfiles/Flask/docs/templates/swagger_ui.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<!-- HTML for static distribution bundle build -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Swagger UI</title>
<link rel="stylesheet" type="text/css" href="{{ url_for('swagger_blueprint.static', filename='css/swagger-ui.css') }}" />
<link rel="stylesheet" type="text/css" href="{{ url_for('swagger_blueprint.static', filename='css/index-ui.css') }}" />
<link rel="icon" type="image/png" href="{{ url_for('swagger_blueprint.static', filename='image/favicon-32x32.png') }}" sizes="32x32" />
<link rel="icon" type="image/png" href="{{ url_for('swagger_blueprint.static', filename='image/favicon-16x16.png') }}" sizes="16x16" />
</head>

<body>
<div id="swagger-ui" openapi-url="{{ url_for('swagger_blueprint.static', filename='openapi.yaml') }}"></div>
<script src="{{ url_for('swagger_blueprint.static', filename='javascript/swagger-ui-bundle.js') }}" charset="UTF-8"> </script>
<script src="{{ url_for('swagger_blueprint.static', filename='javascript/swagger-initializer.js') }}" charset="UTF-8"> </script>
<script src="{{ url_for('swagger_blueprint.static', filename='javascript/swagger-ui-standalone-preset.js') }}" charset="UTF-8"> </script>
<script>
window.onload = function() {
window.ui = SwaggerUIBundle({
url: document.getElementById("swagger-ui").getAttribute('openapi-url'),
dom_id: '#swagger-ui',
});};</script>
</body>
</html>
39 changes: 16 additions & 23 deletions Dockerfiles/Flask/main_flask.py
Original file line number Diff line number Diff line change
@@ -1,42 +1,35 @@
import os
from typing import List, Union

from flask import Flask, Blueprint
from flask import Flask
from flask_cors import CORS

from Dockerfiles.Flask.re_edge_gpt_blueprint import re_edge_gpt_blueprint_instance
from Dockerfiles.Flask.swagger_config import bind_swagger


def create_app(blueprint_list: Union[List[Blueprint], None] = None) -> Flask:
def create_app() -> Flask:
flask_app = Flask(__name__)
if blueprint_list is not None:
for blueprint in blueprint_list:
flask_app.register_blueprint(blueprint)
blueprints = [re_edge_gpt_blueprint_instance]
for blueprint in blueprints:
flask_app.register_blueprint(blueprint)

@flask_app.route("/", methods=["GET"])
async def index():
return "INDEX"

CORS(flask_app)
bind_swagger(flask_app)

return flask_app


if __name__ == "__main__":
# Init Flask with blueprint
blueprints = [re_edge_gpt_blueprint_instance]
app = create_app(blueprints)
app = create_app()
# Create new secret key using urandom 24
app.secret_key = os.urandom(24)


@app.route("/", methods=["GET"])
async def index():
return "INDEX"


app.run(port=8888, debug=True)
else:
# Init Flask with blueprint
blueprints = [re_edge_gpt_blueprint_instance]
app = create_app(blueprints)
app = create_app()
# Create new secret key using urandom 24
app.secret_key = os.urandom(24)


@app.route("/", methods=["GET"])
async def index():
return "INDEX"
93 changes: 93 additions & 0 deletions Dockerfiles/Flask/re_edge_gpt_blueprint.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,69 @@ async def setup_imagebot():

@re_edge_gpt_blueprint_instance.route("/chat", methods=["POST"])
async def chat():
"""
Send a prompt and chat mode to chat with Bing
---
post:
description: Chat with bing
tags:
- GPT
requestBody:
description: Data that chat needed
content:
application/json:
schema:
properties:
prompt:
type: string
example: How to boil the eggs
conversation_style:
type: string
enum: ["creative", "balanced", "precise"]
default: balanced
simplify_response:
type: boolean
attachment:
type: object
properties:
image_url:
type: string
default: null
filename:
type: string
default: null
base64_image:
type: string
default: null
responses:
200:
description: Success chat
content:
application/json:
schema:
properties:
text:
type: string
author:
type: string
sources:
type: string
sources_link:
type: string
suggestions:
type: array
example: [
"How do I know if the eggs are fresh?",
"What is a soft-boiled egg?",
"Can you give me some recipes with boiled eggs?"
]
messages_left:
type: integer
example: 29
max_messages:
type: integer
example: 30
"""
prompt = request.get_json()["prompt"]
conversation_style = request.get_json()["conversation_style"]
conversation_style = {
Expand Down Expand Up @@ -58,6 +121,36 @@ async def chat():

@re_edge_gpt_blueprint_instance.route("/image", methods=["POST"])
async def image():
"""
Send a prompt to generate image
---
post:
description: Generate image using DALL3-E
tags:
- GPT
requestBody:
description: prompt
content:
application/json:
schema:
properties:
prompt:
type: string
responses:
200:
description: Success generate image
content:
application/json:
schema:
properties:
images:
type: array
example: [
"image_url1",
"image_url2",
"image_url3"
]
"""
prompt = request.get_json()["prompt"]
if bot.get("chatbot") is None:
imagebot = await setup_imagebot()
Expand Down
47 changes: 47 additions & 0 deletions Dockerfiles/Flask/swagger_config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
from pathlib import Path

from apispec import APISpec
from apispec_webframeworks.flask import FlaskPlugin
from flask import Flask, Blueprint, render_template


def write_swagger_doc(openapi_yaml_content: str):
with open(str(Path(str(Path.cwd()) + str(Path("/docs/static" + "/openapi.yaml")))), "w+") as openapi_file:
openapi_file.write(openapi_yaml_content)


def bind_swagger(flask_app: Flask):
from Dockerfiles.Flask.re_edge_gpt_blueprint import chat
from Dockerfiles.Flask.re_edge_gpt_blueprint import image

flask_api_docs_view = [
chat, image
]

spec = APISpec(
title="ReEdgeGPT Example API Doc",
version="1.0.0",
openapi_version="3.0.2",
servers=[{"url": "http://localhost:8888"}],
plugins=[FlaskPlugin()]
)

swagger_blueprint = Blueprint(
"swagger_blueprint", __name__, url_prefix="/docs",
template_folder=str(
Path(str(Path.cwd()) + "/docs/templates")),
static_folder=str(
Path(str(Path.cwd()) + "/docs/static"))
)

@swagger_blueprint.route("/", methods=["GET"])
async def swagger_doc():
return render_template('swagger_ui.html')

flask_app.register_blueprint(swagger_blueprint)

with flask_app.app_context():
for doc_view in flask_api_docs_view:
spec.path(view=doc_view)

write_swagger_doc(spec.to_yaml())
Loading

0 comments on commit 97a170f

Please sign in to comment.