api.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. from typing import Optional
  2. from pydantic import BaseModel
  3. from core.extension.api_based_extension_requestor import APIBasedExtensionPoint, APIBasedExtensionRequestor
  4. from core.helper.encrypter import decrypt_token
  5. from core.moderation.base import Moderation, ModerationAction, ModerationInputsResult, ModerationOutputsResult
  6. from extensions.ext_database import db
  7. from models.api_based_extension import APIBasedExtension
  8. class ModerationInputParams(BaseModel):
  9. app_id: str = ""
  10. inputs: dict = {}
  11. query: str = ""
  12. class ModerationOutputParams(BaseModel):
  13. app_id: str = ""
  14. text: str
  15. class ApiModeration(Moderation):
  16. name: str = "api"
  17. @classmethod
  18. def validate_config(cls, tenant_id: str, config: dict) -> None:
  19. """
  20. Validate the incoming form config data.
  21. :param tenant_id: the id of workspace
  22. :param config: the form config data
  23. :return:
  24. """
  25. cls._validate_inputs_and_outputs_config(config, False)
  26. api_based_extension_id = config.get("api_based_extension_id")
  27. if not api_based_extension_id:
  28. raise ValueError("api_based_extension_id is required")
  29. extension = cls._get_api_based_extension(tenant_id, api_based_extension_id)
  30. if not extension:
  31. raise ValueError("API-based Extension not found. Please check it again.")
  32. def moderation_for_inputs(self, inputs: dict, query: str = "") -> ModerationInputsResult:
  33. flagged = False
  34. preset_response = ""
  35. if self.config is None:
  36. raise ValueError("The config is not set.")
  37. if self.config["inputs_config"]["enabled"]:
  38. params = ModerationInputParams(app_id=self.app_id, inputs=inputs, query=query)
  39. result = self._get_config_by_requestor(APIBasedExtensionPoint.APP_MODERATION_INPUT, params.model_dump())
  40. return ModerationInputsResult(**result)
  41. return ModerationInputsResult(
  42. flagged=flagged, action=ModerationAction.DIRECT_OUTPUT, preset_response=preset_response
  43. )
  44. def moderation_for_outputs(self, text: str) -> ModerationOutputsResult:
  45. flagged = False
  46. preset_response = ""
  47. if self.config is None:
  48. raise ValueError("The config is not set.")
  49. if self.config["outputs_config"]["enabled"]:
  50. params = ModerationOutputParams(app_id=self.app_id, text=text)
  51. result = self._get_config_by_requestor(APIBasedExtensionPoint.APP_MODERATION_OUTPUT, params.model_dump())
  52. return ModerationOutputsResult(**result)
  53. return ModerationOutputsResult(
  54. flagged=flagged, action=ModerationAction.DIRECT_OUTPUT, preset_response=preset_response
  55. )
  56. def _get_config_by_requestor(self, extension_point: APIBasedExtensionPoint, params: dict) -> dict:
  57. if self.config is None:
  58. raise ValueError("The config is not set.")
  59. extension = self._get_api_based_extension(self.tenant_id, self.config.get("api_based_extension_id", ""))
  60. if not extension:
  61. raise ValueError("API-based Extension not found. Please check it again.")
  62. requestor = APIBasedExtensionRequestor(extension.api_endpoint, decrypt_token(self.tenant_id, extension.api_key))
  63. result = requestor.request(extension_point, params)
  64. return result
  65. @staticmethod
  66. def _get_api_based_extension(tenant_id: str, api_based_extension_id: str) -> Optional[APIBasedExtension]:
  67. extension = (
  68. db.session.query(APIBasedExtension)
  69. .filter(APIBasedExtension.tenant_id == tenant_id, APIBasedExtension.id == api_based_extension_id)
  70. .first()
  71. )
  72. return extension