dify-oapi2 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- dify_oapi/__init__.py +0 -0
- dify_oapi/api/__init__.py +0 -0
- dify_oapi/api/chat/__init__.py +0 -0
- dify_oapi/api/chat/service.py +8 -0
- dify_oapi/api/chat/v1/__init__.py +0 -0
- dify_oapi/api/chat/v1/model/__init__.py +0 -0
- dify_oapi/api/chat/v1/model/audio_to_text_request.py +40 -0
- dify_oapi/api/chat/v1/model/audio_to_text_request_body.py +23 -0
- dify_oapi/api/chat/v1/model/audio_to_text_response.py +5 -0
- dify_oapi/api/chat/v1/model/chat_request.py +32 -0
- dify_oapi/api/chat/v1/model/chat_request_body.py +57 -0
- dify_oapi/api/chat/v1/model/chat_request_file.py +46 -0
- dify_oapi/api/chat/v1/model/chat_response.py +19 -0
- dify_oapi/api/chat/v1/model/delete_conversation_request.py +38 -0
- dify_oapi/api/chat/v1/model/delete_conversation_request_body.py +23 -0
- dify_oapi/api/chat/v1/model/delete_conversation_response.py +5 -0
- dify_oapi/api/chat/v1/model/get_conversation_list_request.py +48 -0
- dify_oapi/api/chat/v1/model/get_conversation_list_response.py +21 -0
- dify_oapi/api/chat/v1/model/message_history_request.py +48 -0
- dify_oapi/api/chat/v1/model/message_history_response.py +49 -0
- dify_oapi/api/chat/v1/model/message_suggested_request.py +36 -0
- dify_oapi/api/chat/v1/model/message_suggested_response.py +6 -0
- dify_oapi/api/chat/v1/model/rename_conversation_request.py +38 -0
- dify_oapi/api/chat/v1/model/rename_conversation_request_body.py +33 -0
- dify_oapi/api/chat/v1/model/rename_conversation_response.py +11 -0
- dify_oapi/api/chat/v1/model/stop_chat_request.py +38 -0
- dify_oapi/api/chat/v1/model/stop_chat_request_body.py +23 -0
- dify_oapi/api/chat/v1/model/stop_chat_response.py +5 -0
- dify_oapi/api/chat/v1/resource/__init__.py +4 -0
- dify_oapi/api/chat/v1/resource/audio.py +17 -0
- dify_oapi/api/chat/v1/resource/chat.py +68 -0
- dify_oapi/api/chat/v1/resource/conversation.py +59 -0
- dify_oapi/api/chat/v1/resource/message.py +35 -0
- dify_oapi/api/chat/v1/version.py +11 -0
- dify_oapi/api/completion/__init__.py +0 -0
- dify_oapi/api/completion/service.py +8 -0
- dify_oapi/api/completion/v1/__init__.py +0 -0
- dify_oapi/api/completion/v1/model/__init__.py +0 -0
- dify_oapi/api/completion/v1/model/completion_request.py +34 -0
- dify_oapi/api/completion/v1/model/completion_request_body.py +43 -0
- dify_oapi/api/completion/v1/model/completion_request_body_input.py +38 -0
- dify_oapi/api/completion/v1/model/completion_request_file.py +49 -0
- dify_oapi/api/completion/v1/model/completion_response.py +18 -0
- dify_oapi/api/completion/v1/model/stop_completion_request.py +38 -0
- dify_oapi/api/completion/v1/model/stop_completion_request_body.py +23 -0
- dify_oapi/api/completion/v1/model/stop_completion_response.py +5 -0
- dify_oapi/api/completion/v1/resource/__init__.py +1 -0
- dify_oapi/api/completion/v1/resource/completion.py +84 -0
- dify_oapi/api/completion/v1/version.py +8 -0
- dify_oapi/api/dify/__init__.py +0 -0
- dify_oapi/api/dify/service.py +8 -0
- dify_oapi/api/dify/v1/__init__.py +0 -0
- dify_oapi/api/dify/v1/model/__init__.py +0 -0
- dify_oapi/api/dify/v1/model/get_info_request.py +30 -0
- dify_oapi/api/dify/v1/model/get_info_response.py +7 -0
- dify_oapi/api/dify/v1/model/get_meta_request.py +30 -0
- dify_oapi/api/dify/v1/model/get_meta_response.py +19 -0
- dify_oapi/api/dify/v1/model/get_parameter_request.py +30 -0
- dify_oapi/api/dify/v1/model/get_parameter_response.py +13 -0
- dify_oapi/api/dify/v1/model/message_feedback_request.py +38 -0
- dify_oapi/api/dify/v1/model/message_feedback_request_body.py +30 -0
- dify_oapi/api/dify/v1/model/message_feedback_response.py +5 -0
- dify_oapi/api/dify/v1/model/text_to_audio_request.py +32 -0
- dify_oapi/api/dify/v1/model/text_to_audio_request_body.py +33 -0
- dify_oapi/api/dify/v1/model/text_to_audio_response.py +4 -0
- dify_oapi/api/dify/v1/model/upload_file_body.py +23 -0
- dify_oapi/api/dify/v1/model/upload_file_request.py +42 -0
- dify_oapi/api/dify/v1/model/upload_file_response.py +11 -0
- dify_oapi/api/dify/v1/resource/__init__.py +6 -0
- dify_oapi/api/dify/v1/resource/audio.py +17 -0
- dify_oapi/api/dify/v1/resource/file.py +17 -0
- dify_oapi/api/dify/v1/resource/info.py +19 -0
- dify_oapi/api/dify/v1/resource/message.py +21 -0
- dify_oapi/api/dify/v1/resource/meta.py +17 -0
- dify_oapi/api/dify/v1/resource/parameter.py +19 -0
- dify_oapi/api/dify/v1/version.py +13 -0
- dify_oapi/api/knowledge_base/__init__.py +0 -0
- dify_oapi/api/knowledge_base/service.py +8 -0
- dify_oapi/api/knowledge_base/v1/__init__.py +0 -0
- dify_oapi/api/knowledge_base/v1/model/__init__.py +0 -0
- dify_oapi/api/knowledge_base/v1/model/dataset/__init__.py +49 -0
- dify_oapi/api/knowledge_base/v1/model/dataset/create_request.py +32 -0
- dify_oapi/api/knowledge_base/v1/model/dataset/create_request_body.py +73 -0
- dify_oapi/api/knowledge_base/v1/model/dataset/create_response.py +11 -0
- dify_oapi/api/knowledge_base/v1/model/dataset/dataset_info.py +150 -0
- dify_oapi/api/knowledge_base/v1/model/dataset/delete_request.py +30 -0
- dify_oapi/api/knowledge_base/v1/model/dataset/delete_response.py +9 -0
- dify_oapi/api/knowledge_base/v1/model/dataset/external_knowledge_info.py +38 -0
- dify_oapi/api/knowledge_base/v1/model/dataset/filter_condition.py +72 -0
- dify_oapi/api/knowledge_base/v1/model/dataset/get_request.py +30 -0
- dify_oapi/api/knowledge_base/v1/model/dataset/get_response.py +11 -0
- dify_oapi/api/knowledge_base/v1/model/dataset/list_request.py +45 -0
- dify_oapi/api/knowledge_base/v1/model/dataset/list_response.py +13 -0
- dify_oapi/api/knowledge_base/v1/model/dataset/metadata_filtering_conditions.py +30 -0
- dify_oapi/api/knowledge_base/v1/model/dataset/reranking_model.py +28 -0
- dify_oapi/api/knowledge_base/v1/model/dataset/retrieval_model.py +147 -0
- dify_oapi/api/knowledge_base/v1/model/dataset/retrieve_request.py +38 -0
- dify_oapi/api/knowledge_base/v1/model/dataset/retrieve_request_body.py +38 -0
- dify_oapi/api/knowledge_base/v1/model/dataset/retrieve_response.py +53 -0
- dify_oapi/api/knowledge_base/v1/model/dataset/update_request.py +38 -0
- dify_oapi/api/knowledge_base/v1/model/dataset/update_request_body.py +58 -0
- dify_oapi/api/knowledge_base/v1/model/dataset/update_response.py +11 -0
- dify_oapi/api/knowledge_base/v1/model/document/__init__.py +0 -0
- dify_oapi/api/knowledge_base/v1/model/document/create_by_file_request.py +53 -0
- dify_oapi/api/knowledge_base/v1/model/document/create_by_file_request_body.py +31 -0
- dify_oapi/api/knowledge_base/v1/model/document/create_by_file_request_body_data.py +78 -0
- dify_oapi/api/knowledge_base/v1/model/document/create_by_file_response.py +12 -0
- dify_oapi/api/knowledge_base/v1/model/document/create_by_text_request.py +38 -0
- dify_oapi/api/knowledge_base/v1/model/document/create_by_text_request_body.py +80 -0
- dify_oapi/api/knowledge_base/v1/model/document/create_by_text_response.py +12 -0
- dify_oapi/api/knowledge_base/v1/model/document/data_source_info.py +30 -0
- dify_oapi/api/knowledge_base/v1/model/document/delete_request.py +38 -0
- dify_oapi/api/knowledge_base/v1/model/document/delete_response.py +9 -0
- dify_oapi/api/knowledge_base/v1/model/document/document_info.py +164 -0
- dify_oapi/api/knowledge_base/v1/model/document/get_request.py +40 -0
- dify_oapi/api/knowledge_base/v1/model/document/get_response.py +9 -0
- dify_oapi/api/knowledge_base/v1/model/document/get_upload_file_request.py +38 -0
- dify_oapi/api/knowledge_base/v1/model/document/get_upload_file_response.py +11 -0
- dify_oapi/api/knowledge_base/v1/model/document/indexing_status_info.py +80 -0
- dify_oapi/api/knowledge_base/v1/model/document/indexing_status_request.py +36 -0
- dify_oapi/api/knowledge_base/v1/model/document/indexing_status_response.py +11 -0
- dify_oapi/api/knowledge_base/v1/model/document/list_request.py +42 -0
- dify_oapi/api/knowledge_base/v1/model/document/list_response.py +15 -0
- dify_oapi/api/knowledge_base/v1/model/document/pre_processing_rule.py +32 -0
- dify_oapi/api/knowledge_base/v1/model/document/process_rule.py +34 -0
- dify_oapi/api/knowledge_base/v1/model/document/retrieval_model.py +54 -0
- dify_oapi/api/knowledge_base/v1/model/document/rules.py +31 -0
- dify_oapi/api/knowledge_base/v1/model/document/segmentation.py +35 -0
- dify_oapi/api/knowledge_base/v1/model/document/subchunk_segmentation.py +35 -0
- dify_oapi/api/knowledge_base/v1/model/document/update_by_file_request.py +53 -0
- dify_oapi/api/knowledge_base/v1/model/document/update_by_file_request_body.py +26 -0
- dify_oapi/api/knowledge_base/v1/model/document/update_by_file_request_body_data.py +40 -0
- dify_oapi/api/knowledge_base/v1/model/document/update_by_file_response.py +12 -0
- dify_oapi/api/knowledge_base/v1/model/document/update_by_text_request.py +55 -0
- dify_oapi/api/knowledge_base/v1/model/document/update_by_text_request_body.py +46 -0
- dify_oapi/api/knowledge_base/v1/model/document/update_by_text_response.py +14 -0
- dify_oapi/api/knowledge_base/v1/model/document/update_status_request.py +55 -0
- dify_oapi/api/knowledge_base/v1/model/document/update_status_request_body.py +32 -0
- dify_oapi/api/knowledge_base/v1/model/document/update_status_response.py +9 -0
- dify_oapi/api/knowledge_base/v1/model/document/upload_file_info.py +65 -0
- dify_oapi/api/knowledge_base/v1/model/metadata/__init__.py +35 -0
- dify_oapi/api/knowledge_base/v1/model/metadata/create_request.py +38 -0
- dify_oapi/api/knowledge_base/v1/model/metadata/create_request_body.py +31 -0
- dify_oapi/api/knowledge_base/v1/model/metadata/create_response.py +13 -0
- dify_oapi/api/knowledge_base/v1/model/metadata/delete_request.py +36 -0
- dify_oapi/api/knowledge_base/v1/model/metadata/delete_response.py +7 -0
- dify_oapi/api/knowledge_base/v1/model/metadata/list_request.py +30 -0
- dify_oapi/api/knowledge_base/v1/model/metadata/list_response.py +9 -0
- dify_oapi/api/knowledge_base/v1/model/metadata/metadata_info.py +38 -0
- dify_oapi/api/knowledge_base/v1/model/metadata/toggle_builtin_request.py +36 -0
- dify_oapi/api/knowledge_base/v1/model/metadata/toggle_builtin_response.py +7 -0
- dify_oapi/api/knowledge_base/v1/model/metadata/update_document_request.py +38 -0
- dify_oapi/api/knowledge_base/v1/model/metadata/update_document_request_body.py +79 -0
- dify_oapi/api/knowledge_base/v1/model/metadata/update_document_response.py +7 -0
- dify_oapi/api/knowledge_base/v1/model/metadata/update_request.py +44 -0
- dify_oapi/api/knowledge_base/v1/model/metadata/update_request_body.py +24 -0
- dify_oapi/api/knowledge_base/v1/model/metadata/update_response.py +13 -0
- dify_oapi/api/knowledge_base/v1/model/segment/__init__.py +77 -0
- dify_oapi/api/knowledge_base/v1/model/segment/child_chunk_info.py +88 -0
- dify_oapi/api/knowledge_base/v1/model/segment/create_child_chunk_request.py +52 -0
- dify_oapi/api/knowledge_base/v1/model/segment/create_child_chunk_request_body.py +23 -0
- dify_oapi/api/knowledge_base/v1/model/segment/create_child_chunk_response.py +7 -0
- dify_oapi/api/knowledge_base/v1/model/segment/create_request.py +42 -0
- dify_oapi/api/knowledge_base/v1/model/segment/create_request_body.py +25 -0
- dify_oapi/api/knowledge_base/v1/model/segment/create_response.py +8 -0
- dify_oapi/api/knowledge_base/v1/model/segment/delete_child_chunk_request.py +50 -0
- dify_oapi/api/knowledge_base/v1/model/segment/delete_child_chunk_response.py +5 -0
- dify_oapi/api/knowledge_base/v1/model/segment/delete_request.py +40 -0
- dify_oapi/api/knowledge_base/v1/model/segment/delete_response.py +5 -0
- dify_oapi/api/knowledge_base/v1/model/segment/get_request.py +40 -0
- dify_oapi/api/knowledge_base/v1/model/segment/get_response.py +8 -0
- dify_oapi/api/knowledge_base/v1/model/segment/list_child_chunks_request.py +56 -0
- dify_oapi/api/knowledge_base/v1/model/segment/list_child_chunks_response.py +11 -0
- dify_oapi/api/knowledge_base/v1/model/segment/list_request.py +50 -0
- dify_oapi/api/knowledge_base/v1/model/segment/list_response.py +12 -0
- dify_oapi/api/knowledge_base/v1/model/segment/segment_data.py +43 -0
- dify_oapi/api/knowledge_base/v1/model/segment/segment_info.py +123 -0
- dify_oapi/api/knowledge_base/v1/model/segment/update_child_chunk_request.py +58 -0
- dify_oapi/api/knowledge_base/v1/model/segment/update_child_chunk_request_body.py +23 -0
- dify_oapi/api/knowledge_base/v1/model/segment/update_child_chunk_response.py +7 -0
- dify_oapi/api/knowledge_base/v1/model/segment/update_request.py +48 -0
- dify_oapi/api/knowledge_base/v1/model/segment/update_request_body.py +25 -0
- dify_oapi/api/knowledge_base/v1/model/segment/update_response.py +8 -0
- dify_oapi/api/knowledge_base/v1/model/tag/__init__.py +41 -0
- dify_oapi/api/knowledge_base/v1/model/tag/bind_request.py +32 -0
- dify_oapi/api/knowledge_base/v1/model/tag/bind_request_body.py +29 -0
- dify_oapi/api/knowledge_base/v1/model/tag/bind_response.py +7 -0
- dify_oapi/api/knowledge_base/v1/model/tag/create_request.py +32 -0
- dify_oapi/api/knowledge_base/v1/model/tag/create_request_body.py +24 -0
- dify_oapi/api/knowledge_base/v1/model/tag/create_response.py +16 -0
- dify_oapi/api/knowledge_base/v1/model/tag/delete_request.py +32 -0
- dify_oapi/api/knowledge_base/v1/model/tag/delete_request_body.py +24 -0
- dify_oapi/api/knowledge_base/v1/model/tag/delete_response.py +7 -0
- dify_oapi/api/knowledge_base/v1/model/tag/list_request.py +24 -0
- dify_oapi/api/knowledge_base/v1/model/tag/list_response.py +19 -0
- dify_oapi/api/knowledge_base/v1/model/tag/query_bound_request.py +30 -0
- dify_oapi/api/knowledge_base/v1/model/tag/query_bound_response.py +9 -0
- dify_oapi/api/knowledge_base/v1/model/tag/tag_info.py +38 -0
- dify_oapi/api/knowledge_base/v1/model/tag/unbind_request.py +32 -0
- dify_oapi/api/knowledge_base/v1/model/tag/unbind_request_body.py +29 -0
- dify_oapi/api/knowledge_base/v1/model/tag/unbind_response.py +7 -0
- dify_oapi/api/knowledge_base/v1/model/tag/update_request.py +32 -0
- dify_oapi/api/knowledge_base/v1/model/tag/update_request_body.py +29 -0
- dify_oapi/api/knowledge_base/v1/model/tag/update_response.py +19 -0
- dify_oapi/api/knowledge_base/v1/resource/__init__.py +7 -0
- dify_oapi/api/knowledge_base/v1/resource/dataset.py +58 -0
- dify_oapi/api/knowledge_base/v1/resource/document.py +107 -0
- dify_oapi/api/knowledge_base/v1/resource/metadata.py +65 -0
- dify_oapi/api/knowledge_base/v1/resource/segment.py +110 -0
- dify_oapi/api/knowledge_base/v1/resource/tag.py +65 -0
- dify_oapi/api/knowledge_base/v1/version.py +12 -0
- dify_oapi/api/workflow/__init__.py +0 -0
- dify_oapi/api/workflow/service.py +8 -0
- dify_oapi/api/workflow/v1/__init__.py +0 -0
- dify_oapi/api/workflow/v1/model/__init__.py +0 -0
- dify_oapi/api/workflow/v1/model/get_workflow_log_request.py +50 -0
- dify_oapi/api/workflow/v1/model/get_workflow_log_response.py +42 -0
- dify_oapi/api/workflow/v1/model/get_workflow_result_request.py +30 -0
- dify_oapi/api/workflow/v1/model/get_workflow_result_response.py +17 -0
- dify_oapi/api/workflow/v1/model/run_workflow_request.py +32 -0
- dify_oapi/api/workflow/v1/model/run_workflow_request_body.py +42 -0
- dify_oapi/api/workflow/v1/model/run_workflow_request_file.py +50 -0
- dify_oapi/api/workflow/v1/model/run_workflow_response.py +24 -0
- dify_oapi/api/workflow/v1/model/stop_workflow_request.py +38 -0
- dify_oapi/api/workflow/v1/model/stop_workflow_request_body.py +23 -0
- dify_oapi/api/workflow/v1/model/stop_workflow_response.py +5 -0
- dify_oapi/api/workflow/v1/resource/__init__.py +1 -0
- dify_oapi/api/workflow/v1/resource/workflow.py +102 -0
- dify_oapi/api/workflow/v1/version.py +8 -0
- dify_oapi/client.py +97 -0
- dify_oapi/core/__init__.py +0 -0
- dify_oapi/core/const.py +15 -0
- dify_oapi/core/enum.py +21 -0
- dify_oapi/core/http/__init__.py +0 -0
- dify_oapi/core/http/transport/__init__.py +4 -0
- dify_oapi/core/http/transport/_misc.py +145 -0
- dify_oapi/core/http/transport/async_transport.py +217 -0
- dify_oapi/core/http/transport/sync_transport.py +220 -0
- dify_oapi/core/json.py +61 -0
- dify_oapi/core/log.py +8 -0
- dify_oapi/core/misc.py +41 -0
- dify_oapi/core/model/__init__.py +0 -0
- dify_oapi/core/model/base_request.py +21 -0
- dify_oapi/core/model/base_response.py +27 -0
- dify_oapi/core/model/config.py +9 -0
- dify_oapi/core/model/raw_request.py +5 -0
- dify_oapi/core/model/raw_response.py +17 -0
- dify_oapi/core/model/request_option.py +27 -0
- dify_oapi/core/type.py +5 -0
- dify_oapi/core/utils/__init__.py +0 -0
- dify_oapi/core/utils/strings.py +8 -0
- dify_oapi2-0.1.0.dist-info/LICENSE +21 -0
- dify_oapi2-0.1.0.dist-info/METADATA +295 -0
- dify_oapi2-0.1.0.dist-info/RECORD +255 -0
- dify_oapi2-0.1.0.dist-info/WHEEL +4 -0
@@ -0,0 +1,220 @@
|
|
1
|
+
import json
|
2
|
+
import os
|
3
|
+
import time
|
4
|
+
from collections.abc import Generator
|
5
|
+
from typing import Literal, overload
|
6
|
+
|
7
|
+
import httpx
|
8
|
+
|
9
|
+
from dify_oapi.core.enum import HttpMethod
|
10
|
+
from dify_oapi.core.json import JSON
|
11
|
+
from dify_oapi.core.log import logger
|
12
|
+
from dify_oapi.core.model.base_request import BaseRequest
|
13
|
+
from dify_oapi.core.model.base_response import BaseResponse
|
14
|
+
from dify_oapi.core.model.config import Config
|
15
|
+
from dify_oapi.core.model.raw_response import RawResponse
|
16
|
+
from dify_oapi.core.model.request_option import RequestOption
|
17
|
+
from dify_oapi.core.type import T
|
18
|
+
|
19
|
+
from ._misc import _build_header, _build_url, _get_sleep_time, _merge_dicts, _unmarshaller
|
20
|
+
|
21
|
+
|
22
|
+
def _format_log_details(
|
23
|
+
method: str, url: str, headers: dict, queries: list[tuple[str, str]] | dict, body_data: dict | None
|
24
|
+
) -> str:
|
25
|
+
"""Format log details"""
|
26
|
+
details = [f"{method} {url}"]
|
27
|
+
if headers:
|
28
|
+
details.append(f"headers: {JSON.marshal(headers)}")
|
29
|
+
if queries:
|
30
|
+
queries_dict = dict(queries) if isinstance(queries, list) else queries
|
31
|
+
details.append(f"params: {JSON.marshal(queries_dict)}")
|
32
|
+
if body_data:
|
33
|
+
details.append(f"body: {JSON.marshal(body_data)}")
|
34
|
+
return ", ".join(details)
|
35
|
+
|
36
|
+
|
37
|
+
def _handle_stream_error(response: httpx.Response) -> bytes:
|
38
|
+
"""Handle streaming response errors"""
|
39
|
+
try:
|
40
|
+
error_detail = response.read()
|
41
|
+
error_message = error_detail.decode("utf-8", errors="ignore").strip()
|
42
|
+
except Exception:
|
43
|
+
error_message = f"Error response with status code {response.status_code}"
|
44
|
+
logger.warning(f"Streaming request failed: {response.status_code}, detail: {error_message}")
|
45
|
+
return f"data: [ERROR] {error_message}\n\n".encode()
|
46
|
+
|
47
|
+
|
48
|
+
def _stream_generator(
|
49
|
+
conf: Config,
|
50
|
+
req: BaseRequest,
|
51
|
+
*,
|
52
|
+
url: str,
|
53
|
+
headers: dict[str, str],
|
54
|
+
json_: dict | None,
|
55
|
+
data: dict | None,
|
56
|
+
files: dict | None,
|
57
|
+
http_method: HttpMethod,
|
58
|
+
) -> Generator[bytes, None, None]:
|
59
|
+
method_name = http_method.name
|
60
|
+
body_data = _merge_dicts(json_, files, data)
|
61
|
+
|
62
|
+
for retry in range(conf.max_retry_count + 1):
|
63
|
+
if retry > 0:
|
64
|
+
sleep_time = _get_sleep_time(retry)
|
65
|
+
logger.info(f"in-request: sleep {sleep_time}s")
|
66
|
+
time.sleep(sleep_time)
|
67
|
+
|
68
|
+
try:
|
69
|
+
with (
|
70
|
+
httpx.Client() as client,
|
71
|
+
client.stream(
|
72
|
+
method_name,
|
73
|
+
url,
|
74
|
+
headers=headers,
|
75
|
+
params=tuple(req.queries),
|
76
|
+
json=json_,
|
77
|
+
data=data,
|
78
|
+
files=files,
|
79
|
+
timeout=conf.timeout,
|
80
|
+
) as response,
|
81
|
+
):
|
82
|
+
logger.debug(
|
83
|
+
f"{_format_log_details(method_name, url, headers, req.queries, body_data)}, stream response"
|
84
|
+
)
|
85
|
+
|
86
|
+
if response.status_code != 200:
|
87
|
+
yield _handle_stream_error(response)
|
88
|
+
return
|
89
|
+
|
90
|
+
try:
|
91
|
+
yield from response.iter_bytes()
|
92
|
+
except Exception as e:
|
93
|
+
logger.exception("Streaming failed during chunk reading")
|
94
|
+
yield f"data: [ERROR] Stream interrupted: {str(e)}\n\n".encode()
|
95
|
+
return
|
96
|
+
|
97
|
+
except httpx.RequestError as e:
|
98
|
+
err_msg = f"{e.__class__.__name__}: {e!r}"
|
99
|
+
log_details = _format_log_details(method_name, url, headers, req.queries, body_data)
|
100
|
+
|
101
|
+
if retry < conf.max_retry_count:
|
102
|
+
logger.info(f"in-request: retrying ({retry + 1}/{conf.max_retry_count}) {log_details}, exp: {err_msg}")
|
103
|
+
continue
|
104
|
+
logger.info(
|
105
|
+
f"in-request: request failed, retried ({retry}/{conf.max_retry_count}) {log_details}, exp: {err_msg}"
|
106
|
+
)
|
107
|
+
raise
|
108
|
+
|
109
|
+
|
110
|
+
class Transport:
|
111
|
+
@staticmethod
|
112
|
+
@overload
|
113
|
+
def execute(
|
114
|
+
conf: Config,
|
115
|
+
req: BaseRequest,
|
116
|
+
*,
|
117
|
+
stream: Literal[True],
|
118
|
+
option: RequestOption | None,
|
119
|
+
) -> Generator[bytes, None, None]: ...
|
120
|
+
|
121
|
+
@staticmethod
|
122
|
+
@overload
|
123
|
+
def execute(conf: Config, req: BaseRequest) -> BaseResponse: ...
|
124
|
+
|
125
|
+
@staticmethod
|
126
|
+
@overload
|
127
|
+
def execute(conf: Config, req: BaseRequest, *, option: RequestOption | None) -> BaseResponse: ...
|
128
|
+
|
129
|
+
@staticmethod
|
130
|
+
@overload
|
131
|
+
def execute(
|
132
|
+
conf: Config,
|
133
|
+
req: BaseRequest,
|
134
|
+
*,
|
135
|
+
unmarshal_as: type[T],
|
136
|
+
option: RequestOption | None,
|
137
|
+
) -> T: ...
|
138
|
+
|
139
|
+
@staticmethod
|
140
|
+
def execute(
|
141
|
+
conf: Config,
|
142
|
+
req: BaseRequest,
|
143
|
+
*,
|
144
|
+
stream: bool = False,
|
145
|
+
unmarshal_as: type[T] | type[BaseResponse] | None = None,
|
146
|
+
option: RequestOption | None = None,
|
147
|
+
):
|
148
|
+
unmarshal_as = unmarshal_as or BaseResponse
|
149
|
+
option = option or RequestOption()
|
150
|
+
|
151
|
+
if req.http_method is None:
|
152
|
+
raise RuntimeError("HTTP method is required")
|
153
|
+
|
154
|
+
url = _build_url(conf.domain, req.uri, req.paths)
|
155
|
+
headers = _build_header(req, option)
|
156
|
+
|
157
|
+
# Prepare request body
|
158
|
+
json_, files, data = None, None, None
|
159
|
+
if req.files:
|
160
|
+
files = req.files
|
161
|
+
if req.body is not None:
|
162
|
+
data = json.loads(JSON.marshal(req.body))
|
163
|
+
elif req.body is not None:
|
164
|
+
json_ = json.loads(JSON.marshal(req.body))
|
165
|
+
|
166
|
+
if stream:
|
167
|
+
return _stream_generator(
|
168
|
+
conf, req, url=url, headers=headers, json_=json_, data=data, files=files, http_method=req.http_method
|
169
|
+
)
|
170
|
+
|
171
|
+
# Set local proxy
|
172
|
+
original_no_proxy = os.environ.get("NO_PROXY", "")
|
173
|
+
if "localhost" not in original_no_proxy:
|
174
|
+
os.environ["NO_PROXY"] = f"{original_no_proxy},localhost,127.0.0.1".strip(",")
|
175
|
+
|
176
|
+
method_name = req.http_method.name
|
177
|
+
body_data = _merge_dicts(json_, files, data)
|
178
|
+
|
179
|
+
with httpx.Client() as client:
|
180
|
+
for retry in range(conf.max_retry_count + 1):
|
181
|
+
if retry > 0:
|
182
|
+
sleep_time = _get_sleep_time(retry)
|
183
|
+
logger.info(f"in-request: sleep {sleep_time}s")
|
184
|
+
time.sleep(sleep_time)
|
185
|
+
|
186
|
+
try:
|
187
|
+
response = client.request(
|
188
|
+
method_name,
|
189
|
+
url,
|
190
|
+
headers=headers,
|
191
|
+
params=tuple(req.queries),
|
192
|
+
json=json_,
|
193
|
+
data=data,
|
194
|
+
files=files,
|
195
|
+
timeout=conf.timeout,
|
196
|
+
)
|
197
|
+
break
|
198
|
+
except httpx.RequestError as e:
|
199
|
+
err_msg = f"{e.__class__.__name__}: {e!r}"
|
200
|
+
log_details = _format_log_details(method_name, url, headers, req.queries, body_data)
|
201
|
+
|
202
|
+
if retry < conf.max_retry_count:
|
203
|
+
logger.info(
|
204
|
+
f"in-request: retrying ({retry + 1}/{conf.max_retry_count}) {log_details}, exp: {err_msg}"
|
205
|
+
)
|
206
|
+
continue
|
207
|
+
logger.info(
|
208
|
+
f"in-request: request failed, retried ({retry}/{conf.max_retry_count}) {log_details}, exp: {err_msg}"
|
209
|
+
)
|
210
|
+
raise
|
211
|
+
|
212
|
+
logger.debug(
|
213
|
+
f"{_format_log_details(method_name, url, headers, req.queries, body_data)} {response.status_code}"
|
214
|
+
)
|
215
|
+
|
216
|
+
raw_resp = RawResponse()
|
217
|
+
raw_resp.status_code = response.status_code
|
218
|
+
raw_resp.headers = dict(response.headers)
|
219
|
+
raw_resp.content = response.content
|
220
|
+
return _unmarshaller(raw_resp, unmarshal_as)
|
dify_oapi/core/json.py
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
import copy
|
2
|
+
import datetime
|
3
|
+
import io
|
4
|
+
from json import JSONEncoder, dumps, loads
|
5
|
+
from typing import Any, overload
|
6
|
+
|
7
|
+
from .const import UTF_8
|
8
|
+
from .type import T
|
9
|
+
|
10
|
+
|
11
|
+
class JSON:
|
12
|
+
@staticmethod
|
13
|
+
@overload
|
14
|
+
def marshal(obj: None, indent=None) -> None:
|
15
|
+
pass
|
16
|
+
|
17
|
+
@staticmethod
|
18
|
+
@overload
|
19
|
+
def marshal(obj: Any, indent=None) -> str:
|
20
|
+
pass
|
21
|
+
|
22
|
+
@staticmethod
|
23
|
+
def marshal(obj: Any, indent=None) -> str | None:
|
24
|
+
if obj is None:
|
25
|
+
return None
|
26
|
+
return dumps(obj, cls=Encoder, indent=indent, ensure_ascii=False)
|
27
|
+
|
28
|
+
@staticmethod
|
29
|
+
def unmarshal(json_str: str, clazz: type[T]) -> T:
|
30
|
+
dict_obj = loads(json_str)
|
31
|
+
return clazz(**dict_obj)
|
32
|
+
|
33
|
+
|
34
|
+
class Encoder(JSONEncoder):
|
35
|
+
def default(self, o: Any) -> Any:
|
36
|
+
if isinstance(o, io.BufferedReader):
|
37
|
+
return o.__str__()
|
38
|
+
if hasattr(o, "__dict__"):
|
39
|
+
return filter_null(copy.deepcopy(vars(o)))
|
40
|
+
if isinstance(o, datetime.datetime):
|
41
|
+
return o.strftime("%Y-%m-%d %H:%M:%S")
|
42
|
+
if isinstance(o, bytes):
|
43
|
+
return str(o, encoding=UTF_8)
|
44
|
+
if isinstance(o, int):
|
45
|
+
return int(o)
|
46
|
+
if isinstance(o, float):
|
47
|
+
return float(o)
|
48
|
+
if isinstance(o, set):
|
49
|
+
return list(o)
|
50
|
+
return super().default(o)
|
51
|
+
|
52
|
+
|
53
|
+
def filter_null(d: dict) -> dict:
|
54
|
+
if isinstance(d, dict):
|
55
|
+
for k, v in list(d.items()):
|
56
|
+
if isinstance(v, dict):
|
57
|
+
filter_null(v)
|
58
|
+
elif v is None:
|
59
|
+
del d[k]
|
60
|
+
|
61
|
+
return d
|
dify_oapi/core/log.py
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
import logging
|
2
|
+
import sys
|
3
|
+
|
4
|
+
logger = logging.getLogger("Dify")
|
5
|
+
handler = logging.StreamHandler(sys.stdout)
|
6
|
+
handler.setFormatter(logging.Formatter("[Dify] [%(asctime)s] [%(levelname)s] %(message)s"))
|
7
|
+
logger.addHandler(handler)
|
8
|
+
logger.setLevel(logging.WARNING)
|
dify_oapi/core/misc.py
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
from dataclasses import dataclass
|
2
|
+
from typing import Any
|
3
|
+
|
4
|
+
|
5
|
+
@dataclass(frozen=True, slots=False)
|
6
|
+
class HiddenText(str):
|
7
|
+
secret: str
|
8
|
+
redacted: str
|
9
|
+
|
10
|
+
def __new__(cls, secret: str, redacted: str):
|
11
|
+
obj = super().__new__(cls, redacted)
|
12
|
+
return obj
|
13
|
+
|
14
|
+
@property
|
15
|
+
def __dict__(self): # type: ignore[override]
|
16
|
+
return self.__repr__()
|
17
|
+
|
18
|
+
def __repr__(self) -> str:
|
19
|
+
return f"<HiddenText {str(self)!r}>"
|
20
|
+
|
21
|
+
def __str__(self) -> str:
|
22
|
+
return self.redacted
|
23
|
+
|
24
|
+
# This is useful for testing.
|
25
|
+
def __eq__(self, other: Any) -> bool:
|
26
|
+
if not isinstance(other, type(self)):
|
27
|
+
return False
|
28
|
+
|
29
|
+
# The string being used for redaction doesn't also have to match,
|
30
|
+
# just the raw, original string.
|
31
|
+
return self.secret == other.secret
|
32
|
+
|
33
|
+
def encode(self, encoding="utf-8", errors="strict"):
|
34
|
+
# Needed for building as bytes for httpx request
|
35
|
+
# Encode into bytes for transmission over the network.
|
36
|
+
return self.secret.encode(encoding, errors)
|
37
|
+
|
38
|
+
|
39
|
+
# if __name__ == '__main__':
|
40
|
+
# ht = HiddenText("secret", "****")
|
41
|
+
# print(vars(ht), "\n", ht)
|
File without changes
|
@@ -0,0 +1,21 @@
|
|
1
|
+
from typing import Any
|
2
|
+
|
3
|
+
from dify_oapi.core.enum import HttpMethod
|
4
|
+
|
5
|
+
|
6
|
+
class BaseRequest:
|
7
|
+
def __init__(self) -> None:
|
8
|
+
self.http_method: HttpMethod | None = None
|
9
|
+
self.uri: str | None = None
|
10
|
+
self.paths: dict[str, str] = {}
|
11
|
+
self.queries: list[tuple[str, str]] = []
|
12
|
+
self.headers: dict[str, str] = {}
|
13
|
+
self.body: dict = {}
|
14
|
+
self.files: dict | None = None
|
15
|
+
|
16
|
+
def add_query(self, k: str, v: Any) -> None:
|
17
|
+
if isinstance(v, list | tuple):
|
18
|
+
for i in v:
|
19
|
+
self.queries.append((k, str(i)))
|
20
|
+
else:
|
21
|
+
self.queries.append((k, str(v)))
|
@@ -0,0 +1,27 @@
|
|
1
|
+
from pydantic import BaseModel, Field
|
2
|
+
|
3
|
+
from .raw_response import RawResponse
|
4
|
+
|
5
|
+
|
6
|
+
class BaseResponse(BaseModel):
|
7
|
+
raw: RawResponse | None = None
|
8
|
+
code: str | None = Field(default=None, exclude=True)
|
9
|
+
msg_: str | None = Field(default=None, validation_alias="msg", exclude=True)
|
10
|
+
message_: str | None = Field(default=None, validation_alias="message", exclude=True)
|
11
|
+
|
12
|
+
@property
|
13
|
+
def msg(self) -> str | None:
|
14
|
+
if self.msg_ is not None:
|
15
|
+
return self.msg_
|
16
|
+
|
17
|
+
if self.message_ is not None:
|
18
|
+
return self.message_
|
19
|
+
|
20
|
+
if self.raw is not None and self.raw.content is not None:
|
21
|
+
return self.raw.content.decode("utf-8")
|
22
|
+
|
23
|
+
return None
|
24
|
+
|
25
|
+
@property
|
26
|
+
def success(self) -> bool:
|
27
|
+
return self.code is None
|
@@ -0,0 +1,9 @@
|
|
1
|
+
from dify_oapi.core.enum import LogLevel
|
2
|
+
|
3
|
+
|
4
|
+
class Config:
|
5
|
+
def __init__(self):
|
6
|
+
self.domain: str | None = None
|
7
|
+
self.timeout: float | None = None # Client timeout in seconds, default is no timeout
|
8
|
+
self.log_level: LogLevel = LogLevel.WARNING # Log level, default is WARNING
|
9
|
+
self.max_retry_count: int = 3 # Maximum retry count after request failure. Default is 3
|
@@ -0,0 +1,17 @@
|
|
1
|
+
from pydantic import BaseModel, Field
|
2
|
+
|
3
|
+
from dify_oapi.core.const import CONTENT_TYPE
|
4
|
+
|
5
|
+
|
6
|
+
class RawResponse(BaseModel):
|
7
|
+
status_code: int | None = None
|
8
|
+
headers: dict[str, str] = Field(default_factory=dict)
|
9
|
+
content: bytes | None = None
|
10
|
+
|
11
|
+
def set_content_type(self, content_type: str) -> None:
|
12
|
+
self.headers[CONTENT_TYPE] = content_type
|
13
|
+
|
14
|
+
@property
|
15
|
+
def content_type(self) -> str | None:
|
16
|
+
content_type = self.headers.get(CONTENT_TYPE) or self.headers.get(CONTENT_TYPE.lower())
|
17
|
+
return content_type
|
@@ -0,0 +1,27 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
|
4
|
+
class RequestOption:
|
5
|
+
def __init__(self):
|
6
|
+
self.api_key: str | None = None
|
7
|
+
self.headers: dict[str, str] = {}
|
8
|
+
|
9
|
+
@staticmethod
|
10
|
+
def builder() -> RequestOptionBuilder:
|
11
|
+
return RequestOptionBuilder()
|
12
|
+
|
13
|
+
|
14
|
+
class RequestOptionBuilder:
|
15
|
+
def __init__(self) -> None:
|
16
|
+
self._request_option: RequestOption = RequestOption()
|
17
|
+
|
18
|
+
def api_key(self, api_key: str) -> RequestOptionBuilder:
|
19
|
+
self._request_option.api_key = api_key
|
20
|
+
return self
|
21
|
+
|
22
|
+
def headers(self, headers: dict[str, str]) -> RequestOptionBuilder:
|
23
|
+
self._request_option.headers = headers
|
24
|
+
return self
|
25
|
+
|
26
|
+
def build(self) -> RequestOption:
|
27
|
+
return self._request_option
|
dify_oapi/core/type.py
ADDED
File without changes
|
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2023 LangGenius
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|