Skip to content

Commit

Permalink
feat: add api-based extension & external data tool & moderation backe…
Browse files Browse the repository at this point in the history
…nd (#1403)

Co-authored-by: takatost <[email protected]>
  • Loading branch information
GarfieldDai and takatost authored Nov 6, 2023
1 parent 7699621 commit db43ed6
Show file tree
Hide file tree
Showing 50 changed files with 1,622 additions and 271 deletions.
2 changes: 1 addition & 1 deletion .vscode/launch.json → api/.vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"request": "launch",
"module": "flask",
"env": {
"FLASK_APP": "api/app.py",
"FLASK_APP": "app.py",
"FLASK_DEBUG": "1",
"GEVENT_SUPPORT": "True"
},
Expand Down
3 changes: 2 additions & 1 deletion api/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

from core.model_providers.providers import hosted
from extensions import ext_celery, ext_sentry, ext_redis, ext_login, ext_migrate, \
ext_database, ext_storage, ext_mail, ext_stripe
ext_database, ext_storage, ext_mail, ext_stripe, ext_code_based_extension
from extensions.ext_database import db
from extensions.ext_login import login_manager

Expand Down Expand Up @@ -79,6 +79,7 @@ def create_app(test_config=None) -> Flask:
def initialize_extensions(app):
# Since the application instance is now created, pass it to each Flask
# extension instance to bind it to the Flask application instance (app)
ext_code_based_extension.init()
ext_database.init_app(app)
ext_migrate.init(app, db)
ext_redis.init_app(app)
Expand Down
4 changes: 4 additions & 0 deletions api/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
'CLEAN_DAY_SETTING': 30,
'UPLOAD_FILE_SIZE_LIMIT': 15,
'UPLOAD_FILE_BATCH_LIMIT': 5,
'OUTPUT_MODERATION_BUFFER_SIZE': 300
}


Expand Down Expand Up @@ -228,6 +229,9 @@ def __init__(self):
self.UPLOAD_FILE_SIZE_LIMIT = int(get_env('UPLOAD_FILE_SIZE_LIMIT'))
self.UPLOAD_FILE_BATCH_LIMIT = int(get_env('UPLOAD_FILE_BATCH_LIMIT'))

# moderation settings
self.OUTPUT_MODERATION_BUFFER_SIZE = int(get_env('OUTPUT_MODERATION_BUFFER_SIZE'))


class CloudEditionConfig(Config):

Expand Down
2 changes: 1 addition & 1 deletion api/controllers/console/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
api = ExternalApi(bp)

# Import other controllers
from . import setup, version, apikey, admin
from . import extension, setup, version, apikey, admin

# Import app controllers
from .app import advanced_prompt_template, app, site, completion, model_config, statistic, conversation, message, generator, audio
Expand Down
4 changes: 3 additions & 1 deletion api/controllers/console/explore/parameter.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class AppParameterApi(InstalledAppResource):
'retriever_resource': fields.Raw,
'more_like_this': fields.Raw,
'user_input_form': fields.Raw,
'sensitive_word_avoidance': fields.Raw
}

@marshal_with(parameters_fields)
Expand All @@ -42,7 +43,8 @@ def get(self, installed_app: InstalledApp):
'speech_to_text': app_model_config.speech_to_text_dict,
'retriever_resource': app_model_config.retriever_resource_dict,
'more_like_this': app_model_config.more_like_this_dict,
'user_input_form': app_model_config.user_input_form_list
'user_input_form': app_model_config.user_input_form_list,
'sensitive_word_avoidance': app_model_config.sensitive_word_avoidance_dict
}


Expand Down
114 changes: 114 additions & 0 deletions api/controllers/console/extension.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
from flask_restful import Resource, reqparse, marshal_with
from flask_login import current_user

from controllers.console import api
from controllers.console.setup import setup_required
from controllers.console.wraps import account_initialization_required
from libs.login import login_required
from models.api_based_extension import APIBasedExtension
from fields.api_based_extension_fields import api_based_extension_fields
from services.code_based_extension_service import CodeBasedExtensionService
from services.api_based_extension_service import APIBasedExtensionService


class CodeBasedExtensionAPI(Resource):

@setup_required
@login_required
@account_initialization_required
def get(self):
parser = reqparse.RequestParser()
parser.add_argument('module', type=str, required=True, location='args')
args = parser.parse_args()

return {
'module': args['module'],
'data': CodeBasedExtensionService.get_code_based_extension(args['module'])
}


class APIBasedExtensionAPI(Resource):

@setup_required
@login_required
@account_initialization_required
@marshal_with(api_based_extension_fields)
def get(self):
tenant_id = current_user.current_tenant_id
return APIBasedExtensionService.get_all_by_tenant_id(tenant_id)

