mirror of https://github.com/langgenius/dify.git
feat: http download file
This commit is contained in:
parent
9175eb455f
commit
fed19db938
|
|
@ -15,9 +15,9 @@ HTTP_REQUEST_DEFAULT_TIMEOUT = (10, 60)
|
|||
class HttpExecutorResponse:
|
||||
status_code: int
|
||||
headers: dict[str, str]
|
||||
body: str
|
||||
body: bytes
|
||||
|
||||
def __init__(self, status_code: int, headers: dict[str, str], body: str):
|
||||
def __init__(self, status_code: int, headers: dict[str, str], body: bytes):
|
||||
"""
|
||||
init
|
||||
"""
|
||||
|
|
@ -25,6 +25,34 @@ class HttpExecutorResponse:
|
|||
self.headers = headers
|
||||
self.body = body
|
||||
|
||||
def get_content_type(self) -> str:
|
||||
"""
|
||||
get content type
|
||||
"""
|
||||
for key, val in self.headers.items():
|
||||
if key.lower() == 'content-type':
|
||||
return val
|
||||
return ''
|
||||
|
||||
def extract_file(self) -> tuple[str, bytes]:
|
||||
"""
|
||||
extract file from response if content type is file related
|
||||
"""
|
||||
content_type = self.get_content_type()
|
||||
file_content_types = ['image', 'audio', 'video']
|
||||
for v in file_content_types:
|
||||
if v in content_type:
|
||||
return content_type, self.body
|
||||
|
||||
return '', b''
|
||||
|
||||
@property
|
||||
def content(self) -> str:
|
||||
"""
|
||||
get content
|
||||
"""
|
||||
return self.body.decode('utf-8')
|
||||
|
||||
class HttpExecutor:
|
||||
server_url: str
|
||||
method: str
|
||||
|
|
@ -192,14 +220,14 @@ class HttpExecutor:
|
|||
for k, v in response.headers.items():
|
||||
headers[k] = v
|
||||
|
||||
return HttpExecutorResponse(response.status_code, headers, response.text)
|
||||
return HttpExecutorResponse(response.status_code, headers, response.content)
|
||||
elif isinstance(response, requests.Response):
|
||||
# get key-value pairs headers
|
||||
headers = {}
|
||||
for k, v in response.headers.items():
|
||||
headers[k] = v
|
||||
|
||||
return HttpExecutorResponse(response.status_code, headers, response.text)
|
||||
return HttpExecutorResponse(response.status_code, headers, response.content)
|
||||
else:
|
||||
raise ValueError(f'Invalid response type {type(response)}')
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,2 @@
|
|||
class HttpFileTransformer:
|
||||
pass
|
||||
|
|
@ -1,10 +1,14 @@
|
|||
from mimetypes import guess_extension
|
||||
from os import path
|
||||
from typing import cast
|
||||
|
||||
from core.file.file_obj import FileTransferMethod, FileType, FileVar
|
||||
from core.tools.tool_file_manager import ToolFileManager
|
||||
from core.workflow.entities.node_entities import NodeRunResult, NodeType
|
||||
from core.workflow.entities.variable_pool import VariablePool
|
||||
from core.workflow.nodes.base_node import BaseNode
|
||||
from core.workflow.nodes.http_request.entities import HttpRequestNodeData
|
||||
from core.workflow.nodes.http_request.http_executor import HttpExecutor
|
||||
from core.workflow.nodes.http_request.http_executor import HttpExecutor, HttpExecutorResponse
|
||||
from models.workflow import WorkflowNodeExecutionStatus
|
||||
|
||||
|
||||
|
|
@ -33,17 +37,20 @@ class HttpRequestNode(BaseNode):
|
|||
inputs=variables,
|
||||
error=str(e),
|
||||
process_data={
|
||||
'request': http_executor.to_raw_request()
|
||||
'request': http_executor.to_raw_request(),
|
||||
}
|
||||
)
|
||||
|
||||
files = self.extract_files(http_executor.server_url, response)
|
||||
|
||||
return NodeRunResult(
|
||||
status=WorkflowNodeExecutionStatus.SUCCEEDED,
|
||||
inputs=variables,
|
||||
outputs={
|
||||
'status_code': response.status_code,
|
||||
'body': response.body,
|
||||
'headers': response.headers
|
||||
'body': response.content if not files else '',
|
||||
'headers': response.headers,
|
||||
'files': files,
|
||||
},
|
||||
process_data={
|
||||
'request': http_executor.to_raw_request(),
|
||||
|
|
@ -61,3 +68,39 @@ class HttpRequestNode(BaseNode):
|
|||
return {
|
||||
variable_selector.variable: variable_selector.value_selector for variable_selector in node_data.variables
|
||||
}
|
||||
|
||||
def extract_files(self, url: str, response: HttpExecutorResponse) -> list[FileVar]:
|
||||
"""
|
||||
Extract files from response
|
||||
"""
|
||||
files = []
|
||||
mimetype, file_binary = response.extract_file()
|
||||
# if not image, return directly
|
||||
if 'image' not in mimetype:
|
||||
return files
|
||||
|
||||
if mimetype:
|
||||
# extract filename from url
|
||||
filename = path.basename(url)
|
||||
# extract extension if possible
|
||||
extension = guess_extension(mimetype) or '.bin'
|
||||
|
||||
tool_file = ToolFileManager.create_file_by_raw(
|
||||
user_id=self.user_id,
|
||||
tenant_id=self.tenant_id,
|
||||
conversation_id=None,
|
||||
file_binary=file_binary,
|
||||
mimetype=mimetype,
|
||||
)
|
||||
|
||||
files.append(FileVar(
|
||||
tenant_id=self.tenant_id,
|
||||
type=FileType.IMAGE,
|
||||
transfer_method=FileTransferMethod.TOOL_FILE,
|
||||
related_id=tool_file.id,
|
||||
filename=filename,
|
||||
extension=extension,
|
||||
mime_type=mimetype,
|
||||
))
|
||||
|
||||
return files
|
||||
Loading…
Reference in New Issue