feat: http download file

This commit is contained in:
Yeuoly 2024-03-18 21:16:21 +08:00
parent 9175eb455f
commit fed19db938
No known key found for this signature in database
GPG Key ID: A66E7E320FB19F61
3 changed files with 81 additions and 8 deletions

View File

@ -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)}')

View File

@ -0,0 +1,2 @@
class HttpFileTransformer:
pass

View File

@ -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