Underground-Digital/Workflow-Engine
0
1import io2 3from flask import send_file4from flask_login import current_user5from flask_restful import Resource, reqparse6from werkzeug.exceptions import Forbidden7 8from configs import dify_config9from controllers.console import api10from controllers.console.wraps import account_initialization_required, setup_required11from core.model_runtime.utils.encoders import jsonable_encoder12from libs.helper import alphanumeric, uuid_value13from libs.login import login_required14from services.tools.api_tools_manage_service import ApiToolManageService15from services.tools.builtin_tools_manage_service import BuiltinToolManageService16from services.tools.tool_labels_service import ToolLabelsService17from services.tools.tools_manage_service import ToolCommonService18from services.tools.workflow_tools_manage_service import WorkflowToolManageService19 20 21class ToolProviderListApi(Resource):22 @setup_required23 @login_required24 @account_initialization_required25 def get(self):26 user_id = current_user.id27 tenant_id = current_user.current_tenant_id28 29 req = reqparse.RequestParser()30 req.add_argument(31 "type",32 type=str,33 choices=["builtin", "model", "api", "workflow"],34 required=False,35 nullable=True,36 location="args",37 )38 args = req.parse_args()39 40 return ToolCommonService.list_tool_providers(user_id, tenant_id, args.get("type", None))41 42 43class ToolBuiltinProviderListToolsApi(Resource):44 @setup_required45 @login_required46 @account_initialization_required47 def get(self, provider):48 user_id = current_user.id49 tenant_id = current_user.current_tenant_id50 51 return jsonable_encoder(52 BuiltinToolManageService.list_builtin_tool_provider_tools(53 user_id,54 tenant_id,55 provider,56 )57 )58 59 60class ToolBuiltinProviderDeleteApi(Resource):61 @setup_required62 @login_required63 @account_initialization_required64 def post(self, provider):65 if not current_user.is_admin_or_owner:66 raise Forbidden()67 68 user_id = current_user.id69 tenant_id = current_user.current_tenant_id70 71 return BuiltinToolManageService.delete_builtin_tool_provider(72 user_id,73 tenant_id,74 provider,75 )76 77 78class ToolBuiltinProviderUpdateApi(Resource):79 @setup_required80 @login_required81 @account_initialization_required82 def post(self, provider):83 if not current_user.is_admin_or_owner:84 raise Forbidden()85 86 user_id = current_user.id87 tenant_id = current_user.current_tenant_id88 89 parser = reqparse.RequestParser()90 parser.add_argument("credentials", type=dict, required=True, nullable=False, location="json")91 92 args = parser.parse_args()93 94 return BuiltinToolManageService.update_builtin_tool_provider(95 user_id,96 tenant_id,97 provider,98 args["credentials"],99 )100 101 102class ToolBuiltinProviderGetCredentialsApi(Resource):103 @setup_required104 @login_required105 @account_initialization_required106 def get(self, provider):107 user_id = current_user.id108 tenant_id = current_user.current_tenant_id109 110 return BuiltinToolManageService.get_builtin_tool_provider_credentials(111 user_id,112 tenant_id,113 provider,114 )115 116 117class ToolBuiltinProviderIconApi(Resource):118 @setup_required119 def get(self, provider):120 icon_bytes, mimetype = BuiltinToolManageService.get_builtin_tool_provider_icon(provider)121 icon_cache_max_age = dify_config.TOOL_ICON_CACHE_MAX_AGE122 return send_file(io.BytesIO(icon_bytes), mimetype=mimetype, max_age=icon_cache_max_age)123 124 125class ToolApiProviderAddApi(Resource):126 @setup_required127 @login_required128 @account_initialization_required129 def post(self):130 if not current_user.is_admin_or_owner:131 raise Forbidden()132 133 user_id = current_user.id134 tenant_id = current_user.current_tenant_id135 136 parser = reqparse.RequestParser()137 parser.add_argument("credentials", type=dict, required=True, nullable=False, location="json")138 parser.add_argument("schema_type", type=str, required=True, nullable=False, location="json")139 parser.add_argument("schema", type=str, required=True, nullable=False, location="json")140 parser.add_argument("provider", type=str, required=True, nullable=False, location="json")141 parser.add_argument("icon", type=dict, required=True, nullable=False, location="json")142 parser.add_argument("privacy_policy", type=str, required=False, nullable=True, location="json")143 parser.add_argument("labels", type=list[str], required=False, nullable=True, location="json", default=[])144 parser.add_argument("custom_disclaimer", type=str, required=False, nullable=True, location="json")145 146 args = parser.parse_args()147 148 return ApiToolManageService.create_api_tool_provider(149 user_id,150 tenant_id,151 args["provider"],152 args["icon"],153 args["credentials"],154 args["schema_type"],155 args["schema"],156 args.get("privacy_policy", ""),157 args.get("custom_disclaimer", ""),158 args.get("labels", []),159 )160 161 162class ToolApiProviderGetRemoteSchemaApi(Resource):163 @setup_required164 @login_required165 @account_initialization_required166 def get(self):167 parser = reqparse.RequestParser()168 169 parser.add_argument("url", type=str, required=True, nullable=False, location="args")170 171 args = parser.parse_args()172 173 return ApiToolManageService.get_api_tool_provider_remote_schema(174 current_user.id,175 current_user.current_tenant_id,176 args["url"],177 )178 179 180class ToolApiProviderListToolsApi(Resource):181 @setup_required182 @login_required183 @account_initialization_required184 def get(self):185 user_id = current_user.id186 tenant_id = current_user.current_tenant_id187 188 parser = reqparse.RequestParser()189 190 parser.add_argument("provider", type=str, required=True, nullable=False, location="args")191 192 args = parser.parse_args()193 194 return jsonable_encoder(195 ApiToolManageService.list_api_tool_provider_tools(196 user_id,197 tenant_id,198 args["provider"],199 )200 )201 202 203class ToolApiProviderUpdateApi(Resource):204 @setup_required205 @login_required206 @account_initialization_required207 def post(self):208 if not current_user.is_admin_or_owner:209 raise Forbidden()210 211 user_id = current_user.id212 tenant_id = current_user.current_tenant_id213 214 parser = reqparse.RequestParser()215 parser.add_argument("credentials", type=dict, required=True, nullable=False, location="json")216 parser.add_argument("schema_type", type=str, required=True, nullable=False, location="json")217 parser.add_argument("schema", type=str, required=True, nullable=False, location="json")218 parser.add_argument("provider", type=str, required=True, nullable=False, location="json")219 parser.add_argument("original_provider", type=str, required=True, nullable=False, location="json")220 parser.add_argument("icon", type=dict, required=True, nullable=False, location="json")221 parser.add_argument("privacy_policy", type=str, required=True, nullable=True, location="json")222 parser.add_argument("labels", type=list[str], required=False, nullable=True, location="json")223 parser.add_argument("custom_disclaimer", type=str, required=True, nullable=True, location="json")224 225 args = parser.parse_args()226 227 return ApiToolManageService.update_api_tool_provider(228 user_id,229 tenant_id,230 args["provider"],231 args["original_provider"],232 args["icon"],233 args["credentials"],234 args["schema_type"],235 args["schema"],236 args["privacy_policy"],237 args["custom_disclaimer"],238 args.get("labels", []),239 )240 241 242class ToolApiProviderDeleteApi(Resource):243 @setup_required244 @login_required245 @account_initialization_required246 def post(self):247 if not current_user.is_admin_or_owner:248 raise Forbidden()249 250 user_id = current_user.id251 tenant_id = current_user.current_tenant_id252 253 parser = reqparse.RequestParser()254 255 parser.add_argument("provider", type=str, required=True, nullable=False, location="json")256 257 args = parser.parse_args()258 259 return ApiToolManageService.delete_api_tool_provider(260 user_id,261 tenant_id,262 args["provider"],263 )264 265 266class ToolApiProviderGetApi(Resource):267 @setup_required268 @login_required269 @account_initialization_required270 def get(self):271 user_id = current_user.id272 tenant_id = current_user.current_tenant_id273 274 parser = reqparse.RequestParser()275 276 parser.add_argument("provider", type=str, required=True, nullable=False, location="args")277 278 args = parser.parse_args()279 280 return ApiToolManageService.get_api_tool_provider(281 user_id,282 tenant_id,283 args["provider"],284 )285 286 287class ToolBuiltinProviderCredentialsSchemaApi(Resource):288 @setup_required289 @login_required290 @account_initialization_required291 def get(self, provider):292 return BuiltinToolManageService.list_builtin_provider_credentials_schema(provider)293 294 295class ToolApiProviderSchemaApi(Resource):296 @setup_required297 @login_required298 @account_initialization_required299 def post(self):300 parser = reqparse.RequestParser()301 302 parser.add_argument("schema", type=str, required=True, nullable=False, location="json")303 304 args = parser.parse_args()305 306 return ApiToolManageService.parser_api_schema(307 schema=args["schema"],308 )309 310 311class ToolApiProviderPreviousTestApi(Resource):312 @setup_required313 @login_required314 @account_initialization_required315 def post(self):316 parser = reqparse.RequestParser()317 318 parser.add_argument("tool_name", type=str, required=True, nullable=False, location="json")319 parser.add_argument("provider_name", type=str, required=False, nullable=False, location="json")320 parser.add_argument("credentials", type=dict, required=True, nullable=False, location="json")321 parser.add_argument("parameters", type=dict, required=True, nullable=False, location="json")322 parser.add_argument("schema_type", type=str, required=True, nullable=False, location="json")323 parser.add_argument("schema", type=str, required=True, nullable=False, location="json")324 325 args = parser.parse_args()326 327 return ApiToolManageService.test_api_tool_preview(328 current_user.current_tenant_id,329 args["provider_name"] or "",330 args["tool_name"],331 args["credentials"],332 args["parameters"],333 args["schema_type"],334 args["schema"],335 )336 337 338class ToolWorkflowProviderCreateApi(Resource):339 @setup_required340 @login_required341 @account_initialization_required342 def post(self):343 if not current_user.is_admin_or_owner:344 raise Forbidden()345 346 user_id = current_user.id347 tenant_id = current_user.current_tenant_id348 349 reqparser = reqparse.RequestParser()350 reqparser.add_argument("workflow_app_id", type=uuid_value, required=True, nullable=False, location="json")351 reqparser.add_argument("name", type=alphanumeric, required=True, nullable=False, location="json")352 reqparser.add_argument("label", type=str, required=True, nullable=False, location="json")353 reqparser.add_argument("description", type=str, required=True, nullable=False, location="json")354 reqparser.add_argument("icon", type=dict, required=True, nullable=False, location="json")355 reqparser.add_argument("parameters", type=list[dict], required=True, nullable=False, location="json")356 reqparser.add_argument("privacy_policy", type=str, required=False, nullable=True, location="json", default="")357 reqparser.add_argument("labels", type=list[str], required=False, nullable=True, location="json")358 359 args = reqparser.parse_args()360 361 return WorkflowToolManageService.create_workflow_tool(362 user_id=user_id,363 tenant_id=tenant_id,364 workflow_app_id=args["workflow_app_id"],365 name=args["name"],366 label=args["label"],367 icon=args["icon"],368 description=args["description"],369 parameters=args["parameters"],370 privacy_policy=args["privacy_policy"],371 )372 373 374class ToolWorkflowProviderUpdateApi(Resource):375 @setup_required376 @login_required377 @account_initialization_required378 def post(self):379 if not current_user.is_admin_or_owner:380 raise Forbidden()381 382 user_id = current_user.id383 tenant_id = current_user.current_tenant_id384 385 reqparser = reqparse.RequestParser()386 reqparser.add_argument("workflow_tool_id", type=uuid_value, required=True, nullable=False, location="json")387 reqparser.add_argument("name", type=alphanumeric, required=True, nullable=False, location="json")388 reqparser.add_argument("label", type=str, required=True, nullable=False, location="json")389 reqparser.add_argument("description", type=str, required=True, nullable=False, location="json")390 reqparser.add_argument("icon", type=dict, required=True, nullable=False, location="json")391 reqparser.add_argument("parameters", type=list[dict], required=True, nullable=False, location="json")392 reqparser.add_argument("privacy_policy", type=str, required=False, nullable=True, location="json", default="")393 reqparser.add_argument("labels", type=list[str], required=False, nullable=True, location="json")394 395 args = reqparser.parse_args()396 397 if not args["workflow_tool_id"]:398 raise ValueError("incorrect workflow_tool_id")399 400 return WorkflowToolManageService.update_workflow_tool(401 user_id,402 tenant_id,403 args["workflow_tool_id"],404 args["name"],405 args["label"],406 args["icon"],407 args["description"],408 args["parameters"],409 args["privacy_policy"],410 args.get("labels", []),411 )412 413 414class ToolWorkflowProviderDeleteApi(Resource):415 @setup_required416 @login_required417 @account_initialization_required418 def post(self):419 if not current_user.is_admin_or_owner:420 raise Forbidden()421 422 user_id = current_user.id423 tenant_id = current_user.current_tenant_id424 425 reqparser = reqparse.RequestParser()426 reqparser.add_argument("workflow_tool_id", type=uuid_value, required=True, nullable=False, location="json")427 428 args = reqparser.parse_args()429 430 return WorkflowToolManageService.delete_workflow_tool(431 user_id,432 tenant_id,433 args["workflow_tool_id"],434 )435 436 437class ToolWorkflowProviderGetApi(Resource):438 @setup_required439 @login_required440 @account_initialization_required441 def get(self):442 user_id = current_user.id443 tenant_id = current_user.current_tenant_id444 445 parser = reqparse.RequestParser()446 parser.add_argument("workflow_tool_id", type=uuid_value, required=False, nullable=True, location="args")447 parser.add_argument("workflow_app_id", type=uuid_value, required=False, nullable=True, location="args")448 449 args = parser.parse_args()450 451 if args.get("workflow_tool_id"):452 tool = WorkflowToolManageService.get_workflow_tool_by_tool_id(453 user_id,454 tenant_id,455 args["workflow_tool_id"],456 )457 elif args.get("workflow_app_id"):458 tool = WorkflowToolManageService.get_workflow_tool_by_app_id(459 user_id,460 tenant_id,461 args["workflow_app_id"],462 )463 else:464 raise ValueError("incorrect workflow_tool_id or workflow_app_id")465 466 return jsonable_encoder(tool)467 468 469class ToolWorkflowProviderListToolApi(Resource):470 @setup_required471 @login_required472 @account_initialization_required473 def get(self):474 user_id = current_user.id475 tenant_id = current_user.current_tenant_id476 477 parser = reqparse.RequestParser()478 parser.add_argument("workflow_tool_id", type=uuid_value, required=True, nullable=False, location="args")479 480 args = parser.parse_args()481 482 return jsonable_encoder(483 WorkflowToolManageService.list_single_workflow_tools(484 user_id,485 tenant_id,486 args["workflow_tool_id"],487 )488 )489 490 491class ToolBuiltinListApi(Resource):492 @setup_required493 @login_required494 @account_initialization_required495 def get(self):496 user_id = current_user.id497 tenant_id = current_user.current_tenant_id498 499 return jsonable_encoder(500 [501 provider.to_dict()502 for provider in BuiltinToolManageService.list_builtin_tools(503 user_id,504 tenant_id,505 )506 ]507 )508 509 510class ToolApiListApi(Resource):511 @setup_required512 @login_required513 @account_initialization_required514 def get(self):515 user_id = current_user.id516 tenant_id = current_user.current_tenant_id517 518 return jsonable_encoder(519 [520 provider.to_dict()521 for provider in ApiToolManageService.list_api_tools(522 user_id,523 tenant_id,524 )525 ]526 )527 528 529class ToolWorkflowListApi(Resource):530 @setup_required531 @login_required532 @account_initialization_required533 def get(self):534 user_id = current_user.id535 tenant_id = current_user.current_tenant_id536 537 return jsonable_encoder(538 [539 provider.to_dict()540 for provider in WorkflowToolManageService.list_tenant_workflow_tools(541 user_id,542 tenant_id,543 )544 ]545 )546 547 548class ToolLabelsApi(Resource):549 @setup_required550 @login_required551 @account_initialization_required552 def get(self):553 return jsonable_encoder(ToolLabelsService.list_tool_labels())554 555 556# tool provider557api.add_resource(ToolProviderListApi, "/workspaces/current/tool-providers")558 559# builtin tool provider560api.add_resource(ToolBuiltinProviderListToolsApi, "/workspaces/current/tool-provider/builtin/<provider>/tools")561api.add_resource(ToolBuiltinProviderDeleteApi, "/workspaces/current/tool-provider/builtin/<provider>/delete")562api.add_resource(ToolBuiltinProviderUpdateApi, "/workspaces/current/tool-provider/builtin/<provider>/update")563api.add_resource(564 ToolBuiltinProviderGetCredentialsApi, "/workspaces/current/tool-provider/builtin/<provider>/credentials"565)566api.add_resource(567 ToolBuiltinProviderCredentialsSchemaApi, "/workspaces/current/tool-provider/builtin/<provider>/credentials_schema"568)569api.add_resource(ToolBuiltinProviderIconApi, "/workspaces/current/tool-provider/builtin/<provider>/icon")570 571# api tool provider572api.add_resource(ToolApiProviderAddApi, "/workspaces/current/tool-provider/api/add")573api.add_resource(ToolApiProviderGetRemoteSchemaApi, "/workspaces/current/tool-provider/api/remote")574api.add_resource(ToolApiProviderListToolsApi, "/workspaces/current/tool-provider/api/tools")575api.add_resource(ToolApiProviderUpdateApi, "/workspaces/current/tool-provider/api/update")576api.add_resource(ToolApiProviderDeleteApi, "/workspaces/current/tool-provider/api/delete")577api.add_resource(ToolApiProviderGetApi, "/workspaces/current/tool-provider/api/get")578api.add_resource(ToolApiProviderSchemaApi, "/workspaces/current/tool-provider/api/schema")579api.add_resource(ToolApiProviderPreviousTestApi, "/workspaces/current/tool-provider/api/test/pre")580 581# workflow tool provider582api.add_resource(ToolWorkflowProviderCreateApi, "/workspaces/current/tool-provider/workflow/create")583api.add_resource(ToolWorkflowProviderUpdateApi, "/workspaces/current/tool-provider/workflow/update")584api.add_resource(ToolWorkflowProviderDeleteApi, "/workspaces/current/tool-provider/workflow/delete")585api.add_resource(ToolWorkflowProviderGetApi, "/workspaces/current/tool-provider/workflow/get")586api.add_resource(ToolWorkflowProviderListToolApi, "/workspaces/current/tool-provider/workflow/tools")587 588api.add_resource(ToolBuiltinListApi, "/workspaces/current/tools/builtin")589api.add_resource(ToolApiListApi, "/workspaces/current/tools/api")590api.add_resource(ToolWorkflowListApi, "/workspaces/current/tools/workflow")591 592api.add_resource(ToolLabelsApi, "/workspaces/current/tool-labels")593 