@setup_required
@login_required
@account_initialization_required
@marshal_with(api_based_extension_fields)
def post(self):
parser = reqparse.RequestParser()
parser.add_argument('name', type=str, required=True, location='json')
parser.add_argument('api_endpoint', type=str, required=True, location='json')
parser.add_argument('api_key', type=str, required=True, location='json')
args = parser.parse_args()

extension_data = APIBasedExtension(
tenant_id=current_user.current_tenant_id,
name=args['name'],
api_endpoint=args['api_endpoint'],
api_key=args['api_key']
)

return APIBasedExtensionService.save(extension_data)


class APIBasedExtensionDetailAPI(Resource):

@setup_required
@login_required
@account_initialization_required
@marshal_with(api_based_extension_fields)
def get(self, id):
api_based_extension_id = str(id)
tenant_id = current_user.current_tenant_id

return APIBasedExtensionService.get_with_tenant_id(tenant_id, api_based_extension_id)

@setup_required
@login_required
@account_initialization_required
@marshal_with(api_based_extension_fields)
def post(self, id):
api_based_extension_id = str(id)
tenant_id = current_user.current_tenant_id

extension_data_from_db = APIBasedExtensionService.get_with_tenant_id(tenant_id, api_based_extension_id)

parser = reqparse.RequestParser()
parser.add_argument('name', type=str, required=True, location='json')
parser.add_argument('api_endpoint', type=str, required=True, location='json')
parser.add_argument('api_key', type=str, required=True, location='json')
args = parser.parse_args()

extension_data_from_db.name = args['name']
extension_data_from_db.api_endpoint = args['api_endpoint']

if args['api_key'] != '[__HIDDEN__]':
extension_data_from_db.api_key = args['api_key']

return APIBasedExtensionService.save(extension_data_from_db)

@setup_required
@login_required
@account_initialization_required
def delete(self, id):
api_based_extension_id = str(id)
tenant_id = current_user.current_tenant_id

extension_data_from_db = APIBasedExtensionService.get_with_tenant_id(tenant_id, api_based_extension_id)

APIBasedExtensionService.delete(extension_data_from_db)

return {'result': 'success'}


api.add_resource(CodeBasedExtensionAPI, '/code-based-extension')

api.add_resource(APIBasedExtensionAPI, '/api-based-extension')
api.add_resource(APIBasedExtensionDetailAPI, '/api-based-extension/<uuid:id>')
4 changes: 3 additions & 1 deletion api/controllers/service_api/app/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class AppParameterApi(AppApiResource):
'retriever_resource': fields.Raw,
'more_like_this': fields.Raw,
'user_input_form': fields.Raw,
'sensitive_word_avoidance': fields.Raw
}

@marshal_with(parameters_fields)
Expand All @@ -42,7 +43,8 @@ def get(self, app_model: App, end_user):
'speech_to_text': app_model_config.speech_to_text_dict,
'retriever_resource': app_model_config.retriever_resource_dict,
'more_like_this': app_model_config.more_like_this_dict,
'user_input_form': app_model_config.user_input_form_list
'user_input_form': app_model_config.user_input_form_list,
'sensitive_word_avoidance': app_model_config.sensitive_word_avoidance_dict
}


Expand Down
1 change: 0 additions & 1 deletion api/controllers/service_api/app/completion.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,4 +183,3 @@ def generate() -> Generator:
api.add_resource(CompletionStopApi, '/completion-messages/<string:task_id>/stop')
api.add_resource(ChatApi, '/chat-messages')
api.add_resource(ChatStopApi, '/chat-messages/<string:task_id>/stop')

4 changes: 3 additions & 1 deletion api/controllers/web/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class AppParameterApi(WebApiResource):
'retriever_resource': fields.Raw,
'more_like_this': fields.Raw,
'user_input_form': fields.Raw,
'sensitive_word_avoidance': fields.Raw
}

@marshal_with(parameters_fields)
Expand All @@ -41,7 +42,8 @@ def get(self, app_model: App, end_user):
'speech_to_text': app_model_config.speech_to_text_dict,
'retriever_resource': app_model_config.retriever_resource_dict,
'more_like_this': app_model_config.more_like_this_dict,
'user_input_form': app_model_config.user_input_form_list
'user_input_form': app_model_config.user_input_form_list,
'sensitive_word_avoidance': app_model_config.sensitive_word_avoidance_dict
}


Expand Down
2 changes: 1 addition & 1 deletion api/controllers/web/completion.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ def post(self, app_model, end_user, task_id):
return {'result': 'success'}, 200


def compact_response(response: Union[dict | Generator]) -> Response:
def compact_response(response: Union[dict, Generator]) -> Response:
if isinstance(response, dict):
return Response(response=json.dumps(response), status=200, mimetype='application/json')
else:
Expand Down
1 change: 1 addition & 0 deletions api/core/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import core.moderation.base
Loading

0 comments on commit db43ed6

Please sign in to comment.