mirror of
https://github.com/langgenius/dify.git
synced 2026-09-19 10:11:30 +08:00
refactor: replace manual model_validate with @model_validate in workspace plugin/tool controllers (#40238)
This commit is contained in:
@@ -24,6 +24,7 @@ from controllers.console.wraps import (
|
||||
RBACResourceScope,
|
||||
account_initialization_required,
|
||||
is_admin_or_owner_required,
|
||||
model_validate,
|
||||
rbac_permission_required,
|
||||
setup_required,
|
||||
with_current_tenant_id,
|
||||
@@ -592,10 +593,10 @@ class PluginListApi(Resource):
|
||||
@account_initialization_required
|
||||
@with_current_user_id
|
||||
@with_current_tenant_id
|
||||
def get(self, tenant_id: str, user_id: str):
|
||||
args = ParserList.model_validate(request.args.to_dict(flat=True))
|
||||
@model_validate(ParserList)
|
||||
def get(self, req_data: ParserList, tenant_id: str, user_id: str):
|
||||
try:
|
||||
plugins_with_total = PluginService.list_with_total(tenant_id, user_id, args.page, args.page_size)
|
||||
plugins_with_total = PluginService.list_with_total(tenant_id, user_id, req_data.page, req_data.page_size)
|
||||
except PluginDaemonClientSideError as e:
|
||||
return {"code": "plugin_error", "message": e.description}, 400
|
||||
|
||||
@@ -660,10 +661,10 @@ class PluginInstalledIdsApi(Resource):
|
||||
@login_required
|
||||
@account_initialization_required
|
||||
@with_current_tenant_id
|
||||
def get(self, tenant_id: str):
|
||||
args = PluginInstalledIdsQuery.model_validate(request.args.to_dict(flat=True))
|
||||
@model_validate(PluginInstalledIdsQuery)
|
||||
def get(self, req_data: PluginInstalledIdsQuery, tenant_id: str):
|
||||
try:
|
||||
plugin_ids = PluginService.list_installed_plugin_ids(tenant_id, args.category)
|
||||
plugin_ids = PluginService.list_installed_plugin_ids(tenant_id, req_data.category)
|
||||
except PluginDaemonClientSideError as e:
|
||||
return {"code": "plugin_error", "message": e.description}, 400
|
||||
|
||||
@@ -677,11 +678,11 @@ class PluginListLatestVersionsApi(Resource):
|
||||
@setup_required
|
||||
@login_required
|
||||
@account_initialization_required
|
||||
def post(self):
|
||||
args = ParserLatest.model_validate(console_ns.payload)
|
||||
@model_validate(ParserLatest)
|
||||
def post(self, req_data: ParserLatest):
|
||||
|
||||
try:
|
||||
versions = PluginService.list_latest_versions(args.plugin_ids)
|
||||
versions = PluginService.list_latest_versions(req_data.plugin_ids)
|
||||
except PluginDaemonClientSideError as e:
|
||||
return {"code": "plugin_error", "message": e.description}, 400
|
||||
|
||||
@@ -696,11 +697,11 @@ class PluginListInstallationsFromIdsApi(Resource):
|
||||
@login_required
|
||||
@account_initialization_required
|
||||
@with_current_tenant_id
|
||||
def post(self, tenant_id: str):
|
||||
args = ParserLatest.model_validate(console_ns.payload)
|
||||
@model_validate(ParserLatest)
|
||||
def post(self, req_data: ParserLatest, tenant_id: str):
|
||||
|
||||
try:
|
||||
plugins = PluginService.list_installations_from_ids(tenant_id, args.plugin_ids)
|
||||
plugins = PluginService.list_installations_from_ids(tenant_id, req_data.plugin_ids)
|
||||
except PluginDaemonClientSideError as e:
|
||||
return {"code": "plugin_error", "message": e.description}, 400
|
||||
|
||||
@@ -712,11 +713,11 @@ class PluginIconApi(Resource):
|
||||
@console_ns.doc(params=query_params_from_model(ParserIcon))
|
||||
@console_ns.response(200, "Success", console_ns.models[BinaryFileResponse.__name__])
|
||||
@setup_required
|
||||
def get(self):
|
||||
args = ParserIcon.model_validate(request.args.to_dict(flat=True))
|
||||
@model_validate(ParserIcon)
|
||||
def get(self, req_data: ParserIcon):
|
||||
|
||||
try:
|
||||
icon_bytes, mimetype = PluginService.get_asset(args.tenant_id, args.filename)
|
||||
icon_bytes, mimetype = PluginService.get_asset(req_data.tenant_id, req_data.filename)
|
||||
except PluginDaemonClientSideError as e:
|
||||
return {"code": "plugin_error", "message": e.description}, 400
|
||||
|
||||
@@ -732,11 +733,11 @@ class PluginAssetApi(Resource):
|
||||
@login_required
|
||||
@account_initialization_required
|
||||
@with_current_tenant_id
|
||||
def get(self, tenant_id: str):
|
||||
args = ParserAsset.model_validate(request.args.to_dict(flat=True))
|
||||
@model_validate(ParserAsset)
|
||||
def get(self, req_data: ParserAsset, tenant_id: str):
|
||||
|
||||
try:
|
||||
binary = PluginService.extract_asset(tenant_id, args.plugin_unique_identifier, args.file_name)
|
||||
binary = PluginService.extract_asset(tenant_id, req_data.plugin_unique_identifier, req_data.file_name)
|
||||
return send_file(io.BytesIO(binary), mimetype="application/octet-stream")
|
||||
except PluginDaemonClientSideError as e:
|
||||
return {"code": "plugin_error", "message": e.description}, 400
|
||||
@@ -773,11 +774,13 @@ class PluginUploadFromGithubApi(Resource):
|
||||
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.PLUGIN_INSTALL, resource_required=False)
|
||||
@plugin_permission_required(install_required=True)
|
||||
@with_current_tenant_id
|
||||
def post(self, tenant_id: str):
|
||||
args = ParserGithubUpload.model_validate(console_ns.payload)
|
||||
@model_validate(ParserGithubUpload)
|
||||
def post(self, req_data: ParserGithubUpload, tenant_id: str):
|
||||
|
||||
try:
|
||||
response = PluginService.upload_pkg_from_github(tenant_id, args.repo, args.version, args.package)
|
||||
response = PluginService.upload_pkg_from_github(
|
||||
tenant_id, req_data.repo, req_data.version, req_data.package
|
||||
)
|
||||
except PluginDaemonClientSideError as e:
|
||||
return {"code": "plugin_error", "message": e.description}, 400
|
||||
|
||||
@@ -814,11 +817,11 @@ class PluginInstallFromPkgApi(Resource):
|
||||
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.PLUGIN_INSTALL, resource_required=False)
|
||||
@plugin_permission_required(install_required=True)
|
||||
@with_current_tenant_id
|
||||
def post(self, tenant_id: str):
|
||||
args = ParserPluginIdentifiers.model_validate(console_ns.payload)
|
||||
@model_validate(ParserPluginIdentifiers)
|
||||
def post(self, req_data: ParserPluginIdentifiers, tenant_id: str):
|
||||
|
||||
try:
|
||||
response = PluginService.install_from_local_pkg(tenant_id, args.plugin_unique_identifiers)
|
||||
response = PluginService.install_from_local_pkg(tenant_id, req_data.plugin_unique_identifiers)
|
||||
except PluginDaemonClientSideError as e:
|
||||
return {"code": "plugin_error", "message": e.description}, 400
|
||||
|
||||
@@ -835,16 +838,16 @@ class PluginInstallFromGithubApi(Resource):
|
||||
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.PLUGIN_INSTALL, resource_required=False)
|
||||
@plugin_permission_required(install_required=True)
|
||||
@with_current_tenant_id
|
||||
def post(self, tenant_id: str):
|
||||
args = ParserGithubInstall.model_validate(console_ns.payload)
|
||||
@model_validate(ParserGithubInstall)
|
||||
def post(self, req_data: ParserGithubInstall, tenant_id: str):
|
||||
|
||||
try:
|
||||
response = PluginService.install_from_github(
|
||||
tenant_id,
|
||||
args.plugin_unique_identifier,
|
||||
args.repo,
|
||||
args.version,
|
||||
args.package,
|
||||
req_data.plugin_unique_identifier,
|
||||
req_data.repo,
|
||||
req_data.version,
|
||||
req_data.package,
|
||||
)
|
||||
except PluginDaemonClientSideError as e:
|
||||
return {"code": "plugin_error", "message": e.description}, 400
|
||||
@@ -862,11 +865,11 @@ class PluginInstallFromMarketplaceApi(Resource):
|
||||
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.PLUGIN_INSTALL, resource_required=False)
|
||||
@plugin_permission_required(install_required=True)
|
||||
@with_current_tenant_id
|
||||
def post(self, tenant_id: str):
|
||||
args = ParserPluginIdentifiers.model_validate(console_ns.payload)
|
||||
@model_validate(ParserPluginIdentifiers)
|
||||
def post(self, req_data: ParserPluginIdentifiers, tenant_id: str):
|
||||
|
||||
try:
|
||||
response = PluginService.install_from_marketplace_pkg(tenant_id, args.plugin_unique_identifiers)
|
||||
response = PluginService.install_from_marketplace_pkg(tenant_id, req_data.plugin_unique_identifiers)
|
||||
except PluginDaemonClientSideError as e:
|
||||
return {"code": "plugin_error", "message": e.description}, 400
|
||||
|
||||
@@ -883,15 +886,15 @@ class PluginFetchMarketplacePkgApi(Resource):
|
||||
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.PLUGIN_INSTALL, resource_required=False)
|
||||
@plugin_permission_required(install_required=True)
|
||||
@with_current_tenant_id
|
||||
def get(self, tenant_id: str):
|
||||
args = ParserPluginIdentifierQuery.model_validate(request.args.to_dict(flat=True))
|
||||
@model_validate(ParserPluginIdentifierQuery)
|
||||
def get(self, req_data: ParserPluginIdentifierQuery, tenant_id: str):
|
||||
|
||||
try:
|
||||
return jsonable_encoder(
|
||||
{
|
||||
"manifest": PluginService.fetch_marketplace_pkg(
|
||||
tenant_id,
|
||||
args.plugin_unique_identifier,
|
||||
req_data.plugin_unique_identifier,
|
||||
)
|
||||
}
|
||||
)
|
||||
@@ -909,12 +912,16 @@ class PluginFetchManifestApi(Resource):
|
||||
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.PLUGIN_INSTALL, resource_required=False)
|
||||
@plugin_permission_required(install_required=True)
|
||||
@with_current_tenant_id
|
||||
def get(self, tenant_id: str):
|
||||
args = ParserPluginIdentifierQuery.model_validate(request.args.to_dict(flat=True))
|
||||
@model_validate(ParserPluginIdentifierQuery)
|
||||
def get(self, req_data: ParserPluginIdentifierQuery, tenant_id: str):
|
||||
|
||||
try:
|
||||
return jsonable_encoder(
|
||||
{"manifest": PluginService.fetch_plugin_manifest(tenant_id, args.plugin_unique_identifier).model_dump()}
|
||||
{
|
||||
"manifest": PluginService.fetch_plugin_manifest(
|
||||
tenant_id, req_data.plugin_unique_identifier
|
||||
).model_dump()
|
||||
},
|
||||
)
|
||||
except PluginDaemonClientSideError as e:
|
||||
return {"code": "plugin_error", "message": e.description}, 400
|
||||
@@ -929,11 +936,13 @@ class PluginFetchInstallTasksApi(Resource):
|
||||
@account_initialization_required
|
||||
@plugin_permission_required(install_required=True)
|
||||
@with_current_tenant_id
|
||||
def get(self, tenant_id: str):
|
||||
args = ParserTasks.model_validate(request.args.to_dict(flat=True))
|
||||
@model_validate(ParserTasks)
|
||||
def get(self, req_data: ParserTasks, tenant_id: str):
|
||||
|
||||
try:
|
||||
return jsonable_encoder({"tasks": PluginService.fetch_install_tasks(tenant_id, args.page, args.page_size)})
|
||||
return jsonable_encoder(
|
||||
{"tasks": PluginService.fetch_install_tasks(tenant_id, req_data.page, req_data.page_size)}
|
||||
)
|
||||
except PluginDaemonClientSideError as e:
|
||||
return {"code": "plugin_error", "message": e.description}, 400
|
||||
|
||||
@@ -1008,13 +1017,13 @@ class PluginUpgradeFromMarketplaceApi(Resource):
|
||||
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.PLUGIN_MODEL_CONFIG, resource_required=False)
|
||||
@plugin_permission_required(install_required=True)
|
||||
@with_current_tenant_id
|
||||
def post(self, tenant_id: str):
|
||||
args = ParserMarketplaceUpgrade.model_validate(console_ns.payload)
|
||||
@model_validate(ParserMarketplaceUpgrade)
|
||||
def post(self, req_data: ParserMarketplaceUpgrade, tenant_id: str):
|
||||
|
||||
try:
|
||||
return jsonable_encoder(
|
||||
PluginService.upgrade_plugin_with_marketplace(
|
||||
tenant_id, args.original_plugin_unique_identifier, args.new_plugin_unique_identifier
|
||||
tenant_id, req_data.original_plugin_unique_identifier, req_data.new_plugin_unique_identifier
|
||||
)
|
||||
)
|
||||
except PluginDaemonClientSideError as e:
|
||||
@@ -1031,18 +1040,18 @@ class PluginUpgradeFromGithubApi(Resource):
|
||||
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.PLUGIN_MODEL_CONFIG, resource_required=False)
|
||||
@plugin_permission_required(install_required=True)
|
||||
@with_current_tenant_id
|
||||
def post(self, tenant_id: str):
|
||||
args = ParserGithubUpgrade.model_validate(console_ns.payload)
|
||||
@model_validate(ParserGithubUpgrade)
|
||||
def post(self, req_data: ParserGithubUpgrade, tenant_id: str):
|
||||
|
||||
try:
|
||||
return jsonable_encoder(
|
||||
PluginService.upgrade_plugin_with_github(
|
||||
tenant_id,
|
||||
args.original_plugin_unique_identifier,
|
||||
args.new_plugin_unique_identifier,
|
||||
args.repo,
|
||||
args.version,
|
||||
args.package,
|
||||
req_data.original_plugin_unique_identifier,
|
||||
req_data.new_plugin_unique_identifier,
|
||||
req_data.repo,
|
||||
req_data.version,
|
||||
req_data.package,
|
||||
)
|
||||
)
|
||||
except PluginDaemonClientSideError as e:
|
||||
@@ -1059,15 +1068,15 @@ class PluginUninstallApi(Resource):
|
||||
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.PLUGIN_DELETE, resource_required=False)
|
||||
@plugin_permission_required(install_required=True)
|
||||
@with_current_tenant_id
|
||||
def post(self, tenant_id: str):
|
||||
args = ParserUninstall.model_validate(console_ns.payload)
|
||||
@model_validate(ParserUninstall)
|
||||
def post(self, req_data: ParserUninstall, tenant_id: str):
|
||||
|
||||
try:
|
||||
return {
|
||||
"success": PluginService.uninstall(
|
||||
tenant_id,
|
||||
args.plugin_installation_id,
|
||||
preserve_credentials=args.preserve_credentials,
|
||||
req_data.plugin_installation_id,
|
||||
preserve_credentials=req_data.preserve_credentials,
|
||||
)
|
||||
}
|
||||
except PluginDaemonClientSideError as e:
|
||||
@@ -1083,14 +1092,13 @@ class PluginChangePermissionApi(Resource):
|
||||
@account_initialization_required
|
||||
@with_current_user
|
||||
@with_current_tenant_id
|
||||
def post(self, tenant_id: str, user: Account):
|
||||
@model_validate(ParserPermissionChange)
|
||||
def post(self, req_data: ParserPermissionChange, tenant_id: str, user: Account):
|
||||
if not user.is_admin_or_owner:
|
||||
raise Forbidden()
|
||||
|
||||
args = ParserPermissionChange.model_validate(console_ns.payload)
|
||||
|
||||
set_permission_result = PluginPermissionService.change_permission(
|
||||
tenant_id, args.install_permission, args.debug_permission, session=db.session()
|
||||
tenant_id, req_data.install_permission, req_data.debug_permission, session=db.session()
|
||||
)
|
||||
if not set_permission_result:
|
||||
return jsonable_encoder({"success": False, "message": "Failed to set permission"})
|
||||
@@ -1134,19 +1142,19 @@ class PluginFetchDynamicSelectOptionsApi(Resource):
|
||||
@account_initialization_required
|
||||
@with_current_user
|
||||
@with_current_tenant_id
|
||||
def get(self, tenant_id: str, current_user: Account):
|
||||
args = ParserDynamicOptions.model_validate(request.args.to_dict(flat=True))
|
||||
@model_validate(ParserDynamicOptions)
|
||||
def get(self, req_data: ParserDynamicOptions, tenant_id: str, current_user: Account):
|
||||
|
||||
try:
|
||||
options = PluginParameterService.get_dynamic_select_options(
|
||||
tenant_id=tenant_id,
|
||||
user_id=current_user.id,
|
||||
plugin_id=args.plugin_id,
|
||||
provider=args.provider,
|
||||
action=args.action,
|
||||
parameter=args.parameter,
|
||||
credential_id=args.credential_id,
|
||||
provider_type=args.provider_type,
|
||||
plugin_id=req_data.plugin_id,
|
||||
provider=req_data.provider,
|
||||
action=req_data.action,
|
||||
parameter=req_data.parameter,
|
||||
credential_id=req_data.credential_id,
|
||||
provider_type=req_data.provider_type,
|
||||
)
|
||||
except PluginDaemonClientSideError as e:
|
||||
return {"code": "plugin_error", "message": e.description}, 400
|
||||
@@ -1165,20 +1173,20 @@ class PluginFetchDynamicSelectOptionsWithCredentialsApi(Resource):
|
||||
@account_initialization_required
|
||||
@with_current_user
|
||||
@with_current_tenant_id
|
||||
def post(self, tenant_id: str, current_user: Account):
|
||||
@model_validate(ParserDynamicOptionsWithCredentials)
|
||||
def post(self, req_data: ParserDynamicOptionsWithCredentials, tenant_id: str, current_user: Account):
|
||||
"""Fetch dynamic options using credentials directly (for edit mode)."""
|
||||
args = ParserDynamicOptionsWithCredentials.model_validate(console_ns.payload)
|
||||
|
||||
try:
|
||||
options = PluginParameterService.get_dynamic_select_options_with_credentials(
|
||||
tenant_id=tenant_id,
|
||||
user_id=current_user.id,
|
||||
plugin_id=args.plugin_id,
|
||||
provider=args.provider,
|
||||
action=args.action,
|
||||
parameter=args.parameter,
|
||||
credential_id=args.credential_id,
|
||||
credentials=args.credentials,
|
||||
plugin_id=req_data.plugin_id,
|
||||
provider=req_data.provider,
|
||||
action=req_data.action,
|
||||
parameter=req_data.parameter,
|
||||
credential_id=req_data.credential_id,
|
||||
credentials=req_data.credentials,
|
||||
)
|
||||
except PluginDaemonClientSideError as e:
|
||||
return {"code": "plugin_error", "message": e.description}, 400
|
||||
@@ -1196,13 +1204,12 @@ class PluginChangeAutoUpgradeApi(Resource):
|
||||
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.PLUGIN_PREFERENCES, resource_required=False)
|
||||
@with_current_user
|
||||
@with_current_tenant_id
|
||||
def post(self, tenant_id: str, user: Account):
|
||||
@model_validate(ParserAutoUpgradeChange)
|
||||
def post(self, req_data: ParserAutoUpgradeChange, tenant_id: str, user: Account):
|
||||
if not dify_config.RBAC_ENABLED and not user.is_admin_or_owner:
|
||||
raise Forbidden()
|
||||
|
||||
args = ParserAutoUpgradeChange.model_validate(console_ns.payload)
|
||||
|
||||
auto_upgrade = args.auto_upgrade
|
||||
auto_upgrade = req_data.auto_upgrade
|
||||
set_auto_upgrade_strategy_result = PluginAutoUpgradeService.change_strategy(
|
||||
tenant_id,
|
||||
auto_upgrade.strategy_setting,
|
||||
@@ -1210,7 +1217,7 @@ class PluginChangeAutoUpgradeApi(Resource):
|
||||
auto_upgrade.upgrade_mode,
|
||||
auto_upgrade.exclude_plugins,
|
||||
auto_upgrade.include_plugins,
|
||||
category=args.category,
|
||||
category=req_data.category,
|
||||
session=db.session(),
|
||||
)
|
||||
if not set_auto_upgrade_strategy_result:
|
||||
@@ -1227,16 +1234,16 @@ class PluginFetchAutoUpgradeApi(Resource):
|
||||
@login_required
|
||||
@account_initialization_required
|
||||
@with_current_tenant_id
|
||||
def get(self, tenant_id: str):
|
||||
args = ParserAutoUpgradeFetch.model_validate(request.args.to_dict(flat=True))
|
||||
auto_upgrade = PluginAutoUpgradeService.get_strategy(tenant_id, args.category, session=db.session())
|
||||
@model_validate(ParserAutoUpgradeFetch)
|
||||
def get(self, req_data: ParserAutoUpgradeFetch, tenant_id: str):
|
||||
auto_upgrade = PluginAutoUpgradeService.get_strategy(tenant_id, req_data.category, session=db.session())
|
||||
auto_upgrade_dict = (
|
||||
_auto_upgrade_settings_to_dict(auto_upgrade) if auto_upgrade else _missing_auto_upgrade_settings(tenant_id)
|
||||
)
|
||||
|
||||
return jsonable_encoder(
|
||||
{
|
||||
"category": args.category,
|
||||
"category": req_data.category,
|
||||
"auto_upgrade": auto_upgrade_dict,
|
||||
}
|
||||
)
|
||||
@@ -1251,14 +1258,14 @@ class PluginAutoUpgradeExcludePluginApi(Resource):
|
||||
@account_initialization_required
|
||||
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.PLUGIN_PREFERENCES, resource_required=False)
|
||||
@with_current_tenant_id
|
||||
def post(self, tenant_id: str):
|
||||
@model_validate(ParserExcludePlugin)
|
||||
def post(self, req_data: ParserExcludePlugin, tenant_id: str):
|
||||
# exclude one single plugin
|
||||
args = ParserExcludePlugin.model_validate(console_ns.payload)
|
||||
|
||||
return jsonable_encoder(
|
||||
{
|
||||
"success": PluginAutoUpgradeService.exclude_plugin(
|
||||
tenant_id, args.plugin_id, args.category, session=db.session()
|
||||
tenant_id, req_data.plugin_id, req_data.category, session=db.session()
|
||||
)
|
||||
}
|
||||
)
|
||||
@@ -1272,8 +1279,12 @@ class PluginReadmeApi(Resource):
|
||||
@login_required
|
||||
@account_initialization_required
|
||||
@with_current_tenant_id
|
||||
def get(self, tenant_id: str):
|
||||
args = ParserReadme.model_validate(request.args.to_dict(flat=True))
|
||||
@model_validate(ParserReadme)
|
||||
def get(self, req_data: ParserReadme, tenant_id: str):
|
||||
return jsonable_encoder(
|
||||
{"readme": PluginService.fetch_plugin_readme(tenant_id, args.plugin_unique_identifier, args.language)}
|
||||
{
|
||||
"readme": PluginService.fetch_plugin_readme(
|
||||
tenant_id, req_data.plugin_unique_identifier, req_data.language
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
@@ -33,6 +33,7 @@ from controllers.console.wraps import (
|
||||
account_initialization_required,
|
||||
enterprise_license_required,
|
||||
is_admin_or_owner_required,
|
||||
model_validate,
|
||||
rbac_permission_required,
|
||||
setup_required,
|
||||
with_current_tenant_id,
|
||||
@@ -555,16 +556,15 @@ class ToolBuiltinProviderDeleteApi(Resource):
|
||||
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.CREDENTIAL_MANAGE, resource_required=False)
|
||||
@account_initialization_required
|
||||
@with_current_tenant_id
|
||||
def post(self, tenant_id: str, provider: str):
|
||||
|
||||
payload = BuiltinToolCredentialDeletePayload.model_validate(console_ns.payload or {})
|
||||
@model_validate(BuiltinToolCredentialDeletePayload)
|
||||
def post(self, req_data: BuiltinToolCredentialDeletePayload, tenant_id: str, provider: str):
|
||||
|
||||
return dump_response(
|
||||
SimpleResultResponse,
|
||||
BuiltinToolManageService.delete_builtin_tool_provider(
|
||||
tenant_id,
|
||||
provider,
|
||||
payload.credential_id,
|
||||
req_data.credential_id,
|
||||
),
|
||||
)
|
||||
|
||||
@@ -582,19 +582,18 @@ class ToolBuiltinProviderAddApi(Resource):
|
||||
@account_initialization_required
|
||||
@with_current_user
|
||||
@with_current_tenant_id
|
||||
def post(self, tenant_id: str, user: Account, provider: str):
|
||||
payload = BuiltinToolAddPayload.model_validate(console_ns.payload or {})
|
||||
|
||||
@model_validate(BuiltinToolAddPayload)
|
||||
def post(self, req_data: BuiltinToolAddPayload, tenant_id: str, user: Account, provider: str):
|
||||
return dump_response(
|
||||
SimpleResultResponse,
|
||||
BuiltinToolManageService.add_builtin_tool_provider(
|
||||
user_id=user.id,
|
||||
tenant_id=tenant_id,
|
||||
provider=provider,
|
||||
credentials=payload.credentials,
|
||||
name=payload.name,
|
||||
api_type=CredentialType.of(payload.type),
|
||||
visibility=payload.visibility,
|
||||
credentials=req_data.credentials,
|
||||
name=req_data.name,
|
||||
api_type=CredentialType.of(req_data.type),
|
||||
visibility=req_data.visibility,
|
||||
),
|
||||
)
|
||||
|
||||
@@ -614,16 +613,15 @@ class ToolBuiltinProviderUpdateApi(Resource):
|
||||
@account_initialization_required
|
||||
@with_current_user
|
||||
@with_current_tenant_id
|
||||
def post(self, tenant_id: str, user: Account, provider: str):
|
||||
payload = BuiltinToolUpdatePayload.model_validate(console_ns.payload or {})
|
||||
|
||||
@model_validate(BuiltinToolUpdatePayload)
|
||||
def post(self, req_data: BuiltinToolUpdatePayload, tenant_id: str, user: Account, provider: str):
|
||||
result = BuiltinToolManageService.update_builtin_tool_provider(
|
||||
user_id=user.id,
|
||||
tenant_id=tenant_id,
|
||||
provider=provider,
|
||||
credential_id=payload.credential_id,
|
||||
credentials=payload.credentials,
|
||||
name=payload.name or "",
|
||||
credential_id=req_data.credential_id,
|
||||
credentials=req_data.credentials,
|
||||
name=req_data.name or "",
|
||||
)
|
||||
return dump_response(SimpleResultResponse, result)
|
||||
|
||||
@@ -683,22 +681,21 @@ class ToolApiProviderAddApi(Resource):
|
||||
@account_initialization_required
|
||||
@with_current_user
|
||||
@with_current_tenant_id
|
||||
def post(self, tenant_id: str, user: Account):
|
||||
payload = ApiToolProviderAddPayload.model_validate(console_ns.payload or {})
|
||||
|
||||
@model_validate(ApiToolProviderAddPayload)
|
||||
def post(self, req_data: ApiToolProviderAddPayload, tenant_id: str, user: Account):
|
||||
return dump_response(
|
||||
SimpleResultResponse,
|
||||
ApiToolManageService.create_api_tool_provider(
|
||||
user.id,
|
||||
tenant_id,
|
||||
payload.provider,
|
||||
payload.icon.model_dump(mode="json"),
|
||||
payload.credentials,
|
||||
payload.schema_type,
|
||||
payload.schema_,
|
||||
payload.privacy_policy or "",
|
||||
payload.custom_disclaimer or "",
|
||||
payload.labels or [],
|
||||
req_data.provider,
|
||||
req_data.icon.model_dump(mode="json"),
|
||||
req_data.credentials,
|
||||
req_data.schema_type,
|
||||
req_data.schema_,
|
||||
req_data.privacy_policy or "",
|
||||
req_data.custom_disclaimer or "",
|
||||
req_data.labels or [],
|
||||
),
|
||||
)
|
||||
|
||||
@@ -764,23 +761,22 @@ class ToolApiProviderUpdateApi(Resource):
|
||||
@account_initialization_required
|
||||
@with_current_user
|
||||
@with_current_tenant_id
|
||||
def post(self, tenant_id: str, user: Account):
|
||||
payload = ApiToolProviderUpdatePayload.model_validate(console_ns.payload or {})
|
||||
|
||||
@model_validate(ApiToolProviderUpdatePayload)
|
||||
def post(self, req_data: ApiToolProviderUpdatePayload, tenant_id: str, user: Account):
|
||||
return dump_response(
|
||||
SimpleResultResponse,
|
||||
ApiToolManageService.update_api_tool_provider(
|
||||
user.id,
|
||||
tenant_id,
|
||||
payload.provider,
|
||||
payload.original_provider,
|
||||
payload.icon.model_dump(mode="json"),
|
||||
payload.credentials,
|
||||
payload.schema_type,
|
||||
payload.schema_,
|
||||
payload.privacy_policy,
|
||||
payload.custom_disclaimer,
|
||||
payload.labels or [],
|
||||
req_data.provider,
|
||||
req_data.original_provider,
|
||||
req_data.icon.model_dump(mode="json"),
|
||||
req_data.credentials,
|
||||
req_data.schema_type,
|
||||
req_data.schema_,
|
||||
req_data.privacy_policy,
|
||||
req_data.custom_disclaimer,
|
||||
req_data.labels or [],
|
||||
),
|
||||
)
|
||||
|
||||
@@ -796,15 +792,14 @@ class ToolApiProviderDeleteApi(Resource):
|
||||
@account_initialization_required
|
||||
@with_current_user
|
||||
@with_current_tenant_id
|
||||
def post(self, tenant_id: str, user: Account):
|
||||
payload = ApiToolProviderDeletePayload.model_validate(console_ns.payload or {})
|
||||
|
||||
@model_validate(ApiToolProviderDeletePayload)
|
||||
def post(self, req_data: ApiToolProviderDeletePayload, tenant_id: str, user: Account):
|
||||
return dump_response(
|
||||
SimpleResultResponse,
|
||||
ApiToolManageService.delete_api_tool_provider(
|
||||
user.id,
|
||||
tenant_id,
|
||||
payload.provider,
|
||||
req_data.provider,
|
||||
),
|
||||
)
|
||||
|
||||
@@ -861,10 +856,9 @@ class ToolApiProviderSchemaApi(Resource):
|
||||
@setup_required
|
||||
@login_required
|
||||
@account_initialization_required
|
||||
def post(self):
|
||||
payload = ApiToolSchemaPayload.model_validate(console_ns.payload or {})
|
||||
|
||||
return dump_response(ApiSchemaParseResponse, ApiToolManageService.parser_api_schema(schema=payload.schema_))
|
||||
@model_validate(ApiToolSchemaPayload)
|
||||
def post(self, req_data: ApiToolSchemaPayload):
|
||||
return dump_response(ApiSchemaParseResponse, ApiToolManageService.parser_api_schema(schema=req_data.schema_))
|
||||
|
||||
|
||||
@console_ns.route("/workspaces/current/tool-provider/api/test/pre")
|
||||
@@ -879,18 +873,18 @@ class ToolApiProviderPreviousTestApi(Resource):
|
||||
@login_required
|
||||
@account_initialization_required
|
||||
@with_current_tenant_id
|
||||
def post(self, current_tenant_id: str):
|
||||
payload = ApiToolTestPayload.model_validate(console_ns.payload or {})
|
||||
@model_validate(ApiToolTestPayload)
|
||||
def post(self, req_data: ApiToolTestPayload, current_tenant_id: str):
|
||||
return dump_response(
|
||||
ApiToolPreviewResponse,
|
||||
ApiToolManageService.test_api_tool_preview(
|
||||
current_tenant_id,
|
||||
payload.provider_name or "",
|
||||
payload.tool_name,
|
||||
payload.credentials,
|
||||
payload.parameters,
|
||||
payload.schema_type,
|
||||
payload.schema_,
|
||||
req_data.provider_name or "",
|
||||
req_data.tool_name,
|
||||
req_data.credentials,
|
||||
req_data.parameters,
|
||||
req_data.schema_type,
|
||||
req_data.schema_,
|
||||
),
|
||||
)
|
||||
|
||||
@@ -906,22 +900,21 @@ class ToolWorkflowProviderCreateApi(Resource):
|
||||
@account_initialization_required
|
||||
@with_current_user
|
||||
@with_current_tenant_id
|
||||
def post(self, tenant_id: str, user: Account):
|
||||
payload = WorkflowToolCreatePayload.model_validate(console_ns.payload or {})
|
||||
|
||||
@model_validate(WorkflowToolCreatePayload)
|
||||
def post(self, req_data: WorkflowToolCreatePayload, tenant_id: str, user: Account):
|
||||
return dump_response(
|
||||
SimpleResultResponse,
|
||||
WorkflowToolManageService.create_workflow_tool(
|
||||
user_id=user.id,
|
||||
tenant_id=tenant_id,
|
||||
workflow_app_id=payload.workflow_app_id,
|
||||
name=payload.name,
|
||||
label=payload.label,
|
||||
icon=payload.icon.model_dump(mode="json"),
|
||||
description=payload.description,
|
||||
parameters=payload.parameters,
|
||||
privacy_policy=payload.privacy_policy or "",
|
||||
labels=payload.labels or [],
|
||||
workflow_app_id=req_data.workflow_app_id,
|
||||
name=req_data.name,
|
||||
label=req_data.label,
|
||||
icon=req_data.icon.model_dump(mode="json"),
|
||||
description=req_data.description,
|
||||
parameters=req_data.parameters,
|
||||
privacy_policy=req_data.privacy_policy or "",
|
||||
labels=req_data.labels or [],
|
||||
),
|
||||
)
|
||||
|
||||
@@ -937,22 +930,21 @@ class ToolWorkflowProviderUpdateApi(Resource):
|
||||
@account_initialization_required
|
||||
@with_current_user
|
||||
@with_current_tenant_id
|
||||
def post(self, tenant_id: str, user: Account):
|
||||
payload = WorkflowToolUpdatePayload.model_validate(console_ns.payload or {})
|
||||
|
||||
@model_validate(WorkflowToolUpdatePayload)
|
||||
def post(self, req_data: WorkflowToolUpdatePayload, tenant_id: str, user: Account):
|
||||
return dump_response(
|
||||
SimpleResultResponse,
|
||||
WorkflowToolManageService.update_workflow_tool(
|
||||
user.id,
|
||||
tenant_id,
|
||||
payload.workflow_tool_id,
|
||||
payload.name,
|
||||
payload.label,
|
||||
payload.icon.model_dump(mode="json"),
|
||||
payload.description,
|
||||
payload.parameters,
|
||||
payload.privacy_policy or "",
|
||||
payload.labels or [],
|
||||
req_data.workflow_tool_id,
|
||||
req_data.name,
|
||||
req_data.label,
|
||||
req_data.icon.model_dump(mode="json"),
|
||||
req_data.description,
|
||||
req_data.parameters,
|
||||
req_data.privacy_policy or "",
|
||||
req_data.labels or [],
|
||||
),
|
||||
)
|
||||
|
||||
@@ -968,15 +960,14 @@ class ToolWorkflowProviderDeleteApi(Resource):
|
||||
@account_initialization_required
|
||||
@with_current_user
|
||||
@with_current_tenant_id
|
||||
def post(self, tenant_id: str, user: Account):
|
||||
payload = WorkflowToolDeletePayload.model_validate(console_ns.payload or {})
|
||||
|
||||
@model_validate(WorkflowToolDeletePayload)
|
||||
def post(self, req_data: WorkflowToolDeletePayload, tenant_id: str, user: Account):
|
||||
return dump_response(
|
||||
SimpleResultResponse,
|
||||
WorkflowToolManageService.delete_workflow_tool(
|
||||
user.id,
|
||||
tenant_id,
|
||||
payload.workflow_tool_id,
|
||||
req_data.workflow_tool_id,
|
||||
),
|
||||
)
|
||||
|
||||
@@ -1224,12 +1215,12 @@ class ToolBuiltinProviderSetDefaultApi(Resource):
|
||||
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.CREDENTIAL_USE, resource_required=False)
|
||||
@account_initialization_required
|
||||
@with_current_tenant_id
|
||||
def post(self, current_tenant_id: str, provider: str):
|
||||
payload = BuiltinProviderDefaultCredentialPayload.model_validate(console_ns.payload or {})
|
||||
@model_validate(BuiltinProviderDefaultCredentialPayload)
|
||||
def post(self, req_data: BuiltinProviderDefaultCredentialPayload, current_tenant_id: str, provider: str):
|
||||
return dump_response(
|
||||
SimpleResultResponse,
|
||||
BuiltinToolManageService.set_default_provider(
|
||||
tenant_id=current_tenant_id, provider=provider, id=payload.id
|
||||
tenant_id=current_tenant_id, provider=provider, id=req_data.id
|
||||
),
|
||||
)
|
||||
|
||||
@@ -1246,17 +1237,16 @@ class ToolOAuthCustomClient(Resource):
|
||||
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.CREDENTIAL_MANAGE, resource_required=False)
|
||||
@account_initialization_required
|
||||
@with_current_tenant_id
|
||||
def post(self, tenant_id: str, provider: str):
|
||||
payload = ToolOAuthCustomClientPayload.model_validate(console_ns.payload or {})
|
||||
|
||||
@model_validate(ToolOAuthCustomClientPayload)
|
||||
def post(self, req_data: ToolOAuthCustomClientPayload, tenant_id: str, provider: str):
|
||||
return dump_response(
|
||||
SimpleResultResponse,
|
||||
BuiltinToolManageService.save_custom_oauth_client_params(
|
||||
tenant_id=tenant_id,
|
||||
provider=provider,
|
||||
client_params=payload.client_params or {},
|
||||
enable_oauth_custom_client=payload.enable_oauth_custom_client
|
||||
if payload.enable_oauth_custom_client is not None
|
||||
client_params=req_data.client_params or {},
|
||||
enable_oauth_custom_client=req_data.enable_oauth_custom_client
|
||||
if req_data.enable_oauth_custom_client is not None
|
||||
else True,
|
||||
),
|
||||
)
|
||||
@@ -1349,11 +1339,10 @@ class ToolProviderMCPApi(Resource):
|
||||
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.MCP_MANAGE, resource_required=False)
|
||||
@with_current_user
|
||||
@with_current_tenant_id
|
||||
def post(self, tenant_id: str, user: Account):
|
||||
payload = MCPProviderCreatePayload.model_validate(console_ns.payload or {})
|
||||
|
||||
configuration = payload.configuration or MCPConfiguration()
|
||||
authentication = payload.authentication
|
||||
@model_validate(MCPProviderCreatePayload)
|
||||
def post(self, req_data: MCPProviderCreatePayload, tenant_id: str, user: Account):
|
||||
configuration = req_data.configuration or MCPConfiguration()
|
||||
authentication = req_data.authentication
|
||||
|
||||
# 1) Create provider in a short transaction (no network I/O inside)
|
||||
with session_factory.create_session() as session, session.begin():
|
||||
@@ -1361,24 +1350,24 @@ class ToolProviderMCPApi(Resource):
|
||||
result = service.create_provider(
|
||||
tenant_id=tenant_id,
|
||||
user_id=user.id,
|
||||
server_url=payload.server_url,
|
||||
name=payload.name,
|
||||
icon=payload.icon,
|
||||
icon_type=payload.icon_type,
|
||||
icon_background=payload.icon_background,
|
||||
server_identifier=payload.server_identifier,
|
||||
headers=payload.headers or {},
|
||||
server_url=req_data.server_url,
|
||||
name=req_data.name,
|
||||
icon=req_data.icon,
|
||||
icon_type=req_data.icon_type,
|
||||
icon_background=req_data.icon_background,
|
||||
server_identifier=req_data.server_identifier,
|
||||
headers=req_data.headers or {},
|
||||
configuration=configuration,
|
||||
authentication=authentication,
|
||||
identity_mode=_resolve_identity_mode(payload.identity_mode, current=IdentityMode.OFF),
|
||||
identity_mode=_resolve_identity_mode(req_data.identity_mode, current=IdentityMode.OFF),
|
||||
)
|
||||
|
||||
# 2) Try to fetch tools immediately after creation so they appear without a second save.
|
||||
# Perform network I/O outside any DB session to avoid holding locks.
|
||||
try:
|
||||
reconnect = MCPToolManageService.reconnect_with_url(
|
||||
server_url=payload.server_url,
|
||||
headers=payload.headers or {},
|
||||
server_url=req_data.server_url,
|
||||
headers=req_data.headers or {},
|
||||
timeout=configuration.timeout,
|
||||
sse_read_timeout=configuration.sse_read_timeout,
|
||||
)
|
||||
@@ -1403,24 +1392,24 @@ class ToolProviderMCPApi(Resource):
|
||||
@account_initialization_required
|
||||
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.MCP_MANAGE, resource_required=False)
|
||||
@with_current_tenant_id
|
||||
def put(self, current_tenant_id: str):
|
||||
payload = MCPProviderUpdatePayload.model_validate(console_ns.payload or {})
|
||||
configuration = payload.configuration or MCPConfiguration()
|
||||
authentication = payload.authentication
|
||||
@model_validate(MCPProviderUpdatePayload)
|
||||
def put(self, req_data: MCPProviderUpdatePayload, current_tenant_id: str):
|
||||
configuration = req_data.configuration or MCPConfiguration()
|
||||
authentication = req_data.authentication
|
||||
|
||||
# Step 1: Get provider data for URL validation (short-lived session, no network I/O)
|
||||
validation_data = None
|
||||
with sessionmaker(db.engine).begin() as session:
|
||||
service = MCPToolManageService(session=session)
|
||||
validation_data = service.get_provider_for_url_validation(
|
||||
tenant_id=current_tenant_id, provider_id=payload.provider_id
|
||||
tenant_id=current_tenant_id, provider_id=req_data.provider_id
|
||||
)
|
||||
|
||||
# Step 2: Perform URL validation with network I/O OUTSIDE of any database session
|
||||
# This prevents holding database locks during potentially slow network operations
|
||||
validation_result = MCPToolManageService.validate_server_url_standalone(
|
||||
tenant_id=current_tenant_id,
|
||||
new_server_url=payload.server_url,
|
||||
new_server_url=req_data.server_url,
|
||||
validation_data=validation_data,
|
||||
)
|
||||
|
||||
@@ -1430,18 +1419,18 @@ class ToolProviderMCPApi(Resource):
|
||||
# Resolve "leave unchanged" (None) against the stored value, and gate
|
||||
# the result on ENTERPRISE_ENABLED — both are API-layer concerns, so
|
||||
# the service receives a concrete IdentityMode.
|
||||
existing = service.get_provider(provider_id=payload.provider_id, tenant_id=current_tenant_id)
|
||||
identity_mode = _resolve_identity_mode(payload.identity_mode, current=IdentityMode(existing.identity_mode))
|
||||
existing = service.get_provider(provider_id=req_data.provider_id, tenant_id=current_tenant_id)
|
||||
identity_mode = _resolve_identity_mode(req_data.identity_mode, current=IdentityMode(existing.identity_mode))
|
||||
service.update_provider(
|
||||
tenant_id=current_tenant_id,
|
||||
provider_id=payload.provider_id,
|
||||
server_url=payload.server_url,
|
||||
name=payload.name,
|
||||
icon=payload.icon,
|
||||
icon_type=payload.icon_type,
|
||||
icon_background=payload.icon_background,
|
||||
server_identifier=payload.server_identifier,
|
||||
headers=payload.headers or {},
|
||||
provider_id=req_data.provider_id,
|
||||
server_url=req_data.server_url,
|
||||
name=req_data.name,
|
||||
icon=req_data.icon,
|
||||
icon_type=req_data.icon_type,
|
||||
icon_background=req_data.icon_background,
|
||||
server_identifier=req_data.server_identifier,
|
||||
headers=req_data.headers or {},
|
||||
configuration=configuration,
|
||||
authentication=authentication,
|
||||
validation_result=validation_result,
|
||||
@@ -1457,12 +1446,11 @@ class ToolProviderMCPApi(Resource):
|
||||
@account_initialization_required
|
||||
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.MCP_MANAGE, resource_required=False)
|
||||
@with_current_tenant_id
|
||||
def delete(self, current_tenant_id: str):
|
||||
payload = MCPProviderDeletePayload.model_validate(console_ns.payload or {})
|
||||
|
||||
@model_validate(MCPProviderDeletePayload)
|
||||
def delete(self, req_data: MCPProviderDeletePayload, current_tenant_id: str):
|
||||
with sessionmaker(db.engine).begin() as session:
|
||||
service = MCPToolManageService(session=session)
|
||||
service.delete_provider(tenant_id=current_tenant_id, provider_id=payload.provider_id)
|
||||
service.delete_provider(tenant_id=current_tenant_id, provider_id=req_data.provider_id)
|
||||
|
||||
return SimpleResultResponse(result="success").model_dump(mode="json")
|
||||
|
||||
@@ -1476,9 +1464,9 @@ class ToolMCPAuthApi(Resource):
|
||||
@account_initialization_required
|
||||
@rbac_permission_required(RBACResourceScope.WORKSPACE, RBACPermission.MCP_MANAGE, resource_required=False)
|
||||
@with_current_tenant_id
|
||||
def post(self, tenant_id: str):
|
||||
payload = MCPAuthPayload.model_validate(console_ns.payload or {})
|
||||
provider_id = payload.provider_id
|
||||
@model_validate(MCPAuthPayload)
|
||||
def post(self, req_data: MCPAuthPayload, tenant_id: str):
|
||||
provider_id = req_data.provider_id
|
||||
|
||||
with sessionmaker(db.engine).begin() as session:
|
||||
service = MCPToolManageService(session=session)
|
||||
@@ -1515,7 +1503,7 @@ class ToolMCPAuthApi(Resource):
|
||||
# Pass the extracted OAuth metadata hints to auth()
|
||||
auth_result = auth(
|
||||
provider_entity,
|
||||
payload.authorization_code,
|
||||
req_data.authorization_code,
|
||||
resource_metadata_url=e.resource_metadata_url,
|
||||
scope_hint=e.scope_hint,
|
||||
)
|
||||
|
||||
@@ -10,6 +10,25 @@ from werkzeug.datastructures import FileStorage
|
||||
from werkzeug.exceptions import Forbidden
|
||||
|
||||
from controllers.console.workspace.plugin import (
|
||||
ParserAsset,
|
||||
ParserAutoUpgradeChange,
|
||||
ParserAutoUpgradeFetch,
|
||||
ParserDynamicOptions,
|
||||
ParserDynamicOptionsWithCredentials,
|
||||
ParserExcludePlugin,
|
||||
ParserGithubInstall,
|
||||
ParserGithubUpgrade,
|
||||
ParserGithubUpload,
|
||||
ParserIcon,
|
||||
ParserLatest,
|
||||
ParserList,
|
||||
ParserMarketplaceUpgrade,
|
||||
ParserPermissionChange,
|
||||
ParserPluginIdentifierQuery,
|
||||
ParserPluginIdentifiers,
|
||||
ParserReadme,
|
||||
ParserTasks,
|
||||
ParserUninstall,
|
||||
PluginAssetApi,
|
||||
PluginAutoUpgradeExcludePluginApi,
|
||||
PluginCategoryListApi,
|
||||
@@ -29,6 +48,7 @@ from controllers.console.workspace.plugin import (
|
||||
PluginFetchPermissionApi,
|
||||
PluginIconApi,
|
||||
PluginInstalledIdsApi,
|
||||
PluginInstalledIdsQuery,
|
||||
PluginInstallFromGithubApi,
|
||||
PluginInstallFromMarketplaceApi,
|
||||
PluginInstallFromPkgApi,
|
||||
@@ -367,7 +387,7 @@ class TestPluginListLatestVersionsApi:
|
||||
app.test_request_context("/", json=payload),
|
||||
patch("controllers.console.workspace.plugin.PluginService.list_latest_versions", return_value=versions),
|
||||
):
|
||||
result = method(api)
|
||||
result = method(api, ParserLatest.model_validate(payload))
|
||||
|
||||
assert result == {
|
||||
"versions": {
|
||||
@@ -389,7 +409,7 @@ class TestPluginListLatestVersionsApi:
|
||||
side_effect=PluginDaemonClientSideError("error"),
|
||||
),
|
||||
):
|
||||
result = method(api)
|
||||
result = method(api, ParserLatest.model_validate(payload))
|
||||
assert result == ({"code": "plugin_error", "message": "error"}, 400)
|
||||
|
||||
|
||||
@@ -435,7 +455,7 @@ class TestPluginListApi:
|
||||
return_value=plugins_with_total,
|
||||
) as mock_list_with_total,
|
||||
):
|
||||
result = method(api, "t1", "u1")
|
||||
result = method(api, ParserList(page=1, page_size=10), "t1", "u1")
|
||||
|
||||
assert result == {"plugins": [_expected_plugin_entity_dump()], "total": 1}
|
||||
mock_list_with_total.assert_called_once_with("t1", "u1", 1, 10)
|
||||
@@ -584,7 +604,7 @@ class TestPluginIconApi:
|
||||
app.test_request_context("/?tenant_id=t1&filename=a.png"),
|
||||
patch("controllers.console.workspace.plugin.PluginService.get_asset", return_value=(b"x", "image/png")),
|
||||
):
|
||||
response = method(api)
|
||||
response = method(api, ParserIcon.model_validate({"tenant_id": "t1", "filename": "a.png"}))
|
||||
|
||||
assert response.mimetype == "image/png"
|
||||
|
||||
@@ -598,7 +618,9 @@ class TestPluginAssetApi:
|
||||
app.test_request_context("/?plugin_unique_identifier=p&file_name=a.bin"),
|
||||
patch("controllers.console.workspace.plugin.PluginService.extract_asset", return_value=b"x"),
|
||||
):
|
||||
response = method(api, "t1")
|
||||
response = method(
|
||||
api, ParserAsset.model_validate({"plugin_unique_identifier": "p", "file_name": "a.bin"}), "t1"
|
||||
)
|
||||
|
||||
assert response.mimetype == "application/octet-stream"
|
||||
|
||||
@@ -653,7 +675,7 @@ class TestPluginInstallFromPkgApi:
|
||||
"controllers.console.workspace.plugin.PluginService.install_from_local_pkg", return_value={"ok": True}
|
||||
),
|
||||
):
|
||||
result = method(api, "t1")
|
||||
result = method(api, ParserPluginIdentifiers.model_validate(payload), "t1")
|
||||
|
||||
assert result["ok"] is True
|
||||
|
||||
@@ -673,7 +695,7 @@ class TestPluginUninstallApi:
|
||||
app.test_request_context("/", json=payload),
|
||||
patch("controllers.console.workspace.plugin.PluginService.uninstall", return_value=True) as uninstall_mock,
|
||||
):
|
||||
result = method(api, "t1")
|
||||
result = method(api, ParserUninstall.model_validate(payload), "t1")
|
||||
|
||||
assert result["success"] is True
|
||||
uninstall_mock.assert_called_once_with(
|
||||
@@ -699,7 +721,7 @@ class TestPluginChangePermissionApi:
|
||||
app.test_request_context("/", json=payload),
|
||||
):
|
||||
with pytest.raises(Forbidden):
|
||||
method(api, "t1", user)
|
||||
method(api, ParserPermissionChange(), "t1", user)
|
||||
|
||||
def test_change_permission_success(self, app: Flask):
|
||||
api = PluginChangePermissionApi()
|
||||
@@ -716,7 +738,7 @@ class TestPluginChangePermissionApi:
|
||||
app.test_request_context("/", json=payload),
|
||||
patch("controllers.console.workspace.plugin.PluginPermissionService.change_permission", return_value=True),
|
||||
):
|
||||
result = method(api, "t1", user)
|
||||
result = method(api, ParserPermissionChange(), "t1", user)
|
||||
|
||||
assert result["success"] is True
|
||||
|
||||
@@ -747,7 +769,14 @@ class TestPluginFetchDynamicSelectOptionsApi:
|
||||
return_value=[_dynamic_option()],
|
||||
),
|
||||
):
|
||||
result = method(api, "t1", user)
|
||||
result = method(
|
||||
api,
|
||||
ParserDynamicOptions.model_validate(
|
||||
{"plugin_id": "p", "provider": "x", "action": "y", "parameter": "z", "provider_type": "tool"}
|
||||
),
|
||||
"t1",
|
||||
user,
|
||||
)
|
||||
|
||||
assert result == {"options": [_expected_dynamic_option_dump()]}
|
||||
|
||||
@@ -761,7 +790,7 @@ class TestPluginReadmeApi:
|
||||
app.test_request_context("/?plugin_unique_identifier=p"),
|
||||
patch("controllers.console.workspace.plugin.PluginService.fetch_plugin_readme", return_value="readme"),
|
||||
):
|
||||
result = method(api, "t1")
|
||||
result = method(api, ParserReadme.model_validate({"plugin_unique_identifier": "p"}), "t1")
|
||||
|
||||
assert result["readme"] == "readme"
|
||||
|
||||
@@ -780,7 +809,7 @@ class TestPluginListInstallationsFromIdsApi:
|
||||
return_value=[_plugin_installation()],
|
||||
),
|
||||
):
|
||||
result = method(api, "t1")
|
||||
result = method(api, ParserLatest.model_validate(payload), "t1")
|
||||
|
||||
assert result == {"plugins": [_expected_plugin_installation_dump()]}
|
||||
|
||||
@@ -797,7 +826,7 @@ class TestPluginListInstallationsFromIdsApi:
|
||||
side_effect=PluginDaemonClientSideError("error"),
|
||||
),
|
||||
):
|
||||
result = method(api, "t1")
|
||||
result = method(api, ParserLatest.model_validate(payload), "t1")
|
||||
assert result == ({"code": "plugin_error", "message": "error"}, 400)
|
||||
|
||||
|
||||
@@ -813,7 +842,7 @@ class TestPluginInstalledIdsApi:
|
||||
return_value=["langgenius/openai", "langgenius/anthropic"],
|
||||
) as list_installed_plugin_ids,
|
||||
):
|
||||
result = method(api, "t1")
|
||||
result = method(api, PluginInstalledIdsQuery.model_validate({"category": "tool"}), "t1")
|
||||
|
||||
assert result == {"plugin_ids": ["langgenius/openai", "langgenius/anthropic"]}
|
||||
list_installed_plugin_ids.assert_called_once_with("t1", PluginCategory.Tool)
|
||||
@@ -829,7 +858,7 @@ class TestPluginInstalledIdsApi:
|
||||
side_effect=PluginDaemonClientSideError("error"),
|
||||
),
|
||||
):
|
||||
result = method(api, "t1")
|
||||
result = method(api, PluginInstalledIdsQuery.model_validate({"category": "tool"}), "t1")
|
||||
|
||||
assert result == ({"code": "plugin_error", "message": "error"}, 400)
|
||||
|
||||
@@ -847,7 +876,7 @@ class TestPluginUploadFromGithubApi:
|
||||
"controllers.console.workspace.plugin.PluginService.upload_pkg_from_github", return_value={"ok": True}
|
||||
),
|
||||
):
|
||||
result = method(api, "t1")
|
||||
result = method(api, ParserGithubUpload.model_validate(payload), "t1")
|
||||
|
||||
assert result["ok"] is True
|
||||
|
||||
@@ -864,7 +893,7 @@ class TestPluginUploadFromGithubApi:
|
||||
side_effect=PluginDaemonClientSideError("error"),
|
||||
),
|
||||
):
|
||||
result = method(api, "t1")
|
||||
result = method(api, ParserGithubUpload.model_validate(payload), "t1")
|
||||
assert result == ({"code": "plugin_error", "message": "error"}, 400)
|
||||
|
||||
|
||||
@@ -933,7 +962,7 @@ class TestPluginInstallFromGithubApi:
|
||||
app.test_request_context("/", json=payload),
|
||||
patch("controllers.console.workspace.plugin.PluginService.install_from_github", return_value={"ok": True}),
|
||||
):
|
||||
result = method(api, "t1")
|
||||
result = method(api, ParserGithubInstall.model_validate(payload), "t1")
|
||||
|
||||
assert result["ok"] is True
|
||||
|
||||
@@ -955,7 +984,7 @@ class TestPluginInstallFromGithubApi:
|
||||
side_effect=PluginDaemonClientSideError("error"),
|
||||
),
|
||||
):
|
||||
result = method(api, "t1")
|
||||
result = method(api, ParserGithubInstall.model_validate(payload), "t1")
|
||||
assert result == ({"code": "plugin_error", "message": "error"}, 400)
|
||||
|
||||
|
||||
@@ -973,7 +1002,7 @@ class TestPluginInstallFromMarketplaceApi:
|
||||
return_value={"ok": True},
|
||||
),
|
||||
):
|
||||
result = method(api, "t1")
|
||||
result = method(api, ParserPluginIdentifiers.model_validate(payload), "t1")
|
||||
|
||||
assert result["ok"] is True
|
||||
|
||||
@@ -990,7 +1019,7 @@ class TestPluginInstallFromMarketplaceApi:
|
||||
side_effect=PluginDaemonClientSideError("error"),
|
||||
),
|
||||
):
|
||||
result = method(api, "t1")
|
||||
result = method(api, ParserPluginIdentifiers.model_validate(payload), "t1")
|
||||
assert result == ({"code": "plugin_error", "message": "error"}, 400)
|
||||
|
||||
|
||||
@@ -1006,7 +1035,7 @@ class TestPluginFetchMarketplacePkgApi:
|
||||
return_value=_plugin_declaration(),
|
||||
),
|
||||
):
|
||||
result = method(api, "t1")
|
||||
result = method(api, ParserPluginIdentifierQuery.model_validate({"plugin_unique_identifier": "p"}), "t1")
|
||||
|
||||
assert result == {"manifest": _expected_plugin_declaration_dump()}
|
||||
|
||||
@@ -1021,7 +1050,7 @@ class TestPluginFetchMarketplacePkgApi:
|
||||
side_effect=PluginDaemonClientSideError("error"),
|
||||
),
|
||||
):
|
||||
result = method(api, "t1")
|
||||
result = method(api, ParserPluginIdentifierQuery.model_validate({"plugin_unique_identifier": "p"}), "t1")
|
||||
assert result == ({"code": "plugin_error", "message": "error"}, 400)
|
||||
|
||||
|
||||
@@ -1036,7 +1065,7 @@ class TestPluginFetchManifestApi:
|
||||
app.test_request_context("/?plugin_unique_identifier=p"),
|
||||
patch("controllers.console.workspace.plugin.PluginService.fetch_plugin_manifest", return_value=manifest),
|
||||
):
|
||||
result = method(api, "t1")
|
||||
result = method(api, ParserPluginIdentifierQuery.model_validate({"plugin_unique_identifier": "p"}), "t1")
|
||||
|
||||
assert result == {"manifest": _expected_plugin_declaration_dump()}
|
||||
|
||||
@@ -1051,7 +1080,7 @@ class TestPluginFetchManifestApi:
|
||||
side_effect=PluginDaemonClientSideError("error"),
|
||||
),
|
||||
):
|
||||
result = method(api, "t1")
|
||||
result = method(api, ParserPluginIdentifierQuery.model_validate({"plugin_unique_identifier": "p"}), "t1")
|
||||
assert result == ({"code": "plugin_error", "message": "error"}, 400)
|
||||
|
||||
|
||||
@@ -1067,7 +1096,7 @@ class TestPluginFetchInstallTasksApi:
|
||||
return_value=[_plugin_task()],
|
||||
),
|
||||
):
|
||||
result = method(api, "t1")
|
||||
result = method(api, ParserTasks(), "t1")
|
||||
|
||||
assert result == {"tasks": [_expected_plugin_task_dump()]}
|
||||
|
||||
@@ -1082,7 +1111,7 @@ class TestPluginFetchInstallTasksApi:
|
||||
side_effect=PluginDaemonClientSideError("error"),
|
||||
),
|
||||
):
|
||||
result = method(api, "t1")
|
||||
result = method(api, ParserTasks(), "t1")
|
||||
assert result == ({"code": "plugin_error", "message": "error"}, 400)
|
||||
|
||||
|
||||
@@ -1217,7 +1246,7 @@ class TestPluginUpgradeFromMarketplaceApi:
|
||||
return_value={"ok": True},
|
||||
),
|
||||
):
|
||||
result = method(api, "t1")
|
||||
result = method(api, ParserMarketplaceUpgrade.model_validate(payload), "t1")
|
||||
|
||||
assert result["ok"] is True
|
||||
|
||||
@@ -1237,7 +1266,7 @@ class TestPluginUpgradeFromMarketplaceApi:
|
||||
side_effect=PluginDaemonClientSideError("error"),
|
||||
),
|
||||
):
|
||||
result = method(api, "t1")
|
||||
result = method(api, ParserMarketplaceUpgrade.model_validate(payload), "t1")
|
||||
assert result == ({"code": "plugin_error", "message": "error"}, 400)
|
||||
|
||||
|
||||
@@ -1261,7 +1290,7 @@ class TestPluginUpgradeFromGithubApi:
|
||||
return_value={"ok": True},
|
||||
),
|
||||
):
|
||||
result = method(api, "t1")
|
||||
result = method(api, ParserGithubUpgrade.model_validate(payload), "t1")
|
||||
|
||||
assert result["ok"] is True
|
||||
|
||||
@@ -1284,7 +1313,7 @@ class TestPluginUpgradeFromGithubApi:
|
||||
side_effect=PluginDaemonClientSideError("error"),
|
||||
),
|
||||
):
|
||||
result = method(api, "t1")
|
||||
result = method(api, ParserGithubUpgrade.model_validate(payload), "t1")
|
||||
assert result == ({"code": "plugin_error", "message": "error"}, 400)
|
||||
|
||||
|
||||
@@ -1309,7 +1338,7 @@ class TestPluginFetchDynamicSelectOptionsWithCredentialsApi:
|
||||
return_value=[_dynamic_option()],
|
||||
),
|
||||
):
|
||||
result = method(api, "t1", user)
|
||||
result = method(api, ParserDynamicOptionsWithCredentials.model_validate(payload), "t1", user)
|
||||
|
||||
assert result == {"options": [_expected_dynamic_option_dump()]}
|
||||
|
||||
@@ -1333,7 +1362,7 @@ class TestPluginFetchDynamicSelectOptionsWithCredentialsApi:
|
||||
side_effect=PluginDaemonClientSideError("error"),
|
||||
),
|
||||
):
|
||||
result = method(api, "t1", user)
|
||||
result = method(api, ParserDynamicOptionsWithCredentials.model_validate(payload), "t1", user)
|
||||
assert result == ({"code": "plugin_error", "message": "error"}, 400)
|
||||
|
||||
|
||||
@@ -1361,7 +1390,7 @@ class TestPluginChangeAutoUpgradeApi:
|
||||
"controllers.console.workspace.plugin.PluginAutoUpgradeService.change_strategy", return_value=True
|
||||
) as change,
|
||||
):
|
||||
result = method(api, "t1", user)
|
||||
result = method(api, ParserAutoUpgradeChange.model_validate(payload), "t1", user)
|
||||
|
||||
assert result["success"] is True
|
||||
change.assert_called_once()
|
||||
@@ -1389,7 +1418,7 @@ class TestPluginChangeAutoUpgradeApi:
|
||||
"controllers.console.workspace.plugin.PluginAutoUpgradeService.change_strategy", return_value=True
|
||||
) as change,
|
||||
):
|
||||
result = method(api, "t1", user)
|
||||
result = method(api, ParserAutoUpgradeChange.model_validate(payload), "t1", user)
|
||||
|
||||
assert result["success"] is True
|
||||
change.assert_called_once()
|
||||
@@ -1416,7 +1445,7 @@ class TestPluginChangeAutoUpgradeApi:
|
||||
app.test_request_context("/", json=payload),
|
||||
patch("controllers.console.workspace.plugin.PluginAutoUpgradeService.change_strategy", return_value=False),
|
||||
):
|
||||
result = method(api, "t1", user)
|
||||
result = method(api, ParserAutoUpgradeChange.model_validate(payload), "t1", user)
|
||||
|
||||
assert result["success"] is False
|
||||
|
||||
@@ -1442,7 +1471,11 @@ class TestPluginFetchAutoUpgradeApi:
|
||||
return_value=auto_upgrade,
|
||||
),
|
||||
):
|
||||
result = method(api, "t1")
|
||||
result = method(
|
||||
api,
|
||||
ParserAutoUpgradeFetch.model_validate({"category": TenantPluginAutoUpgradeCategory.TOOL.value}),
|
||||
"t1",
|
||||
)
|
||||
|
||||
assert result["category"] == TenantPluginAutoUpgradeCategory.TOOL
|
||||
assert result["auto_upgrade"]["upgrade_time_of_day"] == 1
|
||||
@@ -1462,7 +1495,11 @@ class TestPluginFetchAutoUpgradeApi:
|
||||
return_value=78300,
|
||||
),
|
||||
):
|
||||
result = method(api, "t1")
|
||||
result = method(
|
||||
api,
|
||||
ParserAutoUpgradeFetch.model_validate({"category": TenantPluginAutoUpgradeCategory.MODEL.value}),
|
||||
"t1",
|
||||
)
|
||||
|
||||
assert result == {
|
||||
"category": TenantPluginAutoUpgradeCategory.MODEL,
|
||||
@@ -1487,7 +1524,7 @@ class TestPluginAutoUpgradeExcludePluginApi:
|
||||
app.test_request_context("/", json=payload),
|
||||
patch("controllers.console.workspace.plugin.PluginAutoUpgradeService.exclude_plugin", return_value=True),
|
||||
):
|
||||
result = method(api, "t1")
|
||||
result = method(api, ParserExcludePlugin.model_validate(payload), "t1")
|
||||
|
||||
assert result["success"] is True
|
||||
|
||||
@@ -1501,6 +1538,6 @@ class TestPluginAutoUpgradeExcludePluginApi:
|
||||
app.test_request_context("/", json=payload),
|
||||
patch("controllers.console.workspace.plugin.PluginAutoUpgradeService.exclude_plugin", return_value=False),
|
||||
):
|
||||
result = method(api, "t1")
|
||||
result = method(api, ParserExcludePlugin.model_validate(payload), "t1")
|
||||
|
||||
assert result["success"] is False
|
||||
|
||||
@@ -10,6 +10,13 @@ from flask import Flask
|
||||
from werkzeug.exceptions import Forbidden
|
||||
|
||||
from controllers.console.workspace.tool_providers import (
|
||||
ApiToolProviderAddPayload,
|
||||
ApiToolProviderDeletePayload,
|
||||
ApiToolProviderUpdatePayload,
|
||||
BuiltinProviderDefaultCredentialPayload,
|
||||
BuiltinToolAddPayload,
|
||||
BuiltinToolCredentialDeletePayload,
|
||||
BuiltinToolUpdatePayload,
|
||||
ToolApiListApi,
|
||||
ToolApiProviderAddApi,
|
||||
ToolApiProviderDeleteApi,
|
||||
@@ -32,6 +39,7 @@ from controllers.console.workspace.tool_providers import (
|
||||
ToolLabelsApi,
|
||||
ToolOAuthCallback,
|
||||
ToolOAuthCustomClient,
|
||||
ToolOAuthCustomClientPayload,
|
||||
ToolPluginOAuthApi,
|
||||
ToolProviderListApi,
|
||||
ToolWorkflowListApi,
|
||||
@@ -39,6 +47,9 @@ from controllers.console.workspace.tool_providers import (
|
||||
ToolWorkflowProviderDeleteApi,
|
||||
ToolWorkflowProviderGetApi,
|
||||
ToolWorkflowProviderUpdateApi,
|
||||
WorkflowToolCreatePayload,
|
||||
WorkflowToolDeletePayload,
|
||||
WorkflowToolUpdatePayload,
|
||||
is_valid_url,
|
||||
)
|
||||
from core.tools.entities.api_entities import ToolProviderApiEntity as CoreToolProviderApiEntity
|
||||
@@ -276,7 +287,8 @@ class TestBuiltinProviderApis:
|
||||
return_value={"result": "success"},
|
||||
),
|
||||
):
|
||||
assert method(api, "t1", "provider")["result"] == "success"
|
||||
req = BuiltinToolCredentialDeletePayload(credential_id="cid")
|
||||
assert method(api, req, "t1", "provider")["result"] == "success"
|
||||
|
||||
def test_add_invalid_type(self, app: Flask) -> None:
|
||||
api = ToolBuiltinProviderAddApi()
|
||||
@@ -286,7 +298,13 @@ class TestBuiltinProviderApis:
|
||||
app.test_request_context("/", json={"credentials": empty_mapping(), "type": "invalid"}),
|
||||
):
|
||||
with pytest.raises(ValueError):
|
||||
method(api, "t", make_account(), "provider")
|
||||
method(
|
||||
api,
|
||||
BuiltinToolAddPayload(credentials=empty_mapping(), type="invalid"),
|
||||
"t",
|
||||
make_account(),
|
||||
"provider",
|
||||
)
|
||||
|
||||
def test_add_success(self, app: Flask) -> None:
|
||||
api = ToolBuiltinProviderAddApi()
|
||||
@@ -301,7 +319,7 @@ class TestBuiltinProviderApis:
|
||||
return_value={"result": "success"},
|
||||
),
|
||||
):
|
||||
assert method(api, "t", make_account(), "provider")["result"] == "success"
|
||||
assert method(api, BuiltinToolAddPayload(**payload), "t", make_account(), "provider")["result"] == "success"
|
||||
|
||||
def test_update(self, app: Flask) -> None:
|
||||
api = ToolBuiltinProviderUpdateApi()
|
||||
@@ -316,7 +334,8 @@ class TestBuiltinProviderApis:
|
||||
return_value={"result": "success"},
|
||||
),
|
||||
):
|
||||
assert method(api, "t", make_account(), "provider")["result"] == "success"
|
||||
req = BuiltinToolUpdatePayload(**payload)
|
||||
assert method(api, req, "t", make_account(), "provider")["result"] == "success"
|
||||
|
||||
def test_get_credentials(self, app: Flask) -> None:
|
||||
api = ToolBuiltinProviderGetCredentialsApi()
|
||||
@@ -369,7 +388,8 @@ class TestBuiltinProviderApis:
|
||||
return_value={"result": "success"},
|
||||
),
|
||||
):
|
||||
assert method(api, "t", "provider")["result"] == "success"
|
||||
req = BuiltinProviderDefaultCredentialPayload(id="c1")
|
||||
assert method(api, req, "t", "provider")["result"] == "success"
|
||||
|
||||
def test_get_credential_info(self, app: Flask) -> None:
|
||||
api = ToolBuiltinProviderGetCredentialInfoApi()
|
||||
@@ -418,7 +438,7 @@ class TestApiProviderApis:
|
||||
return_value={"result": "success"},
|
||||
) as create_api_tool_provider,
|
||||
):
|
||||
assert method(api, "t", make_account()) == {"result": "success"}
|
||||
assert method(api, ApiToolProviderAddPayload(**payload), "t", make_account()) == {"result": "success"}
|
||||
|
||||
create_api_tool_provider.assert_called_once()
|
||||
assert create_api_tool_provider.call_args.args[3] == emoji_icon()
|
||||
@@ -472,7 +492,7 @@ class TestApiProviderApis:
|
||||
return_value={"result": "success"},
|
||||
) as update_api_tool_provider,
|
||||
):
|
||||
assert method(api, "t", make_account()) == {"result": "success"}
|
||||
assert method(api, ApiToolProviderUpdatePayload(**payload), "t", make_account()) == {"result": "success"}
|
||||
|
||||
update_api_tool_provider.assert_called_once()
|
||||
assert update_api_tool_provider.call_args.args[4] == emoji_icon()
|
||||
@@ -488,7 +508,8 @@ class TestApiProviderApis:
|
||||
return_value={"result": "success"},
|
||||
),
|
||||
):
|
||||
assert method(api, "t", make_account())["result"] == "success"
|
||||
req = ApiToolProviderDeletePayload(provider="p")
|
||||
assert method(api, req, "t", make_account())["result"] == "success"
|
||||
|
||||
def test_get(self, app: Flask) -> None:
|
||||
api = ToolApiProviderGetApi()
|
||||
@@ -525,7 +546,7 @@ class TestWorkflowApis:
|
||||
return_value={"result": "success"},
|
||||
) as create_workflow_tool,
|
||||
):
|
||||
assert method(api, "t", make_account()) == {"result": "success"}
|
||||
assert method(api, WorkflowToolCreatePayload(**payload), "t", make_account()) == {"result": "success"}
|
||||
|
||||
create_workflow_tool.assert_called_once()
|
||||
assert create_workflow_tool.call_args.kwargs["icon"] == emoji_icon()
|
||||
@@ -549,7 +570,7 @@ class TestWorkflowApis:
|
||||
return_value={"result": "success"},
|
||||
) as update_workflow_tool,
|
||||
):
|
||||
result = method(api, "t", make_account())
|
||||
result = method(api, WorkflowToolUpdatePayload(**payload), "t", make_account())
|
||||
assert result == {"result": "success"}
|
||||
|
||||
update_workflow_tool.assert_called_once()
|
||||
@@ -566,7 +587,8 @@ class TestWorkflowApis:
|
||||
return_value={"result": "success"},
|
||||
),
|
||||
):
|
||||
assert method(api, "t", make_account())["result"] == "success"
|
||||
req = WorkflowToolDeletePayload(workflow_tool_id="123e4567-e89b-12d3-a456-426614174000")
|
||||
assert method(api, req, "t", make_account())["result"] == "success"
|
||||
|
||||
def test_get_error(self, app: Flask) -> None:
|
||||
api = ToolWorkflowProviderGetApi()
|
||||
@@ -671,7 +693,8 @@ class TestOAuthCustomClient:
|
||||
return_value={"result": "success"},
|
||||
),
|
||||
):
|
||||
assert method(api, "t", "provider") == {"result": "success"}
|
||||
req = ToolOAuthCustomClientPayload(client_params={"a": 1})
|
||||
assert method(api, req, "t", "provider") == {"result": "success"}
|
||||
|
||||
def test_get_custom_client(self, app: Flask) -> None:
|
||||
api = ToolOAuthCustomClient()
|
||||
|
||||
Reference in New Issue
Block a user