application.py 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492
  1. # coding=utf-8
  2. """
  3. @project: MaxKB
  4. @Author:虎虎
  5. @file: application.py
  6. @date:2025/5/26 16:51
  7. @desc:
  8. """
  9. from django.db.models import QuerySet
  10. from django.http import HttpResponse
  11. from django.utils.translation import gettext_lazy as _
  12. from drf_spectacular.utils import extend_schema
  13. from rest_framework.parsers import MultiPartParser
  14. from rest_framework.request import Request
  15. from rest_framework.views import APIView
  16. from application.api.application_api import ApplicationCreateAPI, ApplicationQueryAPI, ApplicationImportAPI, \
  17. ApplicationExportAPI, ApplicationOperateAPI, ApplicationEditAPI, TextToSpeechAPI, SpeechToTextAPI, PlayDemoTextAPI, \
  18. ApplicationBatchOperateAPI
  19. from application.models import Application
  20. from application.serializers.application import ApplicationSerializer, Query, ApplicationOperateSerializer, \
  21. ApplicationBatchOperateSerializer
  22. from common import result
  23. from common.auth import TokenAuth
  24. from common.auth.authentication import has_permissions, get_is_permissions, check_batch_permissions
  25. from common.constants.permission_constants import PermissionConstants, RoleConstants, ViewPermission, CompareConstants
  26. from common.log.log import log
  27. from tools.api.tool import GetInternalToolAPI
  28. def get_application_operation_object(application_id):
  29. application_model = QuerySet(model=Application).filter(id=application_id).first()
  30. if application_model is not None:
  31. return {
  32. 'name': application_model.name
  33. }
  34. return {}
  35. def get_application_operation_object_batch(application_id_list):
  36. application_model_list = QuerySet(model=Application).filter(id__in=application_id_list)
  37. if application_model_list is not None:
  38. return {
  39. "name": f'[{",".join([app.name for app in application_model_list])}]',
  40. 'application_list': [{'name': app.name} for app in application_model_list]
  41. }
  42. return {}
  43. class ApplicationAPI(APIView):
  44. authentication_classes = [TokenAuth]
  45. @extend_schema(
  46. methods=['POST'],
  47. description=_('Create an application'),
  48. summary=_('Create an application'),
  49. operation_id=_('Create an application'), # type: ignore
  50. parameters=ApplicationCreateAPI.get_parameters(),
  51. request=ApplicationCreateAPI.get_request(),
  52. responses=ApplicationCreateAPI.get_response(),
  53. tags=[_('Application')] # type: ignore
  54. )
  55. @has_permissions(PermissionConstants.APPLICATION_CREATE.get_workspace_permission(),
  56. RoleConstants.USER.get_workspace_role(),
  57. RoleConstants.WORKSPACE_MANAGE.get_workspace_role())
  58. @log(menu='Application', operate='Create an application',
  59. get_operation_object=lambda r, k: {'name': r.data.get('name')},
  60. )
  61. def post(self, request: Request, workspace_id: str):
  62. return result.success(
  63. ApplicationSerializer(data={'workspace_id': workspace_id, 'user_id': request.user.id}).insert(request.data))
  64. @extend_schema(
  65. methods=['GET'],
  66. description=_('Get the application list'),
  67. summary=_('Get the application list'),
  68. operation_id=_('Get the application list'), # type: ignore
  69. parameters=ApplicationQueryAPI.get_parameters(),
  70. responses=ApplicationQueryAPI.get_response(),
  71. tags=[_('Application')] # type: ignore
  72. )
  73. @has_permissions(PermissionConstants.APPLICATION_READ.get_workspace_permission(),
  74. RoleConstants.USER.get_workspace_role(),
  75. RoleConstants.WORKSPACE_MANAGE.get_workspace_role())
  76. def get(self, request: Request, workspace_id: str):
  77. return result.success(
  78. Query(data={'workspace_id': workspace_id, 'user_id': request.user.id}).list(request.query_params))
  79. class Page(APIView):
  80. authentication_classes = [TokenAuth]
  81. @extend_schema(
  82. methods=['GET'],
  83. description=_('Get the application list by page'),
  84. summary=_('Get the application list by page'),
  85. operation_id=_('Get the application list by page'), # type: ignore
  86. parameters=ApplicationQueryAPI.get_parameters(),
  87. responses=ApplicationQueryAPI.get_page_response(),
  88. tags=[_('Application')] # type: ignore
  89. )
  90. @has_permissions(PermissionConstants.APPLICATION_READ.get_workspace_permission(),
  91. RoleConstants.USER.get_workspace_role(),
  92. RoleConstants.WORKSPACE_MANAGE.get_workspace_role())
  93. def get(self, request: Request, workspace_id: str, current_page: int, page_size: int):
  94. return result.success(
  95. Query(data={'workspace_id': workspace_id, 'user_id': request.user.id}).page(current_page, page_size,
  96. request.query_params))
  97. class Import(APIView):
  98. authentication_classes = [TokenAuth]
  99. parser_classes = [MultiPartParser]
  100. @extend_schema(
  101. methods=['POST'],
  102. description=_('Import Application'),
  103. summary=_('Import Application'),
  104. operation_id=_('Import Application'), # type: ignore
  105. parameters=ApplicationImportAPI.get_parameters(),
  106. request=ApplicationImportAPI.get_request(),
  107. responses=result.DefaultResultSerializer,
  108. tags=[_('Application')] # type: ignore
  109. )
  110. @has_permissions(PermissionConstants.APPLICATION_IMPORT.get_workspace_permission(),
  111. RoleConstants.USER.get_workspace_role(),
  112. RoleConstants.WORKSPACE_MANAGE.get_workspace_role())
  113. @log(menu='Application', operate="Import Application", )
  114. def post(self, request: Request, workspace_id: str, folder_id: str):
  115. is_import_tool = get_is_permissions(request, workspace_id=workspace_id, folder_id=folder_id)(
  116. PermissionConstants.TOOL_IMPORT.get_workspace_permission(),
  117. PermissionConstants.TOOL_IMPORT.get_workspace_permission_workspace_manage_role(),
  118. RoleConstants.WORKSPACE_MANAGE.get_workspace_role(), RoleConstants.USER.get_workspace_role()
  119. )
  120. return result.success(ApplicationSerializer(
  121. data={'user_id': request.user.id, 'workspace_id': workspace_id,
  122. }).import_({'file': request.FILES.get('file'), 'folder_id': folder_id}, is_import_tool))
  123. class Export(APIView):
  124. authentication_classes = [TokenAuth]
  125. @extend_schema(
  126. methods=['POST'],
  127. description=_('Export application'),
  128. summary=_('Export application'),
  129. operation_id=_('Export application'), # type: ignore
  130. parameters=ApplicationExportAPI.get_parameters(),
  131. request=None,
  132. responses=ApplicationExportAPI.get_response(),
  133. tags=[_('Application')] # type: ignore
  134. )
  135. @has_permissions(PermissionConstants.APPLICATION_EXPORT.get_workspace_application_permission(),
  136. PermissionConstants.APPLICATION_EXPORT.get_workspace_permission_workspace_manage_role(),
  137. ViewPermission([RoleConstants.USER.get_workspace_role()],
  138. [PermissionConstants.APPLICATION.get_workspace_application_permission()],
  139. CompareConstants.AND),
  140. RoleConstants.WORKSPACE_MANAGE.get_workspace_role())
  141. @log(menu='Application', operate="Export Application",
  142. get_operation_object=lambda r, k: get_application_operation_object(k.get('application_id')),
  143. )
  144. def get(self, request: Request, workspace_id: str, application_id: str):
  145. return ApplicationOperateSerializer(
  146. data={'application_id': application_id,
  147. 'workspace_id': workspace_id,
  148. 'user_id': request.user.id}).export()
  149. class Operate(APIView):
  150. authentication_classes = [TokenAuth]
  151. @extend_schema(
  152. methods=['DELETE'],
  153. description=_('Deleting application'),
  154. summary=_('Deleting application'),
  155. operation_id=_('Deleting application'), # type: ignore
  156. parameters=ApplicationOperateAPI.get_parameters(),
  157. responses=result.DefaultResultSerializer,
  158. tags=[_('Application')] # type: ignore
  159. )
  160. @has_permissions(PermissionConstants.APPLICATION_DELETE.get_workspace_application_permission(),
  161. PermissionConstants.APPLICATION_DELETE.get_workspace_permission_workspace_manage_role(),
  162. ViewPermission([RoleConstants.USER.get_workspace_role()],
  163. [PermissionConstants.APPLICATION.get_workspace_application_permission()],
  164. CompareConstants.AND),
  165. RoleConstants.WORKSPACE_MANAGE.get_workspace_role())
  166. @log(menu='Application', operate='Deleting application',
  167. get_operation_object=lambda r, k: get_application_operation_object(k.get('application_id')),
  168. )
  169. def delete(self, request: Request, workspace_id: str, application_id: str):
  170. return result.success(ApplicationOperateSerializer(
  171. data={'application_id': application_id, 'user_id': request.user.id,
  172. 'workspace_id': workspace_id, }).delete(
  173. with_valid=True))
  174. @extend_schema(
  175. methods=['PUT'],
  176. description=_('Modify the application'),
  177. summary=_('Modify the application'),
  178. operation_id=_('Modify the application'), # type: ignore
  179. parameters=ApplicationOperateAPI.get_parameters(),
  180. request=ApplicationEditAPI.get_request(),
  181. responses=ApplicationCreateAPI.get_response(),
  182. tags=[_('Application')] # type: ignore
  183. )
  184. @has_permissions(PermissionConstants.APPLICATION_EDIT.get_workspace_application_permission(),
  185. PermissionConstants.APPLICATION_EDIT.get_workspace_permission_workspace_manage_role(),
  186. ViewPermission([RoleConstants.USER.get_workspace_role()],
  187. [PermissionConstants.APPLICATION.get_workspace_application_permission()],
  188. CompareConstants.AND),
  189. RoleConstants.WORKSPACE_MANAGE.get_workspace_role())
  190. @log(menu='Application', operate="Modify the application",
  191. get_operation_object=lambda r, k: get_application_operation_object(k.get('application_id')),
  192. )
  193. def put(self, request: Request, workspace_id: str, application_id: str):
  194. return result.success(
  195. ApplicationOperateSerializer(
  196. data={'application_id': application_id, 'user_id': request.user.id,
  197. 'workspace_id': workspace_id, }).edit(
  198. request.data))
  199. @extend_schema(
  200. methods=['GET'],
  201. description=_('Get application details'),
  202. summary=_('Get application details'),
  203. operation_id=_('Get application details'), # type: ignore
  204. parameters=ApplicationOperateAPI.get_parameters(),
  205. request=ApplicationEditAPI.get_request(),
  206. responses=result.DefaultResultSerializer,
  207. tags=[_('Application')] # type: ignore
  208. )
  209. @has_permissions(PermissionConstants.APPLICATION_READ.get_workspace_application_permission(),
  210. PermissionConstants.APPLICATION_READ.get_workspace_permission_workspace_manage_role(),
  211. ViewPermission([RoleConstants.USER.get_workspace_role()],
  212. [PermissionConstants.APPLICATION.get_workspace_application_permission()],
  213. CompareConstants.AND),
  214. RoleConstants.WORKSPACE_MANAGE.get_workspace_role())
  215. def get(self, request: Request, workspace_id: str, application_id: str):
  216. return result.success(ApplicationOperateSerializer(
  217. data={'application_id': application_id, 'user_id': request.user.id,
  218. 'workspace_id': workspace_id, }).one())
  219. class Move(APIView):
  220. authentication_classes = [TokenAuth]
  221. @extend_schema(
  222. methods=['PUT'],
  223. description=_("Move an application"),
  224. summary=_("Move an application"),
  225. operation_id=_("Move an application"), # type: ignore
  226. parameters=ApplicationOperateAPI.get_parameters(),
  227. request=None,
  228. responses=result.DefaultResultSerializer,
  229. tags=[_('Application')] # type: ignore
  230. )
  231. @has_permissions(PermissionConstants.APPLICATION_EDIT.get_workspace_application_permission(),
  232. PermissionConstants.APPLICATION_EDIT.get_workspace_permission_workspace_manage_role(),
  233. ViewPermission([RoleConstants.USER.get_workspace_role()],
  234. [PermissionConstants.APPLICATION.get_workspace_application_permission()],
  235. CompareConstants.AND),
  236. RoleConstants.WORKSPACE_MANAGE.get_workspace_role())
  237. @log(menu='Application', operate='Move an application',
  238. get_operation_object=lambda r, k: get_application_operation_object(k.get('application_id')))
  239. def put(self, request: Request, workspace_id: str, application_id: str, folder_id: str):
  240. return result.success(
  241. ApplicationOperateSerializer(
  242. data={'application_id': application_id, 'user_id': request.user.id,
  243. 'workspace_id': workspace_id, }).move(folder_id))
  244. class Publish(APIView):
  245. authentication_classes = [TokenAuth]
  246. @extend_schema(
  247. methods=['PUT'],
  248. description=_("Publishing an application"),
  249. summary=_("Publishing an application"),
  250. operation_id=_("Publishing an application"), # type: ignore
  251. parameters=ApplicationOperateAPI.get_parameters(),
  252. request=None,
  253. responses=result.DefaultResultSerializer,
  254. tags=[_('Application')] # type: ignore
  255. )
  256. @has_permissions(PermissionConstants.APPLICATION_EDIT.get_workspace_application_permission(),
  257. PermissionConstants.APPLICATION_EDIT.get_workspace_permission_workspace_manage_role(),
  258. ViewPermission([RoleConstants.USER.get_workspace_role()],
  259. [PermissionConstants.APPLICATION.get_workspace_application_permission()],
  260. CompareConstants.AND),
  261. RoleConstants.WORKSPACE_MANAGE.get_workspace_role())
  262. @log(menu='Application', operate='Publishing an application',
  263. get_operation_object=lambda r, k: get_application_operation_object(k.get('application_id')))
  264. def put(self, request: Request, workspace_id: str, application_id: str):
  265. return result.success(
  266. ApplicationOperateSerializer(
  267. data={'application_id': application_id, 'user_id': request.user.id,
  268. 'workspace_id': workspace_id, }).publish(request.data))
  269. class StoreApplication(APIView):
  270. authentication_classes = [TokenAuth]
  271. @extend_schema(
  272. methods=['GET'],
  273. description=_("Get Appstore apps"),
  274. summary=_("Get Appstore apps"),
  275. operation_id=_("Get Appstore apps"), # type: ignore
  276. responses=GetInternalToolAPI.get_response(),
  277. tags=[_("Application")] # type: ignore
  278. )
  279. def get(self, request: Request):
  280. return result.success(ApplicationSerializer.StoreApplication(data={
  281. 'user_id': request.user.id,
  282. 'name': request.query_params.get('name', ''),
  283. }).get_appstore_templates())
  284. class BatchDelete(APIView):
  285. authentication_classes = [TokenAuth]
  286. @extend_schema(
  287. methods=['PUT'],
  288. description=_("Batch delete applications"),
  289. summary=_("Batch delete applications"),
  290. operation_id=_("Batch delete applications"),
  291. parameters=ApplicationBatchOperateAPI.get_parameters(),
  292. request=ApplicationBatchOperateAPI.get_request(),
  293. responses=result.DefaultResultSerializer,
  294. tags=[_('Application')]
  295. )
  296. @has_permissions(PermissionConstants.APPLICATION_BATCH_DELETE.get_workspace_permission(),
  297. RoleConstants.USER.get_workspace_role(),
  298. RoleConstants.WORKSPACE_MANAGE.get_workspace_role()
  299. )
  300. def put(self, request: Request, workspace_id: str):
  301. id_list = request.data.get('id_list', [])
  302. permitted_ids = check_batch_permissions(
  303. request, id_list, 'application_id',
  304. (PermissionConstants.APPLICATION_DELETE.get_workspace_application_permission(),
  305. PermissionConstants.APPLICATION_DELETE.get_workspace_permission_workspace_manage_role(),
  306. ViewPermission([RoleConstants.USER.get_workspace_role()],
  307. [PermissionConstants.APPLICATION.get_workspace_application_permission()],
  308. CompareConstants.AND),
  309. RoleConstants.WORKSPACE_MANAGE.get_workspace_role()), workspace_id=workspace_id
  310. )
  311. @log(menu='Application', operate='Batch delete applications',
  312. get_operation_object=lambda r, k: get_application_operation_object_batch(permitted_ids))
  313. def inner(view,r, **kwargs):
  314. return ApplicationBatchOperateSerializer(
  315. data={'workspace_id': workspace_id, 'user_id': request.user.id}
  316. ).batch_delete({'id_list': permitted_ids})
  317. return result.success(inner(self,request, workspace_id=workspace_id))
  318. class BatchMove(APIView):
  319. authentication_classes = [TokenAuth]
  320. @extend_schema(
  321. methods=['PUT'],
  322. description=_("Batch move applications"),
  323. summary=_("Batch move applications"),
  324. operation_id=_("Batch move applications"),
  325. parameters=ApplicationBatchOperateAPI.get_parameters(),
  326. request=ApplicationBatchOperateAPI.get_move_request(),
  327. responses=result.DefaultResultSerializer,
  328. tags=[_('Application')]
  329. )
  330. @has_permissions(PermissionConstants.APPLICATION_BATCH_MOVE.get_workspace_permission(),
  331. RoleConstants.USER.get_workspace_role(),
  332. RoleConstants.WORKSPACE_MANAGE.get_workspace_role()
  333. )
  334. def put(self, request: Request, workspace_id: str):
  335. id_list = request.data.get('id_list', [])
  336. permitted_ids = check_batch_permissions(
  337. request, id_list, 'application_id',
  338. (PermissionConstants.APPLICATION_EDIT.get_workspace_application_permission(),
  339. PermissionConstants.APPLICATION_EDIT.get_workspace_permission_workspace_manage_role(),
  340. ViewPermission([RoleConstants.USER.get_workspace_role()],
  341. [PermissionConstants.APPLICATION.get_workspace_application_permission()],
  342. CompareConstants.AND),
  343. RoleConstants.WORKSPACE_MANAGE.get_workspace_role()),
  344. workspace_id=workspace_id
  345. )
  346. @log(menu='Application', operate='Batch move applications',
  347. get_operation_object=lambda r, k: get_application_operation_object_batch(permitted_ids))
  348. def inner(view,r, **kwargs):
  349. return ApplicationBatchOperateSerializer(
  350. data={'workspace_id': workspace_id, 'user_id': request.user.id}
  351. ).batch_move({'id_list': permitted_ids, 'folder_id': request.data.get('folder_id')})
  352. return result.success(inner(self,request, workspace_id=workspace_id))
  353. class McpServers(APIView):
  354. authentication_classes = [TokenAuth]
  355. @extend_schema(
  356. methods=['GET'],
  357. description=_("speech to text"),
  358. summary=_("speech to text"),
  359. operation_id=_("speech to text"), # type: ignore
  360. parameters=SpeechToTextAPI.get_parameters(),
  361. request=SpeechToTextAPI.get_request(),
  362. responses=SpeechToTextAPI.get_response(),
  363. tags=[_('Application')] # type: ignore
  364. )
  365. @has_permissions(PermissionConstants.APPLICATION_READ.get_workspace_application_permission(),
  366. PermissionConstants.APPLICATION_READ.get_workspace_permission_workspace_manage_role(),
  367. ViewPermission([RoleConstants.USER.get_workspace_role()],
  368. [PermissionConstants.APPLICATION.get_workspace_application_permission()],
  369. CompareConstants.AND),
  370. RoleConstants.WORKSPACE_MANAGE.get_workspace_role())
  371. def post(self, request: Request, workspace_id, application_id: str):
  372. return result.success(ApplicationOperateSerializer(
  373. data={'mcp_servers': request.query_params.get('mcp_servers'), 'workspace_id': workspace_id,
  374. 'user_id': request.user.id,
  375. 'application_id': application_id}).get_mcp_servers(request.data))
  376. class SpeechToText(APIView):
  377. authentication_classes = [TokenAuth]
  378. @extend_schema(
  379. methods=['POST'],
  380. description=_("speech to text"),
  381. summary=_("speech to text"),
  382. operation_id=_("speech to text"), # type: ignore
  383. parameters=SpeechToTextAPI.get_parameters(),
  384. request=SpeechToTextAPI.get_request(),
  385. responses=SpeechToTextAPI.get_response(),
  386. tags=[_('Application')] # type: ignore
  387. )
  388. @has_permissions(PermissionConstants.APPLICATION_EDIT.get_workspace_application_permission(),
  389. PermissionConstants.APPLICATION_EDIT.get_workspace_permission_workspace_manage_role(),
  390. ViewPermission([RoleConstants.USER.get_workspace_role()],
  391. [PermissionConstants.APPLICATION.get_workspace_application_permission()],
  392. CompareConstants.AND),
  393. RoleConstants.WORKSPACE_MANAGE.get_workspace_role())
  394. def post(self, request: Request, workspace_id: str, application_id: str):
  395. return result.success(
  396. ApplicationOperateSerializer(
  397. data={'application_id': application_id, 'workspace_id': workspace_id, 'user_id': request.user.id})
  398. .speech_to_text({'file': request.FILES.get('file')}))
  399. class TextToSpeech(APIView):
  400. authentication_classes = [TokenAuth]
  401. @extend_schema(
  402. methods=['POST'],
  403. description=_("text to speech"),
  404. summary=_("text to speech"),
  405. operation_id=_("text to speech"), # type: ignore
  406. parameters=TextToSpeechAPI.get_parameters(),
  407. request=TextToSpeechAPI.get_request(),
  408. responses=TextToSpeechAPI.get_response(),
  409. tags=[_('Application')] # type: ignore
  410. )
  411. @has_permissions(PermissionConstants.APPLICATION_EDIT.get_workspace_application_permission(),
  412. PermissionConstants.APPLICATION_EDIT.get_workspace_permission_workspace_manage_role(),
  413. ViewPermission([RoleConstants.USER.get_workspace_role()],
  414. [PermissionConstants.APPLICATION.get_workspace_application_permission()],
  415. CompareConstants.AND),
  416. RoleConstants.WORKSPACE_MANAGE.get_workspace_role())
  417. def post(self, request: Request, workspace_id: str, application_id: str):
  418. byte_data = ApplicationOperateSerializer(
  419. data={'application_id': application_id, 'workspace_id': workspace_id,
  420. 'user_id': request.user.id}).text_to_speech(request.data)
  421. return HttpResponse(byte_data, status=200, headers={'Content-Type': 'audio/mp3',
  422. 'Content-Disposition': 'attachment; filename="abc.mp3"'})
  423. class PlayDemoText(APIView):
  424. authentication_classes = [TokenAuth]
  425. @extend_schema(
  426. methods=['POST'],
  427. description=_("PlayDemo"),
  428. summary=_("PlayDemo"),
  429. operation_id=_("PlayDemo"), # type: ignore
  430. parameters=PlayDemoTextAPI.get_parameters(),
  431. request=PlayDemoTextAPI.get_request(),
  432. responses=PlayDemoTextAPI.get_response(),
  433. tags=[_('Application')] # type: ignore
  434. )
  435. @has_permissions(PermissionConstants.APPLICATION_EDIT.get_workspace_application_permission(),
  436. PermissionConstants.APPLICATION_EDIT.get_workspace_permission_workspace_manage_role(),
  437. ViewPermission([RoleConstants.USER.get_workspace_role()],
  438. [PermissionConstants.APPLICATION.get_workspace_application_permission()],
  439. CompareConstants.AND),
  440. RoleConstants.WORKSPACE_MANAGE.get_workspace_role())
  441. @log(menu='Application', operate="trial listening",
  442. get_operation_object=lambda r, k: get_application_operation_object(k.get('application_id')))
  443. def post(self, request: Request, workspace_id: str, application_id: str):
  444. byte_data = ApplicationOperateSerializer(
  445. data={'application_id': application_id, 'workspace_id': workspace_id,
  446. 'user_id': request.user.id}).play_demo_text(request.data)
  447. return HttpResponse(byte_data, status=200, headers={'Content-Type': 'audio/mp3',
  448. 'Content-Disposition': 'attachment; filename="abc.mp3"'})