From ed07ce109876d32558365d7c358febb51d215e64 Mon Sep 17 00:00:00 2001 From: QiMington Date: Thu, 7 Nov 2024 23:54:33 +0800 Subject: [PATCH] refactor: python-client --- sdks/python-client/MANIFEST.in | 2 +- sdks/python-client/README.md | 229 +++------ sdks/python-client/dify_client/__init__.py | 1 - sdks/python-client/dify_client/client.py | 446 ------------------ sdks/python-client/dify_oapi/__init__.py | 0 sdks/python-client/dify_oapi/api/__init__.py | 0 .../dify_oapi/api/chat/__init__.py | 0 .../dify_oapi/api/chat/service.py | 8 + .../dify_oapi/api/chat/v1/__init__.py | 0 .../dify_oapi/api/chat/v1/model/__init__.py | 0 .../chat/v1/model/audio_to_text_request.py | 41 ++ .../v1/model/audio_to_text_request_body.py | 23 + .../chat/v1/model/audio_to_text_response.py | 5 + .../api/chat/v1/model/chat_request.py | 32 ++ .../api/chat/v1/model/chat_request_body.py | 57 +++ .../api/chat/v1/model/chat_request_file.py | 56 +++ .../api/chat/v1/model/chat_response.py | 19 + .../v1/model/delete_conversation_request.py | 42 ++ .../model/delete_conversation_request_body.py | 23 + .../v1/model/delete_conversation_response.py | 5 + .../v1/model/get_conversation_list_request.py | 48 ++ .../model/get_conversation_list_response.py | 21 + .../chat/v1/model/message_history_request.py | 48 ++ .../chat/v1/model/message_history_response.py | 49 ++ .../v1/model/message_suggested_request.py | 36 ++ .../v1/model/message_suggested_response.py | 6 + .../v1/model/rename_conversation_request.py | 42 ++ .../model/rename_conversation_request_body.py | 35 ++ .../v1/model/rename_conversation_response.py | 11 + .../api/chat/v1/model/stop_chat_request.py | 38 ++ .../chat/v1/model/stop_chat_request_body.py | 23 + .../api/chat/v1/model/stop_chat_response.py | 5 + .../api/chat/v1/resource/__init__.py | 4 + .../dify_oapi/api/chat/v1/resource/audio.py | 25 + .../dify_oapi/api/chat/v1/resource/chat.py | 93 ++++ .../api/chat/v1/resource/conversation.py | 76 +++ .../dify_oapi/api/chat/v1/resource/message.py | 54 +++ .../dify_oapi/api/chat/v1/version.py | 11 + .../dify_oapi/api/completion/__init__.py | 0 .../dify_oapi/api/completion/service.py | 8 + .../dify_oapi/api/completion/v1/__init__.py | 0 .../api/completion/v1/model/__init__.py | 0 .../completion/v1/model/completion_request.py | 34 ++ .../v1/model/completion_request_body.py | 45 ++ .../v1/model/completion_request_body_input.py | 25 + .../v1/model/completion_request_file.py | 56 +++ .../v1/model/completion_response.py | 18 + .../v1/model/stop_completion_request.py | 40 ++ .../v1/model/stop_completion_request_body.py | 23 + .../v1/model/stop_completion_response.py | 5 + .../api/completion/v1/resource/__init__.py | 1 + .../api/completion/v1/resource/completion.py | 105 +++++ .../dify_oapi/api/completion/v1/version.py | 8 + .../dify_oapi/api/dify/__init__.py | 0 .../dify_oapi/api/dify/service.py | 8 + .../dify_oapi/api/dify/v1/__init__.py | 0 .../dify_oapi/api/dify/v1/model/__init__.py | 0 .../api/dify/v1/model/get_meta_request.py | 30 ++ .../api/dify/v1/model/get_meta_response.py | 19 + .../dify/v1/model/get_parameter_request.py | 30 ++ .../dify/v1/model/get_parameter_response.py | 13 + .../dify/v1/model/message_feedback_request.py | 40 ++ .../v1/model/message_feedback_request_body.py | 30 ++ .../v1/model/message_feedback_response.py | 5 + .../dify/v1/model/text_to_audio_request.py | 33 ++ .../v1/model/text_to_audio_request_body.py | 32 ++ .../dify/v1/model/text_to_audio_response.py | 4 + .../api/dify/v1/model/upload_file_body.py | 23 + .../api/dify/v1/model/upload_file_request.py | 43 ++ .../api/dify/v1/model/upload_file_response.py | 11 + .../api/dify/v1/resource/__init__.py | 5 + .../dify_oapi/api/dify/v1/resource/audio.py | 28 ++ .../dify_oapi/api/dify/v1/resource/file.py | 25 + .../dify_oapi/api/dify/v1/resource/message.py | 32 ++ .../dify_oapi/api/dify/v1/resource/meta.py | 25 + .../api/dify/v1/resource/parameter.py | 32 ++ .../dify_oapi/api/dify/v1/version.py | 12 + .../dify_oapi/api/knowledge_base/__init__.py | 0 .../dify_oapi/api/knowledge_base/service.py | 8 + .../api/knowledge_base/v1/__init__.py | 0 .../api/knowledge_base/v1/model/__init__.py | 0 .../v1/model/create_dataset_request.py | 33 ++ .../v1/model/create_dataset_request_body.py | 63 +++ .../v1/model/create_dataset_response.py | 9 + .../model/create_document_by_file_request.py | 54 +++ .../create_document_by_file_request_body.py | 34 ++ ...eate_document_by_file_request_body_data.py | 51 ++ .../model/create_document_by_text_request.py | 43 ++ .../create_document_by_text_request_body.py | 50 ++ .../v1/model/create_document_response.py | 10 + .../v1/model/create_segment_request.py | 47 ++ .../v1/model/create_segment_request_body.py | 25 + .../create_segment_request_body_segment.py | 32 ++ .../v1/model/create_segment_response.py | 10 + .../api/knowledge_base/v1/model/dataset.py | 54 +++ .../v1/model/delete_dataset_request.py | 30 ++ .../v1/model/delete_dataset_response.py | 4 + .../v1/model/delete_document_request.py | 36 ++ .../v1/model/delete_document_response.py | 5 + .../v1/model/delete_segment_request.py | 44 ++ .../v1/model/delete_segment_response.py | 5 + .../api/knowledge_base/v1/model/document.py | 45 ++ .../document_request_pre_processing_rule.py | 32 ++ .../v1/model/document_request_process_rule.py | 33 ++ .../v1/model/document_request_rules.py | 33 ++ .../v1/model/document_request_segmentation.py | 27 ++ .../v1/model/hit_test_request.py | 37 ++ .../v1/model/hit_test_request_body.py | 37 ++ .../hit_test_request_body_retrieval_model.py | 70 +++ .../v1/model/hit_test_response.py | 51 ++ .../v1/model/index_status_request.py | 38 ++ .../v1/model/index_status_response.py | 24 + .../v1/model/list_dataset_request.py | 36 ++ .../v1/model/list_dataset_response.py | 11 + .../v1/model/list_document_request.py | 48 ++ .../v1/model/list_document_response.py | 11 + .../v1/model/list_segment_request.py | 50 ++ .../v1/model/list_segment_response.py | 7 + .../api/knowledge_base/v1/model/segment.py | 25 + .../model/update_document_by_file_request.py | 60 +++ .../update_document_by_file_request_body.py | 33 ++ .../model/update_document_by_text_request.py | 49 ++ .../update_document_by_text_request_body.py | 37 ++ .../v1/model/update_document_response.py | 56 +++ .../v1/model/update_segment_request.py | 53 +++ .../v1/model/update_segment_request_body.py | 25 + .../update_segment_request_body_segment.py | 37 ++ .../v1/model/update_segment_response.py | 7 + .../knowledge_base/v1/resource/__init__.py | 3 + .../api/knowledge_base/v1/resource/dataset.py | 73 +++ .../knowledge_base/v1/resource/document.py | 119 +++++ .../api/knowledge_base/v1/resource/segment.py | 73 +++ .../api/knowledge_base/v1/version.py | 10 + .../dify_oapi/api/workflow/__init__.py | 0 .../dify_oapi/api/workflow/service.py | 8 + .../dify_oapi/api/workflow/v1/__init__.py | 0 .../api/workflow/v1/model/__init__.py | 0 .../v1/model/get_workflow_result_request.py | 30 ++ .../v1/model/get_workflow_result_response.py | 18 + .../workflow/v1/model/run_workflow_request.py | 34 ++ .../v1/model/run_workflow_request_body.py | 43 ++ .../v1/model/run_workflow_request_file.py | 54 +++ .../v1/model/run_workflow_response.py | 24 + .../v1/model/stop_workflow_request.py | 40 ++ .../v1/model/stop_workflow_request_body.py | 23 + .../v1/model/stop_workflow_response.py | 5 + .../api/workflow/v1/resource/__init__.py | 1 + .../api/workflow/v1/resource/workflow.py | 123 +++++ .../dify_oapi/api/workflow/v1/version.py | 8 + sdks/python-client/dify_oapi/client.py | 56 +++ sdks/python-client/dify_oapi/core/__init__.py | 0 sdks/python-client/dify_oapi/core/const.py | 12 + sdks/python-client/dify_oapi/core/enum.py | 21 + .../dify_oapi/core/http/__init__.py | 0 .../dify_oapi/core/http/transport.py | 288 +++++++++++ sdks/python-client/dify_oapi/core/json.py | 50 ++ sdks/python-client/dify_oapi/core/log.py | 10 + .../dify_oapi/core/model/__init__.py | 0 .../dify_oapi/core/model/base_request.py | 22 + .../dify_oapi/core/model/base_response.py | 14 + .../dify_oapi/core/model/config.py | 8 + .../dify_oapi/core/model/raw_request.py | 5 + .../dify_oapi/core/model/raw_response.py | 18 + .../dify_oapi/core/model/request_option.py | 27 ++ sdks/python-client/dify_oapi/core/type.py | 5 + .../dify_oapi/core/utils/__init__.py | 0 .../dify_oapi/core/utils/strings.py | 8 + sdks/python-client/setup.py | 8 +- sdks/python-client/tests/.gitignore | 1 + sdks/python-client/tests/pytest.ini.example | 9 + sdks/python-client/tests/test_chat.py | 162 +++++++ sdks/python-client/tests/test_client.py | 274 ----------- sdks/python-client/tests/test_completion.py | 94 ++++ sdks/python-client/tests/test_dify.py | 70 +++ sdks/python-client/tests/test_knowledge.py | 226 +++++++++ sdks/python-client/tests/test_workflow.py | 93 ++++ 176 files changed, 5366 insertions(+), 885 deletions(-) delete mode 100644 sdks/python-client/dify_client/__init__.py delete mode 100644 sdks/python-client/dify_client/client.py create mode 100755 sdks/python-client/dify_oapi/__init__.py create mode 100755 sdks/python-client/dify_oapi/api/__init__.py create mode 100755 sdks/python-client/dify_oapi/api/chat/__init__.py create mode 100755 sdks/python-client/dify_oapi/api/chat/service.py create mode 100755 sdks/python-client/dify_oapi/api/chat/v1/__init__.py create mode 100755 sdks/python-client/dify_oapi/api/chat/v1/model/__init__.py create mode 100644 sdks/python-client/dify_oapi/api/chat/v1/model/audio_to_text_request.py create mode 100644 sdks/python-client/dify_oapi/api/chat/v1/model/audio_to_text_request_body.py create mode 100644 sdks/python-client/dify_oapi/api/chat/v1/model/audio_to_text_response.py create mode 100755 sdks/python-client/dify_oapi/api/chat/v1/model/chat_request.py create mode 100755 sdks/python-client/dify_oapi/api/chat/v1/model/chat_request_body.py create mode 100755 sdks/python-client/dify_oapi/api/chat/v1/model/chat_request_file.py create mode 100755 sdks/python-client/dify_oapi/api/chat/v1/model/chat_response.py create mode 100755 sdks/python-client/dify_oapi/api/chat/v1/model/delete_conversation_request.py create mode 100755 sdks/python-client/dify_oapi/api/chat/v1/model/delete_conversation_request_body.py create mode 100755 sdks/python-client/dify_oapi/api/chat/v1/model/delete_conversation_response.py create mode 100755 sdks/python-client/dify_oapi/api/chat/v1/model/get_conversation_list_request.py create mode 100755 sdks/python-client/dify_oapi/api/chat/v1/model/get_conversation_list_response.py create mode 100755 sdks/python-client/dify_oapi/api/chat/v1/model/message_history_request.py create mode 100755 sdks/python-client/dify_oapi/api/chat/v1/model/message_history_response.py create mode 100755 sdks/python-client/dify_oapi/api/chat/v1/model/message_suggested_request.py create mode 100755 sdks/python-client/dify_oapi/api/chat/v1/model/message_suggested_response.py create mode 100755 sdks/python-client/dify_oapi/api/chat/v1/model/rename_conversation_request.py create mode 100755 sdks/python-client/dify_oapi/api/chat/v1/model/rename_conversation_request_body.py create mode 100755 sdks/python-client/dify_oapi/api/chat/v1/model/rename_conversation_response.py create mode 100755 sdks/python-client/dify_oapi/api/chat/v1/model/stop_chat_request.py create mode 100755 sdks/python-client/dify_oapi/api/chat/v1/model/stop_chat_request_body.py create mode 100755 sdks/python-client/dify_oapi/api/chat/v1/model/stop_chat_response.py create mode 100755 sdks/python-client/dify_oapi/api/chat/v1/resource/__init__.py create mode 100644 sdks/python-client/dify_oapi/api/chat/v1/resource/audio.py create mode 100755 sdks/python-client/dify_oapi/api/chat/v1/resource/chat.py create mode 100755 sdks/python-client/dify_oapi/api/chat/v1/resource/conversation.py create mode 100755 sdks/python-client/dify_oapi/api/chat/v1/resource/message.py create mode 100755 sdks/python-client/dify_oapi/api/chat/v1/version.py create mode 100755 sdks/python-client/dify_oapi/api/completion/__init__.py create mode 100755 sdks/python-client/dify_oapi/api/completion/service.py create mode 100755 sdks/python-client/dify_oapi/api/completion/v1/__init__.py create mode 100755 sdks/python-client/dify_oapi/api/completion/v1/model/__init__.py create mode 100755 sdks/python-client/dify_oapi/api/completion/v1/model/completion_request.py create mode 100755 sdks/python-client/dify_oapi/api/completion/v1/model/completion_request_body.py create mode 100755 sdks/python-client/dify_oapi/api/completion/v1/model/completion_request_body_input.py create mode 100755 sdks/python-client/dify_oapi/api/completion/v1/model/completion_request_file.py create mode 100755 sdks/python-client/dify_oapi/api/completion/v1/model/completion_response.py create mode 100755 sdks/python-client/dify_oapi/api/completion/v1/model/stop_completion_request.py create mode 100755 sdks/python-client/dify_oapi/api/completion/v1/model/stop_completion_request_body.py create mode 100755 sdks/python-client/dify_oapi/api/completion/v1/model/stop_completion_response.py create mode 100755 sdks/python-client/dify_oapi/api/completion/v1/resource/__init__.py create mode 100755 sdks/python-client/dify_oapi/api/completion/v1/resource/completion.py create mode 100755 sdks/python-client/dify_oapi/api/completion/v1/version.py create mode 100644 sdks/python-client/dify_oapi/api/dify/__init__.py create mode 100644 sdks/python-client/dify_oapi/api/dify/service.py create mode 100644 sdks/python-client/dify_oapi/api/dify/v1/__init__.py create mode 100644 sdks/python-client/dify_oapi/api/dify/v1/model/__init__.py create mode 100644 sdks/python-client/dify_oapi/api/dify/v1/model/get_meta_request.py create mode 100644 sdks/python-client/dify_oapi/api/dify/v1/model/get_meta_response.py create mode 100755 sdks/python-client/dify_oapi/api/dify/v1/model/get_parameter_request.py create mode 100755 sdks/python-client/dify_oapi/api/dify/v1/model/get_parameter_response.py create mode 100755 sdks/python-client/dify_oapi/api/dify/v1/model/message_feedback_request.py create mode 100755 sdks/python-client/dify_oapi/api/dify/v1/model/message_feedback_request_body.py create mode 100755 sdks/python-client/dify_oapi/api/dify/v1/model/message_feedback_response.py create mode 100644 sdks/python-client/dify_oapi/api/dify/v1/model/text_to_audio_request.py create mode 100644 sdks/python-client/dify_oapi/api/dify/v1/model/text_to_audio_request_body.py create mode 100644 sdks/python-client/dify_oapi/api/dify/v1/model/text_to_audio_response.py create mode 100644 sdks/python-client/dify_oapi/api/dify/v1/model/upload_file_body.py create mode 100644 sdks/python-client/dify_oapi/api/dify/v1/model/upload_file_request.py create mode 100644 sdks/python-client/dify_oapi/api/dify/v1/model/upload_file_response.py create mode 100644 sdks/python-client/dify_oapi/api/dify/v1/resource/__init__.py create mode 100644 sdks/python-client/dify_oapi/api/dify/v1/resource/audio.py create mode 100644 sdks/python-client/dify_oapi/api/dify/v1/resource/file.py create mode 100755 sdks/python-client/dify_oapi/api/dify/v1/resource/message.py create mode 100644 sdks/python-client/dify_oapi/api/dify/v1/resource/meta.py create mode 100755 sdks/python-client/dify_oapi/api/dify/v1/resource/parameter.py create mode 100644 sdks/python-client/dify_oapi/api/dify/v1/version.py create mode 100644 sdks/python-client/dify_oapi/api/knowledge_base/__init__.py create mode 100644 sdks/python-client/dify_oapi/api/knowledge_base/service.py create mode 100644 sdks/python-client/dify_oapi/api/knowledge_base/v1/__init__.py create mode 100644 sdks/python-client/dify_oapi/api/knowledge_base/v1/model/__init__.py create mode 100644 sdks/python-client/dify_oapi/api/knowledge_base/v1/model/create_dataset_request.py create mode 100644 sdks/python-client/dify_oapi/api/knowledge_base/v1/model/create_dataset_request_body.py create mode 100644 sdks/python-client/dify_oapi/api/knowledge_base/v1/model/create_dataset_response.py create mode 100644 sdks/python-client/dify_oapi/api/knowledge_base/v1/model/create_document_by_file_request.py create mode 100644 sdks/python-client/dify_oapi/api/knowledge_base/v1/model/create_document_by_file_request_body.py create mode 100644 sdks/python-client/dify_oapi/api/knowledge_base/v1/model/create_document_by_file_request_body_data.py create mode 100644 sdks/python-client/dify_oapi/api/knowledge_base/v1/model/create_document_by_text_request.py create mode 100644 sdks/python-client/dify_oapi/api/knowledge_base/v1/model/create_document_by_text_request_body.py create mode 100644 sdks/python-client/dify_oapi/api/knowledge_base/v1/model/create_document_response.py create mode 100644 sdks/python-client/dify_oapi/api/knowledge_base/v1/model/create_segment_request.py create mode 100644 sdks/python-client/dify_oapi/api/knowledge_base/v1/model/create_segment_request_body.py create mode 100644 sdks/python-client/dify_oapi/api/knowledge_base/v1/model/create_segment_request_body_segment.py create mode 100644 sdks/python-client/dify_oapi/api/knowledge_base/v1/model/create_segment_response.py create mode 100644 sdks/python-client/dify_oapi/api/knowledge_base/v1/model/dataset.py create mode 100644 sdks/python-client/dify_oapi/api/knowledge_base/v1/model/delete_dataset_request.py create mode 100644 sdks/python-client/dify_oapi/api/knowledge_base/v1/model/delete_dataset_response.py create mode 100644 sdks/python-client/dify_oapi/api/knowledge_base/v1/model/delete_document_request.py create mode 100644 sdks/python-client/dify_oapi/api/knowledge_base/v1/model/delete_document_response.py create mode 100644 sdks/python-client/dify_oapi/api/knowledge_base/v1/model/delete_segment_request.py create mode 100644 sdks/python-client/dify_oapi/api/knowledge_base/v1/model/delete_segment_response.py create mode 100644 sdks/python-client/dify_oapi/api/knowledge_base/v1/model/document.py create mode 100644 sdks/python-client/dify_oapi/api/knowledge_base/v1/model/document_request_pre_processing_rule.py create mode 100644 sdks/python-client/dify_oapi/api/knowledge_base/v1/model/document_request_process_rule.py create mode 100644 sdks/python-client/dify_oapi/api/knowledge_base/v1/model/document_request_rules.py create mode 100644 sdks/python-client/dify_oapi/api/knowledge_base/v1/model/document_request_segmentation.py create mode 100644 sdks/python-client/dify_oapi/api/knowledge_base/v1/model/hit_test_request.py create mode 100644 sdks/python-client/dify_oapi/api/knowledge_base/v1/model/hit_test_request_body.py create mode 100644 sdks/python-client/dify_oapi/api/knowledge_base/v1/model/hit_test_request_body_retrieval_model.py create mode 100644 sdks/python-client/dify_oapi/api/knowledge_base/v1/model/hit_test_response.py create mode 100644 sdks/python-client/dify_oapi/api/knowledge_base/v1/model/index_status_request.py create mode 100644 sdks/python-client/dify_oapi/api/knowledge_base/v1/model/index_status_response.py create mode 100644 sdks/python-client/dify_oapi/api/knowledge_base/v1/model/list_dataset_request.py create mode 100644 sdks/python-client/dify_oapi/api/knowledge_base/v1/model/list_dataset_response.py create mode 100644 sdks/python-client/dify_oapi/api/knowledge_base/v1/model/list_document_request.py create mode 100644 sdks/python-client/dify_oapi/api/knowledge_base/v1/model/list_document_response.py create mode 100644 sdks/python-client/dify_oapi/api/knowledge_base/v1/model/list_segment_request.py create mode 100644 sdks/python-client/dify_oapi/api/knowledge_base/v1/model/list_segment_response.py create mode 100644 sdks/python-client/dify_oapi/api/knowledge_base/v1/model/segment.py create mode 100644 sdks/python-client/dify_oapi/api/knowledge_base/v1/model/update_document_by_file_request.py create mode 100644 sdks/python-client/dify_oapi/api/knowledge_base/v1/model/update_document_by_file_request_body.py create mode 100644 sdks/python-client/dify_oapi/api/knowledge_base/v1/model/update_document_by_text_request.py create mode 100644 sdks/python-client/dify_oapi/api/knowledge_base/v1/model/update_document_by_text_request_body.py create mode 100644 sdks/python-client/dify_oapi/api/knowledge_base/v1/model/update_document_response.py create mode 100644 sdks/python-client/dify_oapi/api/knowledge_base/v1/model/update_segment_request.py create mode 100644 sdks/python-client/dify_oapi/api/knowledge_base/v1/model/update_segment_request_body.py create mode 100644 sdks/python-client/dify_oapi/api/knowledge_base/v1/model/update_segment_request_body_segment.py create mode 100644 sdks/python-client/dify_oapi/api/knowledge_base/v1/model/update_segment_response.py create mode 100644 sdks/python-client/dify_oapi/api/knowledge_base/v1/resource/__init__.py create mode 100644 sdks/python-client/dify_oapi/api/knowledge_base/v1/resource/dataset.py create mode 100644 sdks/python-client/dify_oapi/api/knowledge_base/v1/resource/document.py create mode 100644 sdks/python-client/dify_oapi/api/knowledge_base/v1/resource/segment.py create mode 100644 sdks/python-client/dify_oapi/api/knowledge_base/v1/version.py create mode 100644 sdks/python-client/dify_oapi/api/workflow/__init__.py create mode 100644 sdks/python-client/dify_oapi/api/workflow/service.py create mode 100644 sdks/python-client/dify_oapi/api/workflow/v1/__init__.py create mode 100644 sdks/python-client/dify_oapi/api/workflow/v1/model/__init__.py create mode 100644 sdks/python-client/dify_oapi/api/workflow/v1/model/get_workflow_result_request.py create mode 100644 sdks/python-client/dify_oapi/api/workflow/v1/model/get_workflow_result_response.py create mode 100644 sdks/python-client/dify_oapi/api/workflow/v1/model/run_workflow_request.py create mode 100644 sdks/python-client/dify_oapi/api/workflow/v1/model/run_workflow_request_body.py create mode 100755 sdks/python-client/dify_oapi/api/workflow/v1/model/run_workflow_request_file.py create mode 100644 sdks/python-client/dify_oapi/api/workflow/v1/model/run_workflow_response.py create mode 100755 sdks/python-client/dify_oapi/api/workflow/v1/model/stop_workflow_request.py create mode 100755 sdks/python-client/dify_oapi/api/workflow/v1/model/stop_workflow_request_body.py create mode 100755 sdks/python-client/dify_oapi/api/workflow/v1/model/stop_workflow_response.py create mode 100644 sdks/python-client/dify_oapi/api/workflow/v1/resource/__init__.py create mode 100644 sdks/python-client/dify_oapi/api/workflow/v1/resource/workflow.py create mode 100644 sdks/python-client/dify_oapi/api/workflow/v1/version.py create mode 100755 sdks/python-client/dify_oapi/client.py create mode 100755 sdks/python-client/dify_oapi/core/__init__.py create mode 100755 sdks/python-client/dify_oapi/core/const.py create mode 100755 sdks/python-client/dify_oapi/core/enum.py create mode 100755 sdks/python-client/dify_oapi/core/http/__init__.py create mode 100755 sdks/python-client/dify_oapi/core/http/transport.py create mode 100755 sdks/python-client/dify_oapi/core/json.py create mode 100755 sdks/python-client/dify_oapi/core/log.py create mode 100755 sdks/python-client/dify_oapi/core/model/__init__.py create mode 100755 sdks/python-client/dify_oapi/core/model/base_request.py create mode 100755 sdks/python-client/dify_oapi/core/model/base_response.py create mode 100755 sdks/python-client/dify_oapi/core/model/config.py create mode 100755 sdks/python-client/dify_oapi/core/model/raw_request.py create mode 100755 sdks/python-client/dify_oapi/core/model/raw_response.py create mode 100755 sdks/python-client/dify_oapi/core/model/request_option.py create mode 100755 sdks/python-client/dify_oapi/core/type.py create mode 100755 sdks/python-client/dify_oapi/core/utils/__init__.py create mode 100755 sdks/python-client/dify_oapi/core/utils/strings.py create mode 100644 sdks/python-client/tests/.gitignore create mode 100644 sdks/python-client/tests/pytest.ini.example create mode 100644 sdks/python-client/tests/test_chat.py delete mode 100644 sdks/python-client/tests/test_client.py create mode 100644 sdks/python-client/tests/test_completion.py create mode 100644 sdks/python-client/tests/test_dify.py create mode 100644 sdks/python-client/tests/test_knowledge.py create mode 100644 sdks/python-client/tests/test_workflow.py diff --git a/sdks/python-client/MANIFEST.in b/sdks/python-client/MANIFEST.in index da331d5e5c..1cd16a866b 100644 --- a/sdks/python-client/MANIFEST.in +++ b/sdks/python-client/MANIFEST.in @@ -1 +1 @@ -recursive-include dify_client *.py \ No newline at end of file +recursive-include dify_oapi *.py \ No newline at end of file diff --git a/sdks/python-client/README.md b/sdks/python-client/README.md index 8949ef08fa..b9be904a93 100644 --- a/sdks/python-client/README.md +++ b/sdks/python-client/README.md @@ -1,185 +1,96 @@ -# dify-client +# dify-oapi A Dify App Service-API Client, using for build a webapp by request Service-API ## Usage -First, install `dify-client` python sdk package: +First, install `dify-oapi` python sdk package: ``` -pip install dify-client +pip install dify-oapi ``` Write your code with sdk: -- completion generate with `blocking` response_mode +- chat generate with `blocking` response_mode ```python -from dify_client import CompletionClient +from dify_oapi.api.chat.v1.model.chat_request import ChatRequest +from dify_oapi.api.chat.v1.model.chat_request_body import ChatRequestBody +from dify_oapi.api.chat.v1.model.chat_request_file import ChatRequestFile +from dify_oapi.client import Client +from dify_oapi.core.model.request_option import RequestOption -api_key = "your_api_key" +def main(): + client = Client.builder().domain("https://api.dify.ai").build() + req_file = ( + ChatRequestFile.builder() + .type("image") + .transfer_method("remote_url") + .url("https://cloud.dify.ai/logo/logo-site.png") + .build() + ) + req_body = ( + ChatRequestBody.builder() + .inputs({}) + .query("What are the specs of the iPhone 13 Pro Max?") + .response_mode("blocking") + .conversation_id("") + .user("abc-123") + .files([req_file]) + .build() + ) + req = ChatRequest.builder().request_body(req_body).build() + req_option = RequestOption.builder().api_key("").build() + response = client.chat.v1.chat.chat(req, req_option, False) + # response = await client.chat.v1.chat.achat(req, req_option, False) + print(response.success) + print(response.code) + print(response.msg) + print(response.answer) -# Initialize CompletionClient -completion_client = CompletionClient(api_key) -# Create Completion Message using CompletionClient -completion_response = completion_client.create_completion_message(inputs={"query": "What's the weather like today?"}, - response_mode="blocking", user="user_id") -completion_response.raise_for_status() +if __name__ == "__main__": + main() -result = completion_response.json() - -print(result.get('answer')) -``` - -- completion using vision model, like gpt-4-vision - -```python -from dify_client import CompletionClient - -api_key = "your_api_key" - -# Initialize CompletionClient -completion_client = CompletionClient(api_key) - -files = [{ - "type": "image", - "transfer_method": "remote_url", - "url": "your_image_url" -}] - -# files = [{ -# "type": "image", -# "transfer_method": "local_file", -# "upload_file_id": "your_file_id" -# }] - -# Create Completion Message using CompletionClient -completion_response = completion_client.create_completion_message(inputs={"query": "Describe the picture."}, - response_mode="blocking", user="user_id", files=files) -completion_response.raise_for_status() - -result = completion_response.json() - -print(result.get('answer')) ``` - chat generate with `streaming` response_mode ```python -import json -from dify_client import ChatClient +from dify_oapi.api.chat.v1.model.chat_request import ChatRequest +from dify_oapi.api.chat.v1.model.chat_request_body import ChatRequestBody +from dify_oapi.api.chat.v1.model.chat_request_file import ChatRequestFile +from dify_oapi.client import Client +from dify_oapi.core.model.request_option import RequestOption -api_key = "your_api_key" +def main(): + client = Client.builder().domain("https://api.dify.ai").build() + req_file = ( + ChatRequestFile.builder() + .type("image") + .transfer_method("remote_url") + .url("https://cloud.dify.ai/logo/logo-site.png") + .build() + ) + req_body = ( + ChatRequestBody.builder() + .inputs({}) + .query("What are the specs of the iPhone 13 Pro Max?") + .response_mode("streaming") + .conversation_id("") + .user("abc-123") + .files([req_file]) + .build() + ) + req = ChatRequest.builder().request_body(req_body).build() + req_option = RequestOption.builder().api_key("").build() + response = client.chat.v1.chat.chat(req, req_option, True) + # response = await client.chat.v1.chat.achat(req, req_option, True) + for chunk in response: + print(chunk) -# Initialize ChatClient -chat_client = ChatClient(api_key) -# Create Chat Message using ChatClient -chat_response = chat_client.create_chat_message(inputs={}, query="Hello", user="user_id", response_mode="streaming") -chat_response.raise_for_status() - -for line in chat_response.iter_lines(decode_unicode=True): - line = line.split('data:', 1)[-1] - if line.strip(): - line = json.loads(line.strip()) - print(line.get('answer')) -``` - -- chat using vision model, like gpt-4-vision - -```python -from dify_client import ChatClient - -api_key = "your_api_key" - -# Initialize ChatClient -chat_client = ChatClient(api_key) - -files = [{ - "type": "image", - "transfer_method": "remote_url", - "url": "your_image_url" -}] - -# files = [{ -# "type": "image", -# "transfer_method": "local_file", -# "upload_file_id": "your_file_id" -# }] - -# Create Chat Message using ChatClient -chat_response = chat_client.create_chat_message(inputs={}, query="Describe the picture.", user="user_id", - response_mode="blocking", files=files) -chat_response.raise_for_status() - -result = chat_response.json() - -print(result.get("answer")) -``` - -- upload file when using vision model - -```python -from dify_client import DifyClient - -api_key = "your_api_key" - -# Initialize Client -dify_client = DifyClient(api_key) - -file_path = "your_image_file_path" -file_name = "panda.jpeg" -mime_type = "image/jpeg" - -with open(file_path, "rb") as file: - files = { - "file": (file_name, file, mime_type) - } - response = dify_client.file_upload("user_id", files) - - result = response.json() - print(f'upload_file_id: {result.get("id")}') -``` - - - -- Others - -```python -from dify_client import ChatClient - -api_key = "your_api_key" - -# Initialize Client -client = ChatClient(api_key) - -# Get App parameters -parameters = client.get_application_parameters(user="user_id") -parameters.raise_for_status() - -print('[parameters]') -print(parameters.json()) - -# Get Conversation List (only for chat) -conversations = client.get_conversations(user="user_id") -conversations.raise_for_status() - -print('[conversations]') -print(conversations.json()) - -# Get Message List (only for chat) -messages = client.get_conversation_messages(user="user_id", conversation_id="conversation_id") -messages.raise_for_status() - -print('[messages]') -print(messages.json()) - -# Rename Conversation (only for chat) -rename_conversation_response = client.rename_conversation(conversation_id="conversation_id", - name="new_name", user="user_id") -rename_conversation_response.raise_for_status() - -print('[rename result]') -print(rename_conversation_response.json()) +if __name__ == "__main__": + main() ``` diff --git a/sdks/python-client/dify_client/__init__.py b/sdks/python-client/dify_client/__init__.py deleted file mode 100644 index 6fa9d190e5..0000000000 --- a/sdks/python-client/dify_client/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from dify_client.client import ChatClient, CompletionClient, DifyClient diff --git a/sdks/python-client/dify_client/client.py b/sdks/python-client/dify_client/client.py deleted file mode 100644 index e664488301..0000000000 --- a/sdks/python-client/dify_client/client.py +++ /dev/null @@ -1,446 +0,0 @@ -import json - -import requests - - -class DifyClient: - def __init__(self, api_key, base_url: str = "https://api.dify.ai/v1"): - self.api_key = api_key - self.base_url = base_url - - def _send_request(self, method, endpoint, json=None, params=None, stream=False): - headers = { - "Authorization": f"Bearer {self.api_key}", - "Content-Type": "application/json", - } - - url = f"{self.base_url}{endpoint}" - response = requests.request( - method, url, json=json, params=params, headers=headers, stream=stream - ) - - return response - - def _send_request_with_files(self, method, endpoint, data, files): - headers = {"Authorization": f"Bearer {self.api_key}"} - - url = f"{self.base_url}{endpoint}" - response = requests.request( - method, url, data=data, headers=headers, files=files - ) - - return response - - def message_feedback(self, message_id, rating, user): - data = {"rating": rating, "user": user} - return self._send_request("POST", f"/messages/{message_id}/feedbacks", data) - - def get_application_parameters(self, user): - params = {"user": user} - return self._send_request("GET", "/parameters", params=params) - - def file_upload(self, user, files): - data = {"user": user} - return self._send_request_with_files( - "POST", "/files/upload", data=data, files=files - ) - - def text_to_audio(self, text: str, user: str, streaming: bool = False): - data = {"text": text, "user": user, "streaming": streaming} - return self._send_request("POST", "/text-to-audio", data=data) - - def get_meta(self, user): - params = {"user": user} - return self._send_request("GET", "/meta", params=params) - - -class CompletionClient(DifyClient): - def create_completion_message(self, inputs, response_mode, user, files=None): - data = { - "inputs": inputs, - "response_mode": response_mode, - "user": user, - "files": files, - } - return self._send_request( - "POST", - "/completion-messages", - data, - stream=True if response_mode == "streaming" else False, - ) - - -class ChatClient(DifyClient): - def create_chat_message( - self, - inputs, - query, - user, - response_mode="blocking", - conversation_id=None, - files=None, - ): - data = { - "inputs": inputs, - "query": query, - "user": user, - "response_mode": response_mode, - "files": files, - } - if conversation_id: - data["conversation_id"] = conversation_id - - return self._send_request( - "POST", - "/chat-messages", - data, - stream=True if response_mode == "streaming" else False, - ) - - def get_suggested(self, message_id, user: str): - params = {"user": user} - return self._send_request( - "GET", f"/messages/{message_id}/suggested", params=params - ) - - def stop_message(self, task_id, user): - data = {"user": user} - return self._send_request("POST", f"/chat-messages/{task_id}/stop", data) - - def get_conversations(self, user, last_id=None, limit=None, pinned=None): - params = {"user": user, "last_id": last_id, "limit": limit, "pinned": pinned} - return self._send_request("GET", "/conversations", params=params) - - def get_conversation_messages( - self, user, conversation_id=None, first_id=None, limit=None - ): - params = {"user": user} - - if conversation_id: - params["conversation_id"] = conversation_id - if first_id: - params["first_id"] = first_id - if limit: - params["limit"] = limit - - return self._send_request("GET", "/messages", params=params) - - def rename_conversation( - self, conversation_id, name, auto_generate: bool, user: str - ): - data = {"name": name, "auto_generate": auto_generate, "user": user} - return self._send_request( - "POST", f"/conversations/{conversation_id}/name", data - ) - - def delete_conversation(self, conversation_id, user): - data = {"user": user} - return self._send_request("DELETE", f"/conversations/{conversation_id}", data) - - def audio_to_text(self, audio_file, user): - data = {"user": user} - files = {"audio_file": audio_file} - return self._send_request_with_files("POST", "/audio-to-text", data, files) - - -class WorkflowClient(DifyClient): - def run( - self, inputs: dict, response_mode: str = "streaming", user: str = "abc-123" - ): - data = {"inputs": inputs, "response_mode": response_mode, "user": user} - return self._send_request("POST", "/workflows/run", data) - - def stop(self, task_id, user): - data = {"user": user} - return self._send_request("POST", f"/workflows/tasks/{task_id}/stop", data) - - def get_result(self, workflow_run_id): - return self._send_request("GET", f"/workflows/run/{workflow_run_id}") - - -class KnowledgeBaseClient(DifyClient): - def __init__( - self, api_key, base_url: str = "https://api.dify.ai/v1", dataset_id: str = None - ): - """ - Construct a KnowledgeBaseClient object. - - Args: - api_key (str): API key of Dify. - base_url (str, optional): Base URL of Dify API. Defaults to 'https://api.dify.ai/v1'. - dataset_id (str, optional): ID of the dataset. Defaults to None. You don't need this if you just want to - create a new dataset. or list datasets. otherwise you need to set this. - """ - super().__init__(api_key=api_key, base_url=base_url) - self.dataset_id = dataset_id - - def _get_dataset_id(self): - if self.dataset_id is None: - raise ValueError("dataset_id is not set") - return self.dataset_id - - def create_dataset(self, name: str, **kwargs): - return self._send_request("POST", "/datasets", {"name": name}, **kwargs) - - def list_datasets(self, page: int = 1, page_size: int = 20, **kwargs): - return self._send_request( - "GET", f"/datasets?page={page}&limit={page_size}", **kwargs - ) - - def create_document_by_text(self, name, text, extra_params: dict = None, **kwargs): - """ - Create a document by text. - - :param name: Name of the document - :param text: Text content of the document - :param extra_params: extra parameters pass to the API, such as indexing_technique, process_rule. (optional) - e.g. - { - 'indexing_technique': 'high_quality', - 'process_rule': { - 'rules': { - 'pre_processing_rules': [ - {'id': 'remove_extra_spaces', 'enabled': True}, - {'id': 'remove_urls_emails', 'enabled': True} - ], - 'segmentation': { - 'separator': '\n', - 'max_tokens': 500 - } - }, - 'mode': 'custom' - } - } - :return: Response from the API - """ - data = { - "indexing_technique": "high_quality", - "process_rule": {"mode": "automatic"}, - "name": name, - "text": text, - } - if extra_params is not None and isinstance(extra_params, dict): - data.update(extra_params) - url = f"/datasets/{self._get_dataset_id()}/document/create_by_text" - return self._send_request("POST", url, json=data, **kwargs) - - def update_document_by_text( - self, document_id, name, text, extra_params: dict = None, **kwargs - ): - """ - Update a document by text. - - :param document_id: ID of the document - :param name: Name of the document - :param text: Text content of the document - :param extra_params: extra parameters pass to the API, such as indexing_technique, process_rule. (optional) - e.g. - { - 'indexing_technique': 'high_quality', - 'process_rule': { - 'rules': { - 'pre_processing_rules': [ - {'id': 'remove_extra_spaces', 'enabled': True}, - {'id': 'remove_urls_emails', 'enabled': True} - ], - 'segmentation': { - 'separator': '\n', - 'max_tokens': 500 - } - }, - 'mode': 'custom' - } - } - :return: Response from the API - """ - data = {"name": name, "text": text} - if extra_params is not None and isinstance(extra_params, dict): - data.update(extra_params) - url = ( - f"/datasets/{self._get_dataset_id()}/documents/{document_id}/update_by_text" - ) - return self._send_request("POST", url, json=data, **kwargs) - - def create_document_by_file( - self, file_path, original_document_id=None, extra_params: dict = None - ): - """ - Create a document by file. - - :param file_path: Path to the file - :param original_document_id: pass this ID if you want to replace the original document (optional) - :param extra_params: extra parameters pass to the API, such as indexing_technique, process_rule. (optional) - e.g. - { - 'indexing_technique': 'high_quality', - 'process_rule': { - 'rules': { - 'pre_processing_rules': [ - {'id': 'remove_extra_spaces', 'enabled': True}, - {'id': 'remove_urls_emails', 'enabled': True} - ], - 'segmentation': { - 'separator': '\n', - 'max_tokens': 500 - } - }, - 'mode': 'custom' - } - } - :return: Response from the API - """ - files = {"file": open(file_path, "rb")} - data = { - "process_rule": {"mode": "automatic"}, - "indexing_technique": "high_quality", - } - if extra_params is not None and isinstance(extra_params, dict): - data.update(extra_params) - if original_document_id is not None: - data["original_document_id"] = original_document_id - url = f"/datasets/{self._get_dataset_id()}/document/create_by_file" - return self._send_request_with_files( - "POST", url, {"data": json.dumps(data)}, files - ) - - def update_document_by_file( - self, document_id, file_path, extra_params: dict = None - ): - """ - Update a document by file. - - :param document_id: ID of the document - :param file_path: Path to the file - :param extra_params: extra parameters pass to the API, such as indexing_technique, process_rule. (optional) - e.g. - { - 'indexing_technique': 'high_quality', - 'process_rule': { - 'rules': { - 'pre_processing_rules': [ - {'id': 'remove_extra_spaces', 'enabled': True}, - {'id': 'remove_urls_emails', 'enabled': True} - ], - 'segmentation': { - 'separator': '\n', - 'max_tokens': 500 - } - }, - 'mode': 'custom' - } - } - :return: - """ - files = {"file": open(file_path, "rb")} - data = {} - if extra_params is not None and isinstance(extra_params, dict): - data.update(extra_params) - url = ( - f"/datasets/{self._get_dataset_id()}/documents/{document_id}/update_by_file" - ) - return self._send_request_with_files( - "POST", url, {"data": json.dumps(data)}, files - ) - - def batch_indexing_status(self, batch_id: str, **kwargs): - """ - Get the status of the batch indexing. - - :param batch_id: ID of the batch uploading - :return: Response from the API - """ - url = f"/datasets/{self._get_dataset_id()}/documents/{batch_id}/indexing-status" - return self._send_request("GET", url, **kwargs) - - def delete_dataset(self): - """ - Delete this dataset. - - :return: Response from the API - """ - url = f"/datasets/{self._get_dataset_id()}" - return self._send_request("DELETE", url) - - def delete_document(self, document_id): - """ - Delete a document. - - :param document_id: ID of the document - :return: Response from the API - """ - url = f"/datasets/{self._get_dataset_id()}/documents/{document_id}" - return self._send_request("DELETE", url) - - def list_documents( - self, page: int = None, page_size: int = None, keyword: str = None, **kwargs - ): - """ - Get a list of documents in this dataset. - - :return: Response from the API - """ - params = {} - if page is not None: - params["page"] = page - if page_size is not None: - params["limit"] = page_size - if keyword is not None: - params["keyword"] = keyword - url = f"/datasets/{self._get_dataset_id()}/documents" - return self._send_request("GET", url, params=params, **kwargs) - - def add_segments(self, document_id, segments, **kwargs): - """ - Add segments to a document. - - :param document_id: ID of the document - :param segments: List of segments to add, example: [{"content": "1", "answer": "1", "keyword": ["a"]}] - :return: Response from the API - """ - data = {"segments": segments} - url = f"/datasets/{self._get_dataset_id()}/documents/{document_id}/segments" - return self._send_request("POST", url, json=data, **kwargs) - - def query_segments( - self, document_id, keyword: str = None, status: str = None, **kwargs - ): - """ - Query segments in this document. - - :param document_id: ID of the document - :param keyword: query keyword, optional - :param status: status of the segment, optional, e.g. completed - """ - url = f"/datasets/{self._get_dataset_id()}/documents/{document_id}/segments" - params = {} - if keyword is not None: - params["keyword"] = keyword - if status is not None: - params["status"] = status - if "params" in kwargs: - params.update(kwargs["params"]) - return self._send_request("GET", url, params=params, **kwargs) - - def delete_document_segment(self, document_id, segment_id): - """ - Delete a segment from a document. - - :param document_id: ID of the document - :param segment_id: ID of the segment - :return: Response from the API - """ - url = f"/datasets/{self._get_dataset_id()}/documents/{document_id}/segments/{segment_id}" - return self._send_request("DELETE", url) - - def update_document_segment(self, document_id, segment_id, segment_data, **kwargs): - """ - Update a segment in a document. - - :param document_id: ID of the document - :param segment_id: ID of the segment - :param segment_data: Data of the segment, example: {"content": "1", "answer": "1", "keyword": ["a"], "enabled": True} - :return: Response from the API - """ - data = {"segment": segment_data} - url = f"/datasets/{self._get_dataset_id()}/documents/{document_id}/segments/{segment_id}" - return self._send_request("POST", url, json=data, **kwargs) diff --git a/sdks/python-client/dify_oapi/__init__.py b/sdks/python-client/dify_oapi/__init__.py new file mode 100755 index 0000000000..e69de29bb2 diff --git a/sdks/python-client/dify_oapi/api/__init__.py b/sdks/python-client/dify_oapi/api/__init__.py new file mode 100755 index 0000000000..e69de29bb2 diff --git a/sdks/python-client/dify_oapi/api/chat/__init__.py b/sdks/python-client/dify_oapi/api/chat/__init__.py new file mode 100755 index 0000000000..e69de29bb2 diff --git a/sdks/python-client/dify_oapi/api/chat/service.py b/sdks/python-client/dify_oapi/api/chat/service.py new file mode 100755 index 0000000000..195112fe03 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/chat/service.py @@ -0,0 +1,8 @@ +from dify_oapi.core.model.config import Config + +from .v1.version import V1 + + +class ChatService: + def __init__(self, config: Config) -> None: + self.v1: V1 = V1(config) diff --git a/sdks/python-client/dify_oapi/api/chat/v1/__init__.py b/sdks/python-client/dify_oapi/api/chat/v1/__init__.py new file mode 100755 index 0000000000..e69de29bb2 diff --git a/sdks/python-client/dify_oapi/api/chat/v1/model/__init__.py b/sdks/python-client/dify_oapi/api/chat/v1/model/__init__.py new file mode 100755 index 0000000000..e69de29bb2 diff --git a/sdks/python-client/dify_oapi/api/chat/v1/model/audio_to_text_request.py b/sdks/python-client/dify_oapi/api/chat/v1/model/audio_to_text_request.py new file mode 100644 index 0000000000..5c22a8220a --- /dev/null +++ b/sdks/python-client/dify_oapi/api/chat/v1/model/audio_to_text_request.py @@ -0,0 +1,41 @@ +from __future__ import annotations + +from io import BytesIO + +from dify_oapi.core.enum import HttpMethod +from dify_oapi.core.model.base_request import BaseRequest +from .audio_to_text_request_body import AudioToTextRequestBody + + +class AudioToTextRequest(BaseRequest): + def __init__(self): + super().__init__() + self.file: BytesIO | None = None + self.request_body: AudioToTextRequestBody | None = None + + @staticmethod + def builder() -> AudioToTextRequestBuilder: + return AudioToTextRequestBuilder() + + +class AudioToTextRequestBuilder(object): + def __init__(self): + audio_to_text_request = AudioToTextRequest() + audio_to_text_request.http_method = HttpMethod.POST + audio_to_text_request.uri = "/v1/audio-to-text" + self._audio_to_text_request = audio_to_text_request + + def build(self) -> AudioToTextRequest: + return self._audio_to_text_request + + def request_body( + self, request_body: AudioToTextRequestBody + ) -> AudioToTextRequestBuilder: + self._audio_to_text_request.request_body = request_body + self._audio_to_text_request.body = request_body.model_dump(exclude_none=True) + return self + + def file(self, file: BytesIO, file_name: str) -> AudioToTextRequestBuilder: + self._audio_to_text_request.file = file + self._audio_to_text_request.files = {"file": (file_name, file)} + return self diff --git a/sdks/python-client/dify_oapi/api/chat/v1/model/audio_to_text_request_body.py b/sdks/python-client/dify_oapi/api/chat/v1/model/audio_to_text_request_body.py new file mode 100644 index 0000000000..c5aaedb254 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/chat/v1/model/audio_to_text_request_body.py @@ -0,0 +1,23 @@ +from __future__ import annotations + +from pydantic import BaseModel + + +class AudioToTextRequestBody(BaseModel): + user: str | None = None + + @staticmethod + def builder() -> AudioToTextRequestBodyBuilder: + return AudioToTextRequestBodyBuilder() + + +class AudioToTextRequestBodyBuilder(object): + def __init__(self): + self._audio_to_text_request_body = AudioToTextRequestBody() + + def build(self) -> AudioToTextRequestBody: + return self._audio_to_text_request_body + + def user(self, user: str) -> AudioToTextRequestBodyBuilder: + self._audio_to_text_request_body.user = user + return self diff --git a/sdks/python-client/dify_oapi/api/chat/v1/model/audio_to_text_response.py b/sdks/python-client/dify_oapi/api/chat/v1/model/audio_to_text_response.py new file mode 100644 index 0000000000..9cd04e9254 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/chat/v1/model/audio_to_text_response.py @@ -0,0 +1,5 @@ +from dify_oapi.core.model.base_response import BaseResponse + + +class AudioToTextResponse(BaseResponse): + text: str | None = None diff --git a/sdks/python-client/dify_oapi/api/chat/v1/model/chat_request.py b/sdks/python-client/dify_oapi/api/chat/v1/model/chat_request.py new file mode 100755 index 0000000000..f6130582e3 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/chat/v1/model/chat_request.py @@ -0,0 +1,32 @@ +from __future__ import annotations + +from dify_oapi.core.enum import HttpMethod +from dify_oapi.core.model.base_request import BaseRequest + +from .chat_request_body import ChatRequestBody + + +class ChatRequest(BaseRequest): + def __init__(self) -> None: + super().__init__() + self.request_body: ChatRequestBody | None = None + + @staticmethod + def builder() -> ChatRequestBuilder: + return ChatRequestBuilder() + + +class ChatRequestBuilder: + def __init__(self) -> None: + chat_request = ChatRequest() + chat_request.http_method = HttpMethod.POST + chat_request.uri = "/v1/chat-messages" + self._chat_request: ChatRequest = chat_request + + def request_body(self, request_body: ChatRequestBody) -> ChatRequestBuilder: + self._chat_request.request_body = request_body + self._chat_request.body = request_body.model_dump(exclude_none=True) + return self + + def build(self) -> ChatRequest: + return self._chat_request diff --git a/sdks/python-client/dify_oapi/api/chat/v1/model/chat_request_body.py b/sdks/python-client/dify_oapi/api/chat/v1/model/chat_request_body.py new file mode 100755 index 0000000000..68d1173a16 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/chat/v1/model/chat_request_body.py @@ -0,0 +1,57 @@ +from __future__ import annotations + +from pydantic import BaseModel + +from .chat_request_file import ChatRequestFile + + +class ChatRequestBody(BaseModel): + query: str | None = None + inputs: dict | None = None + response_mode: str | None = None + user: str | None = None + conversation_id: str | None = None + files: list[ChatRequestFile] | None = None + auto_generate_name: bool | None = None + + @staticmethod + def builder() -> ChatRequestBodyBuilder: + return ChatRequestBodyBuilder() + + +class ChatRequestBodyBuilder: + def __init__(self): + self._chat_request_body = ChatRequestBody() + + def query(self, query: str) -> ChatRequestBodyBuilder: + self._chat_request_body.query = query + return self + + def inputs(self, inputs: dict) -> ChatRequestBodyBuilder: + self._chat_request_body.inputs = inputs + return self + + def response_mode(self, response_mode: str) -> ChatRequestBodyBuilder: + if response_mode not in ["streaming", "blocking"]: + raise ValueError('response_mode must be either "streaming" or "blocking"') + self._chat_request_body.response_mode = response_mode + return self + + def user(self, user: str) -> ChatRequestBodyBuilder: + self._chat_request_body.user = user + return self + + def conversation_id(self, conversation_id: str) -> ChatRequestBodyBuilder: + self._chat_request_body.conversation_id = conversation_id + return self + + def files(self, files: list[ChatRequestFile]) -> ChatRequestBodyBuilder: + self._chat_request_body.files = files + return self + + def auto_generate_name(self, auto_generate_name: bool) -> ChatRequestBodyBuilder: + self._chat_request_body.auto_generate_name = auto_generate_name + return self + + def build(self): + return self._chat_request_body diff --git a/sdks/python-client/dify_oapi/api/chat/v1/model/chat_request_file.py b/sdks/python-client/dify_oapi/api/chat/v1/model/chat_request_file.py new file mode 100755 index 0000000000..4c68eabae1 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/chat/v1/model/chat_request_file.py @@ -0,0 +1,56 @@ +from __future__ import annotations + +from pydantic import BaseModel, HttpUrl + + +class ChatRequestFile(BaseModel): + type: str | None = None + transfer_method: str | None = None + url: HttpUrl | None = None + upload_file_id: str | None = None + + @staticmethod + def builder() -> ChatRequestFileBuilder: + return ChatRequestFileBuilder() + + +class ChatRequestFileBuilder: + def __init__(self): + self._chat_request_file = ChatRequestFile() + + def type(self, type_: str): + if type_ != "image": + raise ValueError("Only 'image' is supported") + self._chat_request_file.type = type_ + return self + + def transfer_method(self, transfer_method: str): + if transfer_method not in ("remote_url", "local_file"): + raise ValueError("Only 'remote_url' and 'local_file' are supported") + self._chat_request_file.transfer_method = transfer_method + return self + + def url(self, url: str): + self._chat_request_file.url = HttpUrl(url=url) + return self + + def upload_file_id(self, upload_file_id: str): + self._chat_request_file.upload_file_id = upload_file_id + return self + + def build(self) -> ChatRequestFile: + if ( + self._chat_request_file.transfer_method == "remote_url" + and self._chat_request_file.url is None + ): + raise ValueError( + "Url needs to be set when transfer_method is set as remote_url" + ) + if ( + self._chat_request_file.transfer_method == "local_file" + and self._chat_request_file.upload_file_id is None + ): + raise ValueError( + "Upload file_id needs to be set when transfer_method is set as local_file" + ) + return self._chat_request_file diff --git a/sdks/python-client/dify_oapi/api/chat/v1/model/chat_response.py b/sdks/python-client/dify_oapi/api/chat/v1/model/chat_response.py new file mode 100755 index 0000000000..c148730296 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/chat/v1/model/chat_response.py @@ -0,0 +1,19 @@ +from __future__ import annotations + +from pydantic import BaseModel + +from dify_oapi.core.model.base_response import BaseResponse + + +class ChatResponse(BaseResponse): + message_id: str | None = None + conversation_id: str | None = None + mode: str | None = None + answer: str | None = None + metadata: ChatResponseMetadata | None = None + created_at: int | None = None + + +class ChatResponseMetadata(BaseModel): + usage: dict | None = None + retriever_resources: list[dict] | None = None diff --git a/sdks/python-client/dify_oapi/api/chat/v1/model/delete_conversation_request.py b/sdks/python-client/dify_oapi/api/chat/v1/model/delete_conversation_request.py new file mode 100755 index 0000000000..b0a9c68aa3 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/chat/v1/model/delete_conversation_request.py @@ -0,0 +1,42 @@ +from __future__ import annotations + +from dify_oapi.core.enum import HttpMethod +from dify_oapi.core.model.base_request import BaseRequest + +from .delete_conversation_request_body import DeleteConversationRequestBody + + +class DeleteConversationRequest(BaseRequest): + def __init__(self): + super().__init__() + self.conversation_id: str | None = None + self.request_body: DeleteConversationRequestBody | None = None + + @staticmethod + def builder() -> DeleteConversationRequestBuilder: + return DeleteConversationRequestBuilder() + + +class DeleteConversationRequestBuilder: + def __init__(self): + delete_conversation_request = DeleteConversationRequest() + delete_conversation_request.http_method = HttpMethod.DELETE + delete_conversation_request.uri = "/v1/conversations/:conversation_id" + self._delete_conversation_request = delete_conversation_request + + def request_body( + self, request_body: DeleteConversationRequestBody + ) -> DeleteConversationRequestBuilder: + self._delete_conversation_request.request_body = request_body + self._delete_conversation_request.body = request_body.model_dump( + exclude_none=True + ) + return self + + def conversation_id(self, conversation_id: str) -> DeleteConversationRequestBuilder: + self._delete_conversation_request.conversation_id = conversation_id + self._delete_conversation_request.paths["conversation_id"] = conversation_id + return self + + def build(self) -> DeleteConversationRequest: + return self._delete_conversation_request diff --git a/sdks/python-client/dify_oapi/api/chat/v1/model/delete_conversation_request_body.py b/sdks/python-client/dify_oapi/api/chat/v1/model/delete_conversation_request_body.py new file mode 100755 index 0000000000..dcdd297411 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/chat/v1/model/delete_conversation_request_body.py @@ -0,0 +1,23 @@ +from __future__ import annotations + +from pydantic import BaseModel + + +class DeleteConversationRequestBody(BaseModel): + user: str | None = None + + @staticmethod + def builder() -> DeleteConversationRequestBodyBuilder: + return DeleteConversationRequestBodyBuilder() + + +class DeleteConversationRequestBodyBuilder: + def __init__(self): + self._delete_conversation_request_body = DeleteConversationRequestBody() + + def user(self, user: str): + self._delete_conversation_request_body.user = user + return self + + def build(self) -> DeleteConversationRequestBody: + return self._delete_conversation_request_body diff --git a/sdks/python-client/dify_oapi/api/chat/v1/model/delete_conversation_response.py b/sdks/python-client/dify_oapi/api/chat/v1/model/delete_conversation_response.py new file mode 100755 index 0000000000..547d3abf0e --- /dev/null +++ b/sdks/python-client/dify_oapi/api/chat/v1/model/delete_conversation_response.py @@ -0,0 +1,5 @@ +from dify_oapi.core.model.base_response import BaseResponse + + +class DeleteConversationResponse(BaseResponse): + result: str | None = None diff --git a/sdks/python-client/dify_oapi/api/chat/v1/model/get_conversation_list_request.py b/sdks/python-client/dify_oapi/api/chat/v1/model/get_conversation_list_request.py new file mode 100755 index 0000000000..baae21a872 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/chat/v1/model/get_conversation_list_request.py @@ -0,0 +1,48 @@ +from __future__ import annotations + +from dify_oapi.core.enum import HttpMethod +from dify_oapi.core.model.base_request import BaseRequest + + +class GetConversationListRequest(BaseRequest): + def __init__(self): + super().__init__() + self.user: str | None = None + self.last_id: str | None = None + self.limit: int | None = None + self.pinned: bool | None = None + + @staticmethod + def builder() -> GetConversationListRequestBuilder: + return GetConversationListRequestBuilder() + + +class GetConversationListRequestBuilder: + def __init__(self): + get_conversation_list_request = GetConversationListRequest() + get_conversation_list_request.http_method = HttpMethod.GET + get_conversation_list_request.uri = "/v1/conversations" + self._get_conversation_list_request = get_conversation_list_request + + def user(self, user: str) -> GetConversationListRequestBuilder: + self._get_conversation_list_request.user = user + self._get_conversation_list_request.add_query("user", user) + return self + + def last_id(self, last_id: str) -> GetConversationListRequestBuilder: + self._get_conversation_list_request.last_id = last_id + self._get_conversation_list_request.add_query("last_id", last_id) + return self + + def limit(self, limit: int) -> GetConversationListRequestBuilder: + self._get_conversation_list_request.limit = limit + self._get_conversation_list_request.add_query("limit", limit) + return self + + def pinned(self, pinned: bool) -> GetConversationListRequestBuilder: + self._get_conversation_list_request.pinned = pinned + self._get_conversation_list_request.add_query("pinned", str(pinned).lower()) + return self + + def build(self) -> GetConversationListRequest: + return self._get_conversation_list_request diff --git a/sdks/python-client/dify_oapi/api/chat/v1/model/get_conversation_list_response.py b/sdks/python-client/dify_oapi/api/chat/v1/model/get_conversation_list_response.py new file mode 100755 index 0000000000..19cd168f8e --- /dev/null +++ b/sdks/python-client/dify_oapi/api/chat/v1/model/get_conversation_list_response.py @@ -0,0 +1,21 @@ +from __future__ import annotations + +from pydantic import BaseModel + +from dify_oapi.core.model.base_response import BaseResponse + + +class GetConversationListResponse(BaseResponse): + data: list[GetConversationListData] | None = None + has_more: bool | None = None + limit: int | None = None + + +class GetConversationListData(BaseModel): + id: str | None = None + name: str | None = None + inputs: dict | None = None + status: str | None = None + introduction: str | None = None + created_at: int | None = None + updated_at: int | None = None diff --git a/sdks/python-client/dify_oapi/api/chat/v1/model/message_history_request.py b/sdks/python-client/dify_oapi/api/chat/v1/model/message_history_request.py new file mode 100755 index 0000000000..7b3d28246a --- /dev/null +++ b/sdks/python-client/dify_oapi/api/chat/v1/model/message_history_request.py @@ -0,0 +1,48 @@ +from __future__ import annotations + +from dify_oapi.core.enum import HttpMethod +from dify_oapi.core.model.base_request import BaseRequest + + +class MessageHistoryRequest(BaseRequest): + def __init__(self): + super().__init__() + self.conversation_id: str | None = None + self.user: str | None = None + self.first_id: str | None = None + self.limit: int | None = None + + @staticmethod + def builder() -> MessageHistoryRequestBuilder: + return MessageHistoryRequestBuilder() + + +class MessageHistoryRequestBuilder: + def __init__(self): + message_history_request = MessageHistoryRequest() + message_history_request.http_method = HttpMethod.GET + message_history_request.uri = "/v1/messages" + self._message_history_request = message_history_request + + def build(self) -> MessageHistoryRequest: + return self._message_history_request + + def conversation_id(self, conversation_id: str): + self._message_history_request.conversation_id = conversation_id + self._message_history_request.add_query("conversation_id", conversation_id) + return self + + def user(self, user: str): + self._message_history_request.user = user + self._message_history_request.add_query("user", user) + return self + + def first_id(self, first_id: str): + self._message_history_request.first_id = first_id + self._message_history_request.add_query("first_id", first_id) + return self + + def limit(self, limit: int): + self._message_history_request.limit = limit + self._message_history_request.add_query("limit", limit) + return self diff --git a/sdks/python-client/dify_oapi/api/chat/v1/model/message_history_response.py b/sdks/python-client/dify_oapi/api/chat/v1/model/message_history_response.py new file mode 100755 index 0000000000..c1f9cd816e --- /dev/null +++ b/sdks/python-client/dify_oapi/api/chat/v1/model/message_history_response.py @@ -0,0 +1,49 @@ +from __future__ import annotations + +from pydantic import BaseModel + +from dify_oapi.core.model.base_response import BaseResponse + + +class MessageHistoryResponse(BaseResponse): + data: list[dict] | None = None + id: str | None = None + conversation_id: str | None = None + inputs: list[dict] | None = None + query: str | None = None + message_files: list[MessageHistoryResponseFile] | None = None + answer: str | None = None + created_at: int | None = None + feedback: MessageHistoryResponseFeedback | None = None + retriever_resources: list[dict] | None = None + has_more: bool | None = None + limit: int | None = None + + +class MessageHistoryResponseFeedback(BaseModel): + rating: str | None = None + + +class MessageHistoryResponseFile(BaseModel): + id: str | None = None + type: str | None = None + url: str | None = None + belongs_to: str | None = None + agent_thoughts: list[MessageHistoryResponseFileAgentThought] | None = None + + +class MessageHistoryResponseFileAgentThought(BaseResponse): + id: str | None = None + message_id: str | None = None + position: int | None = None + thought: str | None = None + observation: str | None = None + tool: str | None = None + tool_input: str | None = None + created_at: int | None = None + message_files: list[MessageHistoryResponseFileAgentThoughtFile] | None = None + conversation_id: str | None = None + + +class MessageHistoryResponseFileAgentThoughtFile(BaseModel): + file_id: str | None = None diff --git a/sdks/python-client/dify_oapi/api/chat/v1/model/message_suggested_request.py b/sdks/python-client/dify_oapi/api/chat/v1/model/message_suggested_request.py new file mode 100755 index 0000000000..ab044c578e --- /dev/null +++ b/sdks/python-client/dify_oapi/api/chat/v1/model/message_suggested_request.py @@ -0,0 +1,36 @@ +from __future__ import annotations + +from dify_oapi.core.enum import HttpMethod +from dify_oapi.core.model.base_request import BaseRequest + + +class MessageSuggestedRequest(BaseRequest): + def __init__(self): + super().__init__() + self.message_id: str | None = None + self.user: str | None = None + + @staticmethod + def builder() -> MessageSuggestedRequestBuilder: + return MessageSuggestedRequestBuilder() + + +class MessageSuggestedRequestBuilder: + def __init__(self): + message_suggested_request = MessageSuggestedRequest() + message_suggested_request.http_method = HttpMethod.GET + message_suggested_request.uri = "/v1/messages/:message_id/suggested" + self._message_suggested_request = message_suggested_request + + def build(self) -> MessageSuggestedRequest: + return self._message_suggested_request + + def message_id(self, message_id: str): + self._message_suggested_request.message_id = message_id + self._message_suggested_request.paths["message_id"] = message_id + return self + + def user(self, user: str): + self._message_suggested_request.user = user + self._message_suggested_request.add_query("user", user) + return self diff --git a/sdks/python-client/dify_oapi/api/chat/v1/model/message_suggested_response.py b/sdks/python-client/dify_oapi/api/chat/v1/model/message_suggested_response.py new file mode 100755 index 0000000000..987618f4ff --- /dev/null +++ b/sdks/python-client/dify_oapi/api/chat/v1/model/message_suggested_response.py @@ -0,0 +1,6 @@ +from dify_oapi.core.model.base_response import BaseResponse + + +class MessageSuggestedResponse(BaseResponse): + result: str | None = None + data: list[str] | None = None diff --git a/sdks/python-client/dify_oapi/api/chat/v1/model/rename_conversation_request.py b/sdks/python-client/dify_oapi/api/chat/v1/model/rename_conversation_request.py new file mode 100755 index 0000000000..1c815cf344 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/chat/v1/model/rename_conversation_request.py @@ -0,0 +1,42 @@ +from __future__ import annotations + +from dify_oapi.core.enum import HttpMethod +from dify_oapi.core.model.base_request import BaseRequest + +from .rename_conversation_request_body import RenameConversationRequestBody + + +class RenameConversationRequest(BaseRequest): + def __init__(self): + super().__init__() + self.conversation_id: str | None = None + self.request_body: RenameConversationRequestBody | None = None + + @staticmethod + def builder() -> RenameConversationRequestBuilder: + return RenameConversationRequestBuilder() + + +class RenameConversationRequestBuilder: + def __init__(self): + rename_conversation_request = RenameConversationRequest() + rename_conversation_request.http_method = HttpMethod.POST + rename_conversation_request.uri = "/v1/conversations/:conversation_id/name" + self._rename_conversation_request = rename_conversation_request + + def build(self) -> RenameConversationRequest: + return self._rename_conversation_request + + def request_body( + self, request_body: RenameConversationRequestBody + ) -> RenameConversationRequestBuilder: + self._rename_conversation_request.request_body = request_body + self._rename_conversation_request.body = request_body.model_dump( + exclude_none=True + ) + return self + + def conversation_id(self, conversation_id: str) -> RenameConversationRequestBuilder: + self._rename_conversation_request.conversation_id = conversation_id + self._rename_conversation_request.paths["conversation_id"] = conversation_id + return self diff --git a/sdks/python-client/dify_oapi/api/chat/v1/model/rename_conversation_request_body.py b/sdks/python-client/dify_oapi/api/chat/v1/model/rename_conversation_request_body.py new file mode 100755 index 0000000000..721609c481 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/chat/v1/model/rename_conversation_request_body.py @@ -0,0 +1,35 @@ +from __future__ import annotations + +from pydantic import BaseModel + + +class RenameConversationRequestBody(BaseModel): + name: str | None = None + auto_generate: bool | None = None + user: str | None = None + + @staticmethod + def builder() -> RenameConversationRequestBodyBuilder: + return RenameConversationRequestBodyBuilder() + + +class RenameConversationRequestBodyBuilder: + def __init__(self): + self._rename_conversation_request_body = RenameConversationRequestBody() + + def builder(self) -> RenameConversationRequestBody: + return self._rename_conversation_request_body + + def name(self, name: str) -> RenameConversationRequestBodyBuilder: + self._rename_conversation_request_body.name = name + return self + + def auto_generate( + self, auto_generate: bool + ) -> RenameConversationRequestBodyBuilder: + self._rename_conversation_request_body.auto_generate = auto_generate + return self + + def user(self, user: str) -> RenameConversationRequestBodyBuilder: + self._rename_conversation_request_body.user = user + return self diff --git a/sdks/python-client/dify_oapi/api/chat/v1/model/rename_conversation_response.py b/sdks/python-client/dify_oapi/api/chat/v1/model/rename_conversation_response.py new file mode 100755 index 0000000000..45d43c2b7f --- /dev/null +++ b/sdks/python-client/dify_oapi/api/chat/v1/model/rename_conversation_response.py @@ -0,0 +1,11 @@ +from dify_oapi.core.model.base_response import BaseResponse + + +class RenameConversationResponse(BaseResponse): + id: str | None = None + result: str | None = None + inputs: dict | None = None + status: str | None = None + introduction: str | None = None + created_at: int | None = None + updated_at: int | None = None diff --git a/sdks/python-client/dify_oapi/api/chat/v1/model/stop_chat_request.py b/sdks/python-client/dify_oapi/api/chat/v1/model/stop_chat_request.py new file mode 100755 index 0000000000..ce673e86b7 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/chat/v1/model/stop_chat_request.py @@ -0,0 +1,38 @@ +from __future__ import annotations + +from dify_oapi.core.enum import HttpMethod +from dify_oapi.core.model.base_request import BaseRequest + +from .stop_chat_request_body import StopChatRequestBody + + +class StopChatRequest(BaseRequest): + def __init__(self) -> None: + super().__init__() + self.task_id: str | None = None + self.request_body: StopChatRequestBody | None = None + + @staticmethod + def builder() -> StopChatRequestBuilder: + return StopChatRequestBuilder() + + +class StopChatRequestBuilder: + def __init__(self) -> None: + stop_chat_request = StopChatRequest() + stop_chat_request.http_method = HttpMethod.POST + stop_chat_request.uri = "/v1/chat-messages/:task_id/stop" + self._stop_chat_request: StopChatRequest = stop_chat_request + + def task_id(self, task_id: str) -> StopChatRequestBuilder: + self._stop_chat_request.task_id = task_id + self._stop_chat_request.paths["task_id"] = str(task_id) + return self + + def request_body(self, request_body: StopChatRequestBody) -> StopChatRequestBuilder: + self._stop_chat_request.request_body = request_body + self._stop_chat_request.body = request_body.model_dump(exclude_none=True) + return self + + def build(self) -> StopChatRequest: + return self._stop_chat_request diff --git a/sdks/python-client/dify_oapi/api/chat/v1/model/stop_chat_request_body.py b/sdks/python-client/dify_oapi/api/chat/v1/model/stop_chat_request_body.py new file mode 100755 index 0000000000..7d21d18700 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/chat/v1/model/stop_chat_request_body.py @@ -0,0 +1,23 @@ +from __future__ import annotations + +from pydantic import BaseModel + + +class StopChatRequestBody(BaseModel): + user: str | None = None + + @staticmethod + def builder() -> StopChatRequestBodyBuilder: + return StopChatRequestBodyBuilder() + + +class StopChatRequestBodyBuilder: + def __init__(self): + self._stop_chat_request_body = StopChatRequestBody() + + def user(self, user: str) -> StopChatRequestBodyBuilder: + self._stop_chat_request_body.user = user + return self + + def build(self) -> StopChatRequestBody: + return self._stop_chat_request_body diff --git a/sdks/python-client/dify_oapi/api/chat/v1/model/stop_chat_response.py b/sdks/python-client/dify_oapi/api/chat/v1/model/stop_chat_response.py new file mode 100755 index 0000000000..e2b64de065 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/chat/v1/model/stop_chat_response.py @@ -0,0 +1,5 @@ +from dify_oapi.core.model.base_response import BaseResponse + + +class StopChatResponse(BaseResponse): + result: str | None = None diff --git a/sdks/python-client/dify_oapi/api/chat/v1/resource/__init__.py b/sdks/python-client/dify_oapi/api/chat/v1/resource/__init__.py new file mode 100755 index 0000000000..07889f06d1 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/chat/v1/resource/__init__.py @@ -0,0 +1,4 @@ +from .chat import * # noqa F403 +from .conversation import * # noqa 403 +from .message import * # noqa 403 +from .audio import * # noqa 403 diff --git a/sdks/python-client/dify_oapi/api/chat/v1/resource/audio.py b/sdks/python-client/dify_oapi/api/chat/v1/resource/audio.py new file mode 100644 index 0000000000..96448bbcbf --- /dev/null +++ b/sdks/python-client/dify_oapi/api/chat/v1/resource/audio.py @@ -0,0 +1,25 @@ +from dify_oapi.core.http.transport import ATransport, Transport +from dify_oapi.core.model.config import Config +from dify_oapi.core.model.request_option import RequestOption + +from ..model.audio_to_text_request import AudioToTextRequest +from ..model.audio_to_text_response import AudioToTextResponse + + +class Audio: + def __init__(self, config: Config) -> None: + self.config: Config = config + + def to_text( + self, request: AudioToTextRequest, option: RequestOption | None = None + ) -> AudioToTextResponse: + return Transport.execute( + self.config, request, unmarshal_as=AudioToTextResponse, option=option + ) + + async def ato_text( + self, request: AudioToTextRequest, option: RequestOption | None = None + ) -> AudioToTextResponse: + return await ATransport.aexecute( + self.config, request, unmarshal_as=AudioToTextResponse, option=option + ) diff --git a/sdks/python-client/dify_oapi/api/chat/v1/resource/chat.py b/sdks/python-client/dify_oapi/api/chat/v1/resource/chat.py new file mode 100755 index 0000000000..c8c72fbb5f --- /dev/null +++ b/sdks/python-client/dify_oapi/api/chat/v1/resource/chat.py @@ -0,0 +1,93 @@ +from collections.abc import AsyncGenerator, Generator +from typing import Literal, overload + +from dify_oapi.core.const import APPLICATION_JSON, CONTENT_TYPE +from dify_oapi.core.http.transport import ATransport, Transport +from dify_oapi.core.model.config import Config +from dify_oapi.core.model.request_option import RequestOption + +from ..model.chat_request import ChatRequest +from ..model.chat_response import ChatResponse +from ..model.stop_chat_request import StopChatRequest +from ..model.stop_chat_response import StopChatResponse + + +class Chat: + def __init__(self, config: Config) -> None: + self.config: Config = config + + @overload + def chat( + self, request: ChatRequest, option: RequestOption | None, stream: Literal[True] + ) -> Generator[bytes, None, None]: ... + + @overload + def chat( + self, request: ChatRequest, option: RequestOption | None, stream: Literal[False] + ) -> ChatResponse: ... + + @overload + def chat( + self, request: ChatRequest, option: RequestOption | None + ) -> ChatResponse: ... + + def chat( + self, + request: ChatRequest, + option: RequestOption | None = None, + stream: bool = False, + ): + if request.body is not None: + option.headers[CONTENT_TYPE] = f"{APPLICATION_JSON}; charset=utf-8" + if stream: + return Transport.execute(self.config, request, option=option, stream=True) + else: + return Transport.execute( + self.config, request, unmarshal_as=ChatResponse, option=option + ) + + @overload + async def achat( + self, request: ChatRequest, option: RequestOption | None, stream: Literal[True] + ) -> AsyncGenerator[bytes, None]: ... + + @overload + def achat( + self, request: ChatRequest, option: RequestOption | None, stream: Literal[False] + ) -> ChatResponse: ... + + @overload + async def achat( + self, request: ChatRequest, option: RequestOption | None + ) -> ChatResponse: ... + + async def achat( + self, + request: ChatRequest, + option: RequestOption | None = None, + stream: bool = False, + ): + if stream: + return await ATransport.aexecute( + self.config, request, option=option, stream=True + ) + else: + return await ATransport.aexecute( + self.config, request, unmarshal_as=ChatResponse, option=option + ) + + def stop( + self, request: StopChatRequest, option: RequestOption | None = None + ) -> StopChatResponse: + if request.body is not None: + option.headers[CONTENT_TYPE] = f"{APPLICATION_JSON}; charset=utf-8" + return Transport.execute( + self.config, request, unmarshal_as=StopChatResponse, option=option + ) + + async def astop( + self, request: StopChatRequest, option: RequestOption | None = None + ) -> StopChatResponse: + return await ATransport.aexecute( + self.config, request, unmarshal_as=StopChatResponse, option=option + ) diff --git a/sdks/python-client/dify_oapi/api/chat/v1/resource/conversation.py b/sdks/python-client/dify_oapi/api/chat/v1/resource/conversation.py new file mode 100755 index 0000000000..d85b83e8d4 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/chat/v1/resource/conversation.py @@ -0,0 +1,76 @@ +from dify_oapi.core.const import APPLICATION_JSON, CONTENT_TYPE +from dify_oapi.core.http.transport import ATransport, Transport +from dify_oapi.core.model.config import Config +from dify_oapi.core.model.request_option import RequestOption + +from ..model.delete_conversation_request import DeleteConversationRequest +from ..model.delete_conversation_response import DeleteConversationResponse +from ..model.get_conversation_list_request import GetConversationListRequest +from ..model.get_conversation_list_response import GetConversationListResponse +from ..model.rename_conversation_request import RenameConversationRequest +from ..model.rename_conversation_response import RenameConversationResponse + + +class Conversation: + def __init__(self, config: Config) -> None: + self.config: Config = config + + def list( + self, request: GetConversationListRequest, option: RequestOption | None = None + ) -> GetConversationListResponse: + # 添加 content-type + if request.body is not None: + option.headers[CONTENT_TYPE] = f"{APPLICATION_JSON}; charset=utf-8" + + # 发起请求 + return Transport.execute( + self.config, + request, + unmarshal_as=GetConversationListResponse, + option=option, + ) + + async def alist( + self, request: GetConversationListRequest, option: RequestOption | None = None + ) -> GetConversationListResponse: + # 发起请求 + return await ATransport.aexecute( + self.config, + request, + unmarshal_as=GetConversationListResponse, + option=option, + ) + + def delete( + self, request: DeleteConversationRequest, option: RequestOption | None = None + ) -> DeleteConversationResponse: + if request.body is not None: + option.headers[CONTENT_TYPE] = f"{APPLICATION_JSON}; charset=utf-8" + return Transport.execute( + self.config, request, unmarshal_as=DeleteConversationResponse, option=option + ) + + async def adelete( + self, request: DeleteConversationRequest, option: RequestOption | None = None + ) -> DeleteConversationResponse: + # 发起请求 + return await ATransport.aexecute( + self.config, request, unmarshal_as=DeleteConversationResponse, option=option + ) + + def rename( + self, request: RenameConversationRequest, option: RequestOption | None = None + ) -> RenameConversationResponse: + if request.body is not None: + option.headers[CONTENT_TYPE] = f"{APPLICATION_JSON}; charset=utf-8" + return Transport.execute( + self.config, request, unmarshal_as=RenameConversationResponse, option=option + ) + + async def arename( + self, request: RenameConversationRequest, option: RequestOption | None = None + ) -> RenameConversationResponse: + # 发起请求 + return await ATransport.aexecute( + self.config, request, unmarshal_as=RenameConversationResponse, option=option + ) diff --git a/sdks/python-client/dify_oapi/api/chat/v1/resource/message.py b/sdks/python-client/dify_oapi/api/chat/v1/resource/message.py new file mode 100755 index 0000000000..31eb53e04d --- /dev/null +++ b/sdks/python-client/dify_oapi/api/chat/v1/resource/message.py @@ -0,0 +1,54 @@ +from dify_oapi.core.const import APPLICATION_JSON, CONTENT_TYPE +from dify_oapi.core.http.transport import ATransport, Transport +from dify_oapi.core.model.config import Config +from dify_oapi.core.model.request_option import RequestOption + +from ..model.message_history_request import MessageHistoryRequest +from ..model.message_history_response import MessageHistoryResponse +from ..model.message_suggested_request import MessageSuggestedRequest +from ..model.message_suggested_response import MessageSuggestedResponse + + +class Message: + def __init__(self, config: Config) -> None: + self.config: Config = config + + def suggested( + self, request: MessageSuggestedRequest, option: RequestOption | None = None + ) -> MessageSuggestedResponse: + # 添加 content-type + if request.body is not None: + option.headers[CONTENT_TYPE] = f"{APPLICATION_JSON}; charset=utf-8" + + # 发起请求 + return Transport.execute( + self.config, request, unmarshal_as=MessageSuggestedResponse, option=option + ) + + async def asuggested( + self, request: MessageSuggestedRequest, option: RequestOption | None = None + ) -> MessageSuggestedResponse: + # 发起请求 + return await ATransport.aexecute( + self.config, request, unmarshal_as=MessageSuggestedResponse, option=option + ) + + def history( + self, request: MessageHistoryRequest, option: RequestOption | None = None + ) -> MessageHistoryResponse: + # 添加 content-type + if request.body is not None: + option.headers[CONTENT_TYPE] = f"{APPLICATION_JSON}; charset=utf-8" + + # 发起请求 + return Transport.execute( + self.config, request, unmarshal_as=MessageHistoryResponse, option=option + ) + + async def ahistory( + self, request: MessageHistoryRequest, option: RequestOption | None = None + ) -> MessageHistoryResponse: + # 发起请求 + return await ATransport.aexecute( + self.config, request, unmarshal_as=MessageHistoryResponse, option=option + ) diff --git a/sdks/python-client/dify_oapi/api/chat/v1/version.py b/sdks/python-client/dify_oapi/api/chat/v1/version.py new file mode 100755 index 0000000000..08f46fa2d0 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/chat/v1/version.py @@ -0,0 +1,11 @@ +from dify_oapi.core.model.config import Config + +from .resource import Chat, Conversation, Message, Audio + + +class V1: + def __init__(self, config: Config): + self.chat: Chat = Chat(config) + self.conversation: Conversation = Conversation(config) + self.message: Message = Message(config) + self.audio: Audio = Audio(config) diff --git a/sdks/python-client/dify_oapi/api/completion/__init__.py b/sdks/python-client/dify_oapi/api/completion/__init__.py new file mode 100755 index 0000000000..e69de29bb2 diff --git a/sdks/python-client/dify_oapi/api/completion/service.py b/sdks/python-client/dify_oapi/api/completion/service.py new file mode 100755 index 0000000000..9d841a19da --- /dev/null +++ b/sdks/python-client/dify_oapi/api/completion/service.py @@ -0,0 +1,8 @@ +from dify_oapi.core.model.config import Config + +from .v1.version import V1 + + +class CompletionService: + def __init__(self, config: Config) -> None: + self.v1: V1 = V1(config) diff --git a/sdks/python-client/dify_oapi/api/completion/v1/__init__.py b/sdks/python-client/dify_oapi/api/completion/v1/__init__.py new file mode 100755 index 0000000000..e69de29bb2 diff --git a/sdks/python-client/dify_oapi/api/completion/v1/model/__init__.py b/sdks/python-client/dify_oapi/api/completion/v1/model/__init__.py new file mode 100755 index 0000000000..e69de29bb2 diff --git a/sdks/python-client/dify_oapi/api/completion/v1/model/completion_request.py b/sdks/python-client/dify_oapi/api/completion/v1/model/completion_request.py new file mode 100755 index 0000000000..765698a4e8 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/completion/v1/model/completion_request.py @@ -0,0 +1,34 @@ +from __future__ import annotations + +from dify_oapi.core.enum import HttpMethod +from dify_oapi.core.model.base_request import BaseRequest + +from .completion_request_body import CompletionRequestBody + + +class CompletionRequest(BaseRequest): + def __init__(self) -> None: + super().__init__() + self.request_body: CompletionRequestBody | None = None + + @staticmethod + def builder() -> CompletionRequestBuilder: + return CompletionRequestBuilder() + + +class CompletionRequestBuilder: + def __init__(self) -> None: + completion_request = CompletionRequest() + completion_request.http_method = HttpMethod.POST + completion_request.uri = "/v1/completion-messages" + self._completion_request: CompletionRequest = completion_request + + def request_body( + self, request_body: CompletionRequestBody + ) -> CompletionRequestBuilder: + self._completion_request.request_body = request_body + self._completion_request.body = request_body.model_dump(exclude_none=True) + return self + + def build(self) -> CompletionRequest: + return self._completion_request diff --git a/sdks/python-client/dify_oapi/api/completion/v1/model/completion_request_body.py b/sdks/python-client/dify_oapi/api/completion/v1/model/completion_request_body.py new file mode 100755 index 0000000000..d63f7857ac --- /dev/null +++ b/sdks/python-client/dify_oapi/api/completion/v1/model/completion_request_body.py @@ -0,0 +1,45 @@ +from __future__ import annotations + +from pydantic import BaseModel + +from .completion_request_body_input import CompletionRequestBodyInput +from .completion_request_file import CompletionRequestFile + + +class CompletionRequestBody(BaseModel): + inputs: CompletionRequestBodyInput | None = None + response_mode: str | None = None + user: str | None = None + files: list[CompletionRequestFile] | None = None + + @staticmethod + def builder() -> CompletionRequestBodyBuilder: + return CompletionRequestBodyBuilder() + + +class CompletionRequestBodyBuilder: + def __init__(self): + self._completion_request_body = CompletionRequestBody() + + def inputs( + self, inputs: CompletionRequestBodyInput + ) -> CompletionRequestBodyBuilder: + self._completion_request_body.inputs = inputs.model_dump(exclude_none=True) + return self + + def response_mode(self, response_mode: str) -> CompletionRequestBodyBuilder: + if response_mode not in ["streaming", "blocking"]: + raise ValueError('response_mode must be either "streaming" or "blocking"') + self._completion_request_body.response_mode = response_mode + return self + + def user(self, user: str) -> CompletionRequestBodyBuilder: + self._completion_request_body.user = user + return self + + def files(self, files: list[CompletionRequestFile]) -> CompletionRequestBodyBuilder: + self._completion_request_body.files = files + return self + + def build(self): + return self._completion_request_body diff --git a/sdks/python-client/dify_oapi/api/completion/v1/model/completion_request_body_input.py b/sdks/python-client/dify_oapi/api/completion/v1/model/completion_request_body_input.py new file mode 100755 index 0000000000..7b4893c05d --- /dev/null +++ b/sdks/python-client/dify_oapi/api/completion/v1/model/completion_request_body_input.py @@ -0,0 +1,25 @@ +from __future__ import annotations + +from pydantic import BaseModel + + +class CompletionRequestBodyInput(BaseModel): + query: str | None = None + + @staticmethod + def builder() -> CompletionRequestBodyInputBuilder: + return CompletionRequestBodyInputBuilder() + + +class CompletionRequestBodyInputBuilder: + def __init__(self): + self._completion_request_body_input = CompletionRequestBodyInput() + + def build(self) -> CompletionRequestBodyInput: + if self._completion_request_body_input.query is None: + raise ValueError("CompletionRequestBodyInput.query is None") + return self._completion_request_body_input + + def query(self, query: str): + self._completion_request_body_input.query = query + return self diff --git a/sdks/python-client/dify_oapi/api/completion/v1/model/completion_request_file.py b/sdks/python-client/dify_oapi/api/completion/v1/model/completion_request_file.py new file mode 100755 index 0000000000..3ba382adc7 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/completion/v1/model/completion_request_file.py @@ -0,0 +1,56 @@ +from __future__ import annotations + +from pydantic import BaseModel, HttpUrl + + +class CompletionRequestFile(BaseModel): + type: str | None = None + transfer_method: str | None = None + url: HttpUrl | None = None + upload_file_id: str | None = None + + @staticmethod + def builder() -> CompletionRequestFileBuilder: + return CompletionRequestFileBuilder() + + +class CompletionRequestFileBuilder: + def __init__(self): + self._completion_request_file = CompletionRequestFile() + + def type(self, type_: str): + if type_ != "image": + raise ValueError("Only 'image' is supported") + self._completion_request_file.type = type_ + return self + + def transfer_method(self, transfer_method: str): + if transfer_method not in ("remote_url", "local_file"): + raise ValueError("Only 'remote_url' and 'local_file' are supported") + self._completion_request_file.transfer_method = transfer_method + return self + + def url(self, url: str): + self._completion_request_file.url = HttpUrl(url=url) + return self + + def upload_file_id(self, upload_file_id: str): + self._completion_request_file.upload_file_id = upload_file_id + return self + + def build(self) -> CompletionRequestFile: + if ( + self._completion_request_file.transfer_method == "remote_url" + and self._completion_request_file.url is None + ): + raise ValueError( + "Url needs to be set when transfer_method is set as remote_url" + ) + if ( + self._completion_request_file.transfer_method == "local_file" + and self._completion_request_file.upload_file_id is None + ): + raise ValueError( + "Upload file_id needs to be set when transfer_method is set as local_file" + ) + return self._completion_request_file diff --git a/sdks/python-client/dify_oapi/api/completion/v1/model/completion_response.py b/sdks/python-client/dify_oapi/api/completion/v1/model/completion_response.py new file mode 100755 index 0000000000..f86dd15475 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/completion/v1/model/completion_response.py @@ -0,0 +1,18 @@ +from __future__ import annotations + +from pydantic import BaseModel + +from dify_oapi.core.model.base_response import BaseResponse + + +class CompletionResponse(BaseResponse): + message_id: str | None = None + mode: str | None = None + answer: str | None = None + metadata: CompletionResponseMetadata | None = None + created_at: int | None = None + + +class CompletionResponseMetadata(BaseModel): + usage: dict | None = None + retriever_resources: list[dict] | None = None diff --git a/sdks/python-client/dify_oapi/api/completion/v1/model/stop_completion_request.py b/sdks/python-client/dify_oapi/api/completion/v1/model/stop_completion_request.py new file mode 100755 index 0000000000..a4510a9021 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/completion/v1/model/stop_completion_request.py @@ -0,0 +1,40 @@ +from __future__ import annotations + +from dify_oapi.core.enum import HttpMethod +from dify_oapi.core.model.base_request import BaseRequest + +from .stop_completion_request_body import StopCompletionRequestBody + + +class StopCompletionRequest(BaseRequest): + def __init__(self) -> None: + super().__init__() + self.task_id: str | None = None + self.request_body: StopCompletionRequestBody | None = None + + @staticmethod + def builder() -> StopCompletionRequestBuilder: + return StopCompletionRequestBuilder() + + +class StopCompletionRequestBuilder: + def __init__(self) -> None: + stop_completion_request = StopCompletionRequest() + stop_completion_request.http_method = HttpMethod.POST + stop_completion_request.uri = "/v1/completion-messages/:task_id/stop" + self._stop_completion_request: StopCompletionRequest = stop_completion_request + + def task_id(self, task_id: str) -> StopCompletionRequestBuilder: + self._stop_completion_request.task_id = task_id + self._stop_completion_request.paths["task_id"] = str(task_id) + return self + + def request_body( + self, request_body: StopCompletionRequestBody + ) -> StopCompletionRequestBuilder: + self._stop_completion_request.request_body = request_body + self._stop_completion_request.body = request_body.model_dump(exclude_none=True) + return self + + def build(self) -> StopCompletionRequest: + return self._stop_completion_request diff --git a/sdks/python-client/dify_oapi/api/completion/v1/model/stop_completion_request_body.py b/sdks/python-client/dify_oapi/api/completion/v1/model/stop_completion_request_body.py new file mode 100755 index 0000000000..f28f042dfe --- /dev/null +++ b/sdks/python-client/dify_oapi/api/completion/v1/model/stop_completion_request_body.py @@ -0,0 +1,23 @@ +from __future__ import annotations + +from pydantic import BaseModel + + +class StopCompletionRequestBody(BaseModel): + user: str | None = None + + @staticmethod + def builder() -> StopCompletionRequestBodyBuilder: + return StopCompletionRequestBodyBuilder() + + +class StopCompletionRequestBodyBuilder: + def __init__(self): + self._stop_completion_request_body = StopCompletionRequestBody() + + def user(self, user: str) -> StopCompletionRequestBodyBuilder: + self._stop_completion_request_body.user = user + return self + + def build(self) -> StopCompletionRequestBody: + return self._stop_completion_request_body diff --git a/sdks/python-client/dify_oapi/api/completion/v1/model/stop_completion_response.py b/sdks/python-client/dify_oapi/api/completion/v1/model/stop_completion_response.py new file mode 100755 index 0000000000..7adeea7689 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/completion/v1/model/stop_completion_response.py @@ -0,0 +1,5 @@ +from dify_oapi.core.model.base_response import BaseResponse + + +class StopCompletionResponse(BaseResponse): + result: str | None = None diff --git a/sdks/python-client/dify_oapi/api/completion/v1/resource/__init__.py b/sdks/python-client/dify_oapi/api/completion/v1/resource/__init__.py new file mode 100755 index 0000000000..9e445d34dd --- /dev/null +++ b/sdks/python-client/dify_oapi/api/completion/v1/resource/__init__.py @@ -0,0 +1 @@ +from .completion import * # noqa 403 diff --git a/sdks/python-client/dify_oapi/api/completion/v1/resource/completion.py b/sdks/python-client/dify_oapi/api/completion/v1/resource/completion.py new file mode 100755 index 0000000000..68a5d3054b --- /dev/null +++ b/sdks/python-client/dify_oapi/api/completion/v1/resource/completion.py @@ -0,0 +1,105 @@ +from collections.abc import AsyncGenerator, Generator +from typing import Literal, overload + +from dify_oapi.core.const import APPLICATION_JSON, CONTENT_TYPE +from dify_oapi.core.http.transport import ATransport, Transport +from dify_oapi.core.model.config import Config +from dify_oapi.core.model.request_option import RequestOption + +from ..model.completion_request import CompletionRequest +from ..model.completion_response import CompletionResponse +from ..model.stop_completion_request import StopCompletionRequest +from ..model.stop_completion_response import StopCompletionResponse + + +class Completion: + def __init__(self, config: Config) -> None: + self.config: Config = config + + @overload + def completion( + self, + request: CompletionRequest, + option: RequestOption | None, + stream: Literal[True], + ) -> Generator[bytes, None, None]: ... + + @overload + def completion( + self, + request: CompletionRequest, + option: RequestOption | None, + stream: Literal[False], + ) -> CompletionResponse: ... + + @overload + def completion( + self, request: CompletionRequest, option: RequestOption | None + ) -> CompletionResponse: ... + + def completion( + self, + request: CompletionRequest, + option: RequestOption | None = None, + stream: bool = False, + ): + if request.body is not None: + option.headers[CONTENT_TYPE] = f"{APPLICATION_JSON}; charset=utf-8" + if stream: + return Transport.execute(self.config, request, option=option, stream=True) + else: + return Transport.execute( + self.config, request, unmarshal_as=CompletionResponse, option=option + ) + + @overload + async def acompletion( + self, + request: CompletionRequest, + option: RequestOption | None, + stream: Literal[True], + ) -> AsyncGenerator[bytes, None]: ... + + @overload + def acompletion( + self, + request: CompletionRequest, + option: RequestOption | None, + stream: Literal[False], + ) -> CompletionResponse: ... + + @overload + async def acompletion( + self, request: CompletionRequest, option: RequestOption | None + ) -> CompletionResponse: ... + + async def acompletion( + self, + request: CompletionRequest, + option: RequestOption | None = None, + stream: bool = False, + ): + if stream: + return await ATransport.aexecute( + self.config, request, option=option, stream=True + ) + else: + return await ATransport.aexecute( + self.config, request, unmarshal_as=CompletionResponse, option=option + ) + + def stop( + self, request: StopCompletionRequest, option: RequestOption | None = None + ) -> StopCompletionResponse: + if request.body is not None: + option.headers[CONTENT_TYPE] = f"{APPLICATION_JSON}; charset=utf-8" + return Transport.execute( + self.config, request, unmarshal_as=StopCompletionResponse, option=option + ) + + async def astop( + self, request: StopCompletionRequest, option: RequestOption | None = None + ) -> StopCompletionResponse: + return await ATransport.aexecute( + self.config, request, unmarshal_as=StopCompletionResponse, option=option + ) diff --git a/sdks/python-client/dify_oapi/api/completion/v1/version.py b/sdks/python-client/dify_oapi/api/completion/v1/version.py new file mode 100755 index 0000000000..c3fe223c5d --- /dev/null +++ b/sdks/python-client/dify_oapi/api/completion/v1/version.py @@ -0,0 +1,8 @@ +from dify_oapi.core.model.config import Config + +from .resource import Completion + + +class V1: + def __init__(self, config: Config): + self.completion: Completion = Completion(config) diff --git a/sdks/python-client/dify_oapi/api/dify/__init__.py b/sdks/python-client/dify_oapi/api/dify/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/sdks/python-client/dify_oapi/api/dify/service.py b/sdks/python-client/dify_oapi/api/dify/service.py new file mode 100644 index 0000000000..410e76bea5 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/dify/service.py @@ -0,0 +1,8 @@ +from dify_oapi.core.model.config import Config + +from .v1.version import V1 + + +class DifyService: + def __init__(self, config: Config) -> None: + self.v1: V1 = V1(config) diff --git a/sdks/python-client/dify_oapi/api/dify/v1/__init__.py b/sdks/python-client/dify_oapi/api/dify/v1/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/sdks/python-client/dify_oapi/api/dify/v1/model/__init__.py b/sdks/python-client/dify_oapi/api/dify/v1/model/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/sdks/python-client/dify_oapi/api/dify/v1/model/get_meta_request.py b/sdks/python-client/dify_oapi/api/dify/v1/model/get_meta_request.py new file mode 100644 index 0000000000..6cc3022425 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/dify/v1/model/get_meta_request.py @@ -0,0 +1,30 @@ +from __future__ import annotations + +from dify_oapi.core.enum import HttpMethod +from dify_oapi.core.model.base_request import BaseRequest + + +class GetMetaRequest(BaseRequest): + def __init__(self): + super().__init__() + self.user: str | None = None + + @staticmethod + def builder() -> GetMetaRequestBuilder: + return GetMetaRequestBuilder() + + +class GetMetaRequestBuilder(object): + def __init__(self): + get_meta_request = GetMetaRequest() + get_meta_request.http_method = HttpMethod.GET + get_meta_request.uri = "/v1/meta" + self._get_meta_request = get_meta_request + + def build(self) -> GetMetaRequest: + return self._get_meta_request + + def user(self, user: str) -> GetMetaRequestBuilder: + self._get_meta_request.user = user + self._get_meta_request.add_query("user", user) + return self diff --git a/sdks/python-client/dify_oapi/api/dify/v1/model/get_meta_response.py b/sdks/python-client/dify_oapi/api/dify/v1/model/get_meta_response.py new file mode 100644 index 0000000000..1fe4b87bd5 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/dify/v1/model/get_meta_response.py @@ -0,0 +1,19 @@ +from __future__ import annotations + +from pydantic import BaseModel + +from dify_oapi.core.model.base_response import BaseResponse + + +class GetMetaResponse(BaseResponse): + tool_icons: GetMetaResponseToolIcons | None = None + + +class GetMetaResponseToolIcons(BaseModel): + dalle2: str | None = None + api_tool: GetMetaResponseApiTool | None = None + + +class GetMetaResponseApiTool(BaseModel): + background: str | None = None + content: str | None = None diff --git a/sdks/python-client/dify_oapi/api/dify/v1/model/get_parameter_request.py b/sdks/python-client/dify_oapi/api/dify/v1/model/get_parameter_request.py new file mode 100755 index 0000000000..2cf31fb567 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/dify/v1/model/get_parameter_request.py @@ -0,0 +1,30 @@ +from __future__ import annotations + +from dify_oapi.core.enum import HttpMethod +from dify_oapi.core.model.base_request import BaseRequest + + +class GetParameterRequest(BaseRequest): + def __init__(self): + super().__init__() + self.user: str | None = None + + @staticmethod + def builder() -> GetParameterRequestBuilder: + return GetParameterRequestBuilder() + + +class GetParameterRequestBuilder: + def __init__(self) -> None: + get_parameter_request = GetParameterRequest() + get_parameter_request.http_method = HttpMethod.GET + get_parameter_request.uri = "/v1/parameters" + self._get_parameter_request: GetParameterRequest = get_parameter_request + + def build(self) -> GetParameterRequest: + return self._get_parameter_request + + def user(self, user: str) -> GetParameterRequestBuilder: + self._get_parameter_request.user = user + self._get_parameter_request.add_query("user", user) + return self diff --git a/sdks/python-client/dify_oapi/api/dify/v1/model/get_parameter_response.py b/sdks/python-client/dify_oapi/api/dify/v1/model/get_parameter_response.py new file mode 100755 index 0000000000..751e155c2b --- /dev/null +++ b/sdks/python-client/dify_oapi/api/dify/v1/model/get_parameter_response.py @@ -0,0 +1,13 @@ +from dify_oapi.core.model.base_response import BaseResponse + + +class GetParameterResponse(BaseResponse): + opening_statement: str | None = None + suggested_questions: list[str] | None = None + suggested_questions_after_answer: dict | None = None + speech_to_text: dict | None = None + retriever_resource: dict | None = None + annotation_reply: dict | None = None + user_input_form: list[dict] | None = None + file_upload: dict | None = None + system_parameters: dict | None = None diff --git a/sdks/python-client/dify_oapi/api/dify/v1/model/message_feedback_request.py b/sdks/python-client/dify_oapi/api/dify/v1/model/message_feedback_request.py new file mode 100755 index 0000000000..ffed015e38 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/dify/v1/model/message_feedback_request.py @@ -0,0 +1,40 @@ +from __future__ import annotations + +from dify_oapi.core.enum import HttpMethod +from dify_oapi.core.model.base_request import BaseRequest + +from ..model.message_feedback_request_body import MessageFeedbackRequestBody + + +class MessageFeedbackRequest(BaseRequest): + def __init__(self): + super().__init__() + self.message_id: str | None = None + self.request_body: MessageFeedbackRequestBody | None = None + + @staticmethod + def builder() -> MessageFeedbackRequestBuilder: + return MessageFeedbackRequestBuilder() + + +class MessageFeedbackRequestBuilder: + def __init__(self): + message_feedback_request = MessageFeedbackRequest() + message_feedback_request.http_method = HttpMethod.POST + message_feedback_request.uri = "/v1/messages/:message_id/feedbacks" + self._message_feedback_request = message_feedback_request + + def build(self) -> MessageFeedbackRequest: + return self._message_feedback_request + + def message_id(self, message_id: str) -> MessageFeedbackRequestBuilder: + self._message_feedback_request.message_id = message_id + self._message_feedback_request.paths["message_id"] = message_id + return self + + def request_body( + self, request_body: MessageFeedbackRequestBody + ) -> MessageFeedbackRequestBuilder: + self._message_feedback_request.request_body = request_body + self._message_feedback_request.body = request_body.model_dump(exclude_none=True) + return self diff --git a/sdks/python-client/dify_oapi/api/dify/v1/model/message_feedback_request_body.py b/sdks/python-client/dify_oapi/api/dify/v1/model/message_feedback_request_body.py new file mode 100755 index 0000000000..968968e85c --- /dev/null +++ b/sdks/python-client/dify_oapi/api/dify/v1/model/message_feedback_request_body.py @@ -0,0 +1,30 @@ +from __future__ import annotations + +from pydantic import BaseModel + + +class MessageFeedbackRequestBody(BaseModel): + rating: str | None = None + user: str | None = None + + @staticmethod + def builder() -> MessageFeedbackRequestBodyBuilder: + return MessageFeedbackRequestBodyBuilder() + + +class MessageFeedbackRequestBodyBuilder: + def __init__(self): + self._message_feedback_request_body = MessageFeedbackRequestBody() + + def build(self) -> MessageFeedbackRequestBody: + return self._message_feedback_request_body + + def rating(self, rating: str) -> MessageFeedbackRequestBodyBuilder: + if rating not in ("like", "dislike", "null"): + raise ValueError("Rating must be one of 'like', 'dislike', 'null'") + self._message_feedback_request_body.rating = rating + return self + + def user(self, user: str) -> MessageFeedbackRequestBodyBuilder: + self._message_feedback_request_body.user = user + return self diff --git a/sdks/python-client/dify_oapi/api/dify/v1/model/message_feedback_response.py b/sdks/python-client/dify_oapi/api/dify/v1/model/message_feedback_response.py new file mode 100755 index 0000000000..cfeca5686a --- /dev/null +++ b/sdks/python-client/dify_oapi/api/dify/v1/model/message_feedback_response.py @@ -0,0 +1,5 @@ +from dify_oapi.core.model.base_response import BaseResponse + + +class MessageFeedbackResponse(BaseResponse): + result: str | None = None diff --git a/sdks/python-client/dify_oapi/api/dify/v1/model/text_to_audio_request.py b/sdks/python-client/dify_oapi/api/dify/v1/model/text_to_audio_request.py new file mode 100644 index 0000000000..65a14ee0e6 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/dify/v1/model/text_to_audio_request.py @@ -0,0 +1,33 @@ +from __future__ import annotations + +from dify_oapi.core.enum import HttpMethod +from dify_oapi.core.model.base_request import BaseRequest +from .text_to_audio_request_body import TextToAudioRequestBody + + +class TextToAudioRequest(BaseRequest): + def __init__(self): + super().__init__() + self.request_body: TextToAudioRequestBody | None = None + + @staticmethod + def builder() -> TextToAudioRequestBuilder: + return TextToAudioRequestBuilder() + + +class TextToAudioRequestBuilder(object): + def __init__(self): + text_to_audio_request = TextToAudioRequest() + text_to_audio_request.http_method = HttpMethod.POST + text_to_audio_request.uri = "/v1/text-to-audio" + self._text_to_audio_request = text_to_audio_request + + def build(self) -> TextToAudioRequest: + return self._text_to_audio_request + + def request_body( + self, request_body: TextToAudioRequestBody + ) -> TextToAudioRequestBuilder: + self._text_to_audio_request.request_body = request_body + self._text_to_audio_request.body = request_body.model_dump(exclude_none=True) + return self diff --git a/sdks/python-client/dify_oapi/api/dify/v1/model/text_to_audio_request_body.py b/sdks/python-client/dify_oapi/api/dify/v1/model/text_to_audio_request_body.py new file mode 100644 index 0000000000..443cca8303 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/dify/v1/model/text_to_audio_request_body.py @@ -0,0 +1,32 @@ +from __future__ import annotations +from pydantic import BaseModel + + +class TextToAudioRequestBody(BaseModel): + message_id: str | None = None + text: str | None = None + user: str | None = None + + @staticmethod + def builder() -> TextToAudioRequestBodyBuilder: + return TextToAudioRequestBodyBuilder() + + +class TextToAudioRequestBodyBuilder(object): + def __init__(self): + self._text_to_audio_request_body = TextToAudioRequestBody() + + def build(self) -> TextToAudioRequestBody: + return self._text_to_audio_request_body + + def message_id(self, message_id: str) -> TextToAudioRequestBodyBuilder: + self._text_to_audio_request_body.message_id = message_id + return self + + def text(self, text: str) -> TextToAudioRequestBodyBuilder: + self._text_to_audio_request_body.text = text + return self + + def user(self, user: str) -> TextToAudioRequestBodyBuilder: + self._text_to_audio_request_body.user = user + return self diff --git a/sdks/python-client/dify_oapi/api/dify/v1/model/text_to_audio_response.py b/sdks/python-client/dify_oapi/api/dify/v1/model/text_to_audio_response.py new file mode 100644 index 0000000000..769a14c40d --- /dev/null +++ b/sdks/python-client/dify_oapi/api/dify/v1/model/text_to_audio_response.py @@ -0,0 +1,4 @@ +from dify_oapi.core.model.base_response import BaseResponse + + +class TextToAudioResponse(BaseResponse): ... diff --git a/sdks/python-client/dify_oapi/api/dify/v1/model/upload_file_body.py b/sdks/python-client/dify_oapi/api/dify/v1/model/upload_file_body.py new file mode 100644 index 0000000000..17613d5399 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/dify/v1/model/upload_file_body.py @@ -0,0 +1,23 @@ +from __future__ import annotations + +from pydantic import BaseModel + + +class UploadFileBody(BaseModel): + user: str | None = None + + @staticmethod + def builder() -> UploadFileBodyBuilder: + return UploadFileBodyBuilder() + + +class UploadFileBodyBuilder(object): + def __init__(self): + self._upload_file_body = UploadFileBody() + + def build(self): + return self._upload_file_body + + def user(self, user: str) -> UploadFileBodyBuilder: + self._upload_file_body.user = user + return self diff --git a/sdks/python-client/dify_oapi/api/dify/v1/model/upload_file_request.py b/sdks/python-client/dify_oapi/api/dify/v1/model/upload_file_request.py new file mode 100644 index 0000000000..bd753b0695 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/dify/v1/model/upload_file_request.py @@ -0,0 +1,43 @@ +from __future__ import annotations + +from io import BytesIO + +from dify_oapi.core.enum import HttpMethod +from dify_oapi.core.model.base_request import BaseRequest +from .upload_file_body import UploadFileBody + + +class UploadFileRequest(BaseRequest): + def __init__(self): + super().__init__() + self.file: BytesIO | None = None + self.request_body: UploadFileBody | None = None + + @staticmethod + def builder() -> UploadFileRequestBuilder: + return UploadFileRequestBuilder() + + +class UploadFileRequestBuilder: + def __init__(self) -> None: + upload_file_request = UploadFileRequest() + upload_file_request.http_method = HttpMethod.POST + upload_file_request.uri = "/v1/files/upload" + self._upload_file_request: UploadFileRequest = upload_file_request + + def build(self) -> UploadFileRequest: + return self._upload_file_request + + def file( + self, file: BytesIO, file_name: str | None = None + ) -> UploadFileRequestBuilder: + self._upload_file_request.file = file + if file_name is None: + file_name = "upload" + self._upload_file_request.files = {"file": (file_name, file)} + return self + + def request_body(self, request_body: UploadFileBody) -> UploadFileRequestBuilder: + self._upload_file_request.request_body = request_body + self._upload_file_request.body = request_body.model_dump(exclude_none=True) + return self diff --git a/sdks/python-client/dify_oapi/api/dify/v1/model/upload_file_response.py b/sdks/python-client/dify_oapi/api/dify/v1/model/upload_file_response.py new file mode 100644 index 0000000000..03f68d2c93 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/dify/v1/model/upload_file_response.py @@ -0,0 +1,11 @@ +from dify_oapi.core.model.base_response import BaseResponse + + +class UploadFileResponse(BaseResponse): + id: str | None = None + name: str | None = None + size: int | None = None + extension: str | None = None + mime_type: str | None = None + created_by: str | None = None + created_at: int | None = None diff --git a/sdks/python-client/dify_oapi/api/dify/v1/resource/__init__.py b/sdks/python-client/dify_oapi/api/dify/v1/resource/__init__.py new file mode 100644 index 0000000000..bc8e65851c --- /dev/null +++ b/sdks/python-client/dify_oapi/api/dify/v1/resource/__init__.py @@ -0,0 +1,5 @@ +from .meta import * # noqa 403 +from .file import * # noqa 403 +from .audio import * # noqa 403 +from .parameter import * # noqa 403 +from .message import * # noqa 403 diff --git a/sdks/python-client/dify_oapi/api/dify/v1/resource/audio.py b/sdks/python-client/dify_oapi/api/dify/v1/resource/audio.py new file mode 100644 index 0000000000..28de8283a3 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/dify/v1/resource/audio.py @@ -0,0 +1,28 @@ +from dify_oapi.core.const import CONTENT_TYPE, APPLICATION_JSON +from dify_oapi.core.http.transport import ATransport, Transport +from dify_oapi.core.model.config import Config +from dify_oapi.core.model.request_option import RequestOption + +from ..model.text_to_audio_request import TextToAudioRequest +from ..model.text_to_audio_response import TextToAudioResponse + + +class Audio: + def __init__(self, config: Config) -> None: + self.config: Config = config + + def from_text( + self, request: TextToAudioRequest, option: RequestOption | None = None + ) -> TextToAudioResponse: + if request.body is not None: + option.headers[CONTENT_TYPE] = f"{APPLICATION_JSON}; charset=utf-8" + return Transport.execute( + self.config, request, unmarshal_as=TextToAudioResponse, option=option + ) + + async def afrom_text( + self, request: TextToAudioRequest, option: RequestOption | None = None + ) -> TextToAudioResponse: + return await ATransport.aexecute( + self.config, request, unmarshal_as=TextToAudioResponse, option=option + ) diff --git a/sdks/python-client/dify_oapi/api/dify/v1/resource/file.py b/sdks/python-client/dify_oapi/api/dify/v1/resource/file.py new file mode 100644 index 0000000000..1ce708ba9f --- /dev/null +++ b/sdks/python-client/dify_oapi/api/dify/v1/resource/file.py @@ -0,0 +1,25 @@ +from dify_oapi.core.http.transport import ATransport, Transport +from dify_oapi.core.model.config import Config +from dify_oapi.core.model.request_option import RequestOption + +from ..model.upload_file_request import UploadFileRequest +from ..model.upload_file_response import UploadFileResponse + + +class File: + def __init__(self, config: Config) -> None: + self.config: Config = config + + def upload( + self, request: UploadFileRequest, option: RequestOption | None = None + ) -> UploadFileResponse: + return Transport.execute( + self.config, request, unmarshal_as=UploadFileResponse, option=option + ) + + async def aupload( + self, request: UploadFileRequest, option: RequestOption | None = None + ) -> UploadFileResponse: + return await ATransport.aexecute( + self.config, request, unmarshal_as=UploadFileResponse, option=option + ) diff --git a/sdks/python-client/dify_oapi/api/dify/v1/resource/message.py b/sdks/python-client/dify_oapi/api/dify/v1/resource/message.py new file mode 100755 index 0000000000..aa43bc1341 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/dify/v1/resource/message.py @@ -0,0 +1,32 @@ +from dify_oapi.core.const import APPLICATION_JSON, CONTENT_TYPE +from dify_oapi.core.http.transport import ATransport, Transport +from dify_oapi.core.model.config import Config +from dify_oapi.core.model.request_option import RequestOption + +from ..model.message_feedback_request import MessageFeedbackRequest +from ..model.message_feedback_response import MessageFeedbackResponse + + +class Message: + def __init__(self, config: Config) -> None: + self.config: Config = config + + def feedback( + self, request: MessageFeedbackRequest, option: RequestOption | None = None + ) -> MessageFeedbackResponse: + # 添加 content-type + if request.body is not None: + option.headers[CONTENT_TYPE] = f"{APPLICATION_JSON}; charset=utf-8" + + # 发起请求 + return Transport.execute( + self.config, request, unmarshal_as=MessageFeedbackResponse, option=option + ) + + async def afeedback( + self, request: MessageFeedbackRequest, option: RequestOption | None = None + ) -> MessageFeedbackResponse: + # 发起请求 + return await ATransport.aexecute( + self.config, request, unmarshal_as=MessageFeedbackResponse, option=option + ) diff --git a/sdks/python-client/dify_oapi/api/dify/v1/resource/meta.py b/sdks/python-client/dify_oapi/api/dify/v1/resource/meta.py new file mode 100644 index 0000000000..f0cd1fc103 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/dify/v1/resource/meta.py @@ -0,0 +1,25 @@ +from dify_oapi.core.http.transport import ATransport, Transport +from dify_oapi.core.model.config import Config +from dify_oapi.core.model.request_option import RequestOption + +from ..model.get_meta_request import GetMetaRequest +from ..model.get_meta_response import GetMetaResponse + + +class Meta: + def __init__(self, config: Config) -> None: + self.config: Config = config + + def get( + self, request: GetMetaRequest, option: RequestOption | None = None + ) -> GetMetaResponse: + return Transport.execute( + self.config, request, unmarshal_as=GetMetaResponse, option=option + ) + + async def aget( + self, request: GetMetaRequest, option: RequestOption | None = None + ) -> GetMetaResponse: + return await ATransport.aexecute( + self.config, request, unmarshal_as=GetMetaResponse, option=option + ) diff --git a/sdks/python-client/dify_oapi/api/dify/v1/resource/parameter.py b/sdks/python-client/dify_oapi/api/dify/v1/resource/parameter.py new file mode 100755 index 0000000000..27aff5d952 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/dify/v1/resource/parameter.py @@ -0,0 +1,32 @@ +from dify_oapi.core.const import APPLICATION_JSON, CONTENT_TYPE +from dify_oapi.core.http.transport import ATransport, Transport +from dify_oapi.core.model.config import Config +from dify_oapi.core.model.request_option import RequestOption + +from ..model.get_parameter_request import GetParameterRequest +from ..model.get_parameter_response import GetParameterResponse + + +class Parameter: + def __init__(self, config: Config) -> None: + self.config: Config = config + + def get( + self, request: GetParameterRequest, option: RequestOption | None = None + ) -> GetParameterResponse: + # 添加 content-type + if request.body is not None: + option.headers[CONTENT_TYPE] = f"{APPLICATION_JSON}; charset=utf-8" + + # 发起请求 + return Transport.execute( + self.config, request, unmarshal_as=GetParameterResponse, option=option + ) + + async def aget( + self, request: GetParameterRequest, option: RequestOption | None = None + ) -> GetParameterResponse: + # 发起请求 + return await ATransport.aexecute( + self.config, request, unmarshal_as=GetParameterResponse, option=option + ) diff --git a/sdks/python-client/dify_oapi/api/dify/v1/version.py b/sdks/python-client/dify_oapi/api/dify/v1/version.py new file mode 100644 index 0000000000..f7b2aea927 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/dify/v1/version.py @@ -0,0 +1,12 @@ +from dify_oapi.core.model.config import Config + +from .resource import Meta, File, Audio, Parameter, Message + + +class V1: + def __init__(self, config: Config): + self.meta: Meta = Meta(config) + self.file: File = File(config) + self.audio: Audio = Audio(config) + self.parameter: Parameter = Parameter(config) + self.message: Message = Message(config) diff --git a/sdks/python-client/dify_oapi/api/knowledge_base/__init__.py b/sdks/python-client/dify_oapi/api/knowledge_base/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/sdks/python-client/dify_oapi/api/knowledge_base/service.py b/sdks/python-client/dify_oapi/api/knowledge_base/service.py new file mode 100644 index 0000000000..14c6d9085f --- /dev/null +++ b/sdks/python-client/dify_oapi/api/knowledge_base/service.py @@ -0,0 +1,8 @@ +from dify_oapi.core.model.config import Config + +from .v1.version import V1 + + +class KnowledgeBaseService: + def __init__(self, config: Config) -> None: + self.v1: V1 = V1(config) diff --git a/sdks/python-client/dify_oapi/api/knowledge_base/v1/__init__.py b/sdks/python-client/dify_oapi/api/knowledge_base/v1/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/__init__.py b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/create_dataset_request.py b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/create_dataset_request.py new file mode 100644 index 0000000000..f69332a429 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/create_dataset_request.py @@ -0,0 +1,33 @@ +from __future__ import annotations + +from dify_oapi.core.enum import HttpMethod +from dify_oapi.core.model.base_request import BaseRequest +from .create_dataset_request_body import CreateDatasetRequestBody + + +class CreateDatasetRequest(BaseRequest): + def __init__(self): + super().__init__() + self.request_body: CreateDatasetRequestBody | None = None + + @staticmethod + def builder() -> CreateDatasetRequestBuilder: + return CreateDatasetRequestBuilder() + + +class CreateDatasetRequestBuilder(object): + def __init__(self): + create_dataset_request = CreateDatasetRequest() + create_dataset_request.http_method = HttpMethod.POST + create_dataset_request.uri = "/v1/datasets" + self._create_dataset_request = create_dataset_request + + def build(self) -> CreateDatasetRequest: + return self._create_dataset_request + + def request_body( + self, request_body: CreateDatasetRequestBody + ) -> CreateDatasetRequestBuilder: + self._create_dataset_request.request_body = request_body + self._create_dataset_request.body = request_body.model_dump(exclude_none=True) + return self diff --git a/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/create_dataset_request_body.py b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/create_dataset_request_body.py new file mode 100644 index 0000000000..d36f282c8b --- /dev/null +++ b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/create_dataset_request_body.py @@ -0,0 +1,63 @@ +from __future__ import annotations + +from typing import Literal + +from pydantic import BaseModel + + +class CreateDatasetRequestBody(BaseModel): + name: str | None = None + description: str | None = None + indexing_technique: str | None = None + permission: str | None = None + provider: str | None = None + external_knowledge_api_id: str | None = None + external_knowledge_id: int | None = None + + @staticmethod + def builder() -> CreateDatasetRequestBodyBuilder: + return CreateDatasetRequestBodyBuilder() + + +class CreateDatasetRequestBodyBuilder(object): + def __init__(self): + self._create_dataset_request_body = CreateDatasetRequestBody() + + def build(self) -> CreateDatasetRequestBody: + return self._create_dataset_request_body + + def name(self, name: str) -> CreateDatasetRequestBodyBuilder: + self._create_dataset_request_body.name = name + return self + + def description(self, description: str) -> CreateDatasetRequestBodyBuilder: + self._create_dataset_request_body.description = description + return self + + def indexing_technique( + self, indexing_technique: Literal["high_quality", "economy"] + ) -> CreateDatasetRequestBodyBuilder: + self._create_dataset_request_body.indexing_technique = indexing_technique + return self + + def permission( + self, permission: Literal["only_me", "all_team_members", "partial_members"] + ) -> CreateDatasetRequestBodyBuilder: + self._create_dataset_request_body.permission = permission + return self + + def provider( + self, provider: Literal["vendor", "external"] + ) -> CreateDatasetRequestBodyBuilder: + self._create_dataset_request_body.provider = provider + return self + + def external_knowledge_api_id(self, value: str) -> CreateDatasetRequestBodyBuilder: + self._create_dataset_request_body.external_knowledge_api_id = value + return self + + def external_knowledge_id( + self, external_knowledge_id: int + ) -> CreateDatasetRequestBodyBuilder: + self._create_dataset_request_body.external_knowledge_id = external_knowledge_id + return self diff --git a/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/create_dataset_response.py b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/create_dataset_response.py new file mode 100644 index 0000000000..8b5362285e --- /dev/null +++ b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/create_dataset_response.py @@ -0,0 +1,9 @@ +from __future__ import annotations + + +from dify_oapi.core.model.base_response import BaseResponse +from .dataset import * # noqa F403 + + +class CreateDatasetResponse(BaseResponse, Dataset): # noqa F405 + ... diff --git a/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/create_document_by_file_request.py b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/create_document_by_file_request.py new file mode 100644 index 0000000000..1262953154 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/create_document_by_file_request.py @@ -0,0 +1,54 @@ +from __future__ import annotations + +from io import BytesIO + +from dify_oapi.core.enum import HttpMethod +from dify_oapi.core.model.base_request import BaseRequest +from .create_document_by_file_request_body import CreateDocumentByFileRequestBody + + +class CreateDocumentByFileRequest(BaseRequest): + def __init__(self): + super().__init__() + self.dataset_id: str | None = None + self.request_body: CreateDocumentByFileRequestBody | None = None + self.file: BytesIO | None = None + + @staticmethod + def builder() -> CreateDocumentByFileRequestBuilder: + return CreateDocumentByFileRequestBuilder() + + +class CreateDocumentByFileRequestBuilder(object): + def __init__(self): + create_document_by_file_request = CreateDocumentByFileRequest() + create_document_by_file_request.http_method = HttpMethod.POST + create_document_by_file_request.uri = ( + "/v1/datasets/:dataset_id/document/create_by_file" + ) + self._create_document_by_file_request = create_document_by_file_request + + def build(self) -> CreateDocumentByFileRequest: + return self._create_document_by_file_request + + def dataset_id(self, dataset_id: str) -> CreateDocumentByFileRequestBuilder: + self._create_document_by_file_request.dataset_id = dataset_id + self._create_document_by_file_request.paths["dataset_id"] = dataset_id + return self + + def request_body( + self, request_body: CreateDocumentByFileRequestBody + ) -> CreateDocumentByFileRequestBuilder: + self._create_document_by_file_request.request_body = request_body + self._create_document_by_file_request.body = request_body.model_dump( + exclude_none=True + ) + return self + + def file( + self, file: BytesIO, file_name: str | None = None + ) -> CreateDocumentByFileRequestBuilder: + self._create_document_by_file_request.file = file + file_name = file_name or "upload" + self._create_document_by_file_request.files = {"file": (file_name, file)} + return self diff --git a/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/create_document_by_file_request_body.py b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/create_document_by_file_request_body.py new file mode 100644 index 0000000000..86058abef3 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/create_document_by_file_request_body.py @@ -0,0 +1,34 @@ +from __future__ import annotations + + +from pydantic import BaseModel +from .create_document_by_file_request_body_data import ( + CreateDocumentByTextRequestBodyData, +) + + +class CreateDocumentByFileRequestBody(BaseModel): + data: str | None = None + + @staticmethod + def builder() -> CreateDocumentByFileRequestBodyBuilder: + return CreateDocumentByFileRequestBodyBuilder() + + +class CreateDocumentByFileRequestBodyBuilder(object): + def __init__(self): + create_document_by_file_request_body = CreateDocumentByFileRequestBody() + self._create_document_by_file_request_body = ( + create_document_by_file_request_body + ) + + def build(self) -> CreateDocumentByFileRequestBody: + return self._create_document_by_file_request_body + + def data( + self, data: CreateDocumentByTextRequestBodyData + ) -> CreateDocumentByFileRequestBodyBuilder: + self._create_document_by_file_request_body.data = data.model_dump_json( + exclude_none=True + ) + return self diff --git a/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/create_document_by_file_request_body_data.py b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/create_document_by_file_request_body_data.py new file mode 100644 index 0000000000..4bfef41de1 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/create_document_by_file_request_body_data.py @@ -0,0 +1,51 @@ +from __future__ import annotations + +from typing import Literal + +from pydantic import BaseModel +from .document_request_process_rule import DocumentRequestProcessRule + + +class CreateDocumentByTextRequestBodyData(BaseModel): + original_document_id: str | None = None + indexing_technique: str | None = None + process_rule: DocumentRequestProcessRule | None = None + + @staticmethod + def builder() -> CreateDocumentByTextRequestBodyDataBuilder: + return CreateDocumentByTextRequestBodyDataBuilder() + + +class CreateDocumentByTextRequestBodyDataBuilder(object): + def __init__(self): + create_document_by_file_request_body_data = ( + CreateDocumentByTextRequestBodyData() + ) + self._create_document_by_file_request_body_data = ( + create_document_by_file_request_body_data + ) + + def build(self) -> CreateDocumentByTextRequestBodyData: + return self._create_document_by_file_request_body_data + + def original_document_id( + self, original_document_id: str + ) -> CreateDocumentByTextRequestBodyDataBuilder: + self._create_document_by_file_request_body_data.original_document_id = ( + original_document_id + ) + return self + + def indexing_technique( + self, indexing_technique: Literal["high_quality", "economy"] + ) -> CreateDocumentByTextRequestBodyDataBuilder: + self._create_document_by_file_request_body_data.indexing_technique = ( + indexing_technique + ) + return self + + def process_rule( + self, process_rule: DocumentRequestProcessRule + ) -> CreateDocumentByTextRequestBodyDataBuilder: + self._create_document_by_file_request_body_data.process_rule = process_rule + return self diff --git a/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/create_document_by_text_request.py b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/create_document_by_text_request.py new file mode 100644 index 0000000000..6e5f13259a --- /dev/null +++ b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/create_document_by_text_request.py @@ -0,0 +1,43 @@ +from __future__ import annotations + +from dify_oapi.core.enum import HttpMethod +from dify_oapi.core.model.base_request import BaseRequest +from .create_document_by_text_request_body import CreateDocumentByTextRequestBody + + +class CreateDocumentByTextRequest(BaseRequest): + def __init__(self): + super().__init__() + self.dataset_id: str | None = None + self.request_body: CreateDocumentByTextRequestBody | None = None + + @staticmethod + def builder() -> CreateDocumentByTextRequestBuilder: + return CreateDocumentByTextRequestBuilder() + + +class CreateDocumentByTextRequestBuilder(object): + def __init__(self): + create_document_by_text_request = CreateDocumentByTextRequest() + create_document_by_text_request.http_method = HttpMethod.POST + create_document_by_text_request.uri = ( + "/v1/datasets/:dataset_id/document/create_by_text" + ) + self._create_document_by_text_request = create_document_by_text_request + + def build(self) -> CreateDocumentByTextRequest: + return self._create_document_by_text_request + + def dataset_id(self, dataset_id: str) -> CreateDocumentByTextRequestBuilder: + self._create_document_by_text_request.dataset_id = dataset_id + self._create_document_by_text_request.paths["dataset_id"] = dataset_id + return self + + def request_body( + self, request_body: CreateDocumentByTextRequestBody + ) -> CreateDocumentByTextRequestBuilder: + self._create_document_by_text_request.request_body = request_body + self._create_document_by_text_request.body = request_body.model_dump( + exclude_none=True + ) + return self diff --git a/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/create_document_by_text_request_body.py b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/create_document_by_text_request_body.py new file mode 100644 index 0000000000..65f18cb1f5 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/create_document_by_text_request_body.py @@ -0,0 +1,50 @@ +from __future__ import annotations + +from typing import Literal + +from pydantic import BaseModel +from .document_request_process_rule import DocumentRequestProcessRule + + +class CreateDocumentByTextRequestBody(BaseModel): + name: str | None = None + text: str | None = None + indexing_technique: str | None = None + process_rule: DocumentRequestProcessRule | None = None + + @staticmethod + def builder() -> CreateDocumentByTextRequestBodyBuilder: + return CreateDocumentByTextRequestBodyBuilder() + + +class CreateDocumentByTextRequestBodyBuilder(object): + def __init__(self): + create_document_by_text_request_body = CreateDocumentByTextRequestBody() + self._create_document_by_text_request_body = ( + create_document_by_text_request_body + ) + + def build(self) -> CreateDocumentByTextRequestBody: + return self._create_document_by_text_request_body + + def name(self, name: str) -> CreateDocumentByTextRequestBodyBuilder: + self._create_document_by_text_request_body.name = name + return self + + def text(self, text: str) -> CreateDocumentByTextRequestBodyBuilder: + self._create_document_by_text_request_body.text = text + return self + + def indexing_technique( + self, indexing_technique: Literal["high_quality", "economy"] + ) -> CreateDocumentByTextRequestBodyBuilder: + self._create_document_by_text_request_body.indexing_technique = ( + indexing_technique + ) + return self + + def process_rule( + self, process_rule: DocumentRequestProcessRule + ) -> CreateDocumentByTextRequestBodyBuilder: + self._create_document_by_text_request_body.process_rule = process_rule + return self diff --git a/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/create_document_response.py b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/create_document_response.py new file mode 100644 index 0000000000..2825177081 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/create_document_response.py @@ -0,0 +1,10 @@ +from __future__ import annotations + + +from dify_oapi.core.model.base_response import BaseResponse +from .document import Document + + +class CreateDocumentResponse(BaseResponse): + document: Document | None = None + batch: str | None = None diff --git a/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/create_segment_request.py b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/create_segment_request.py new file mode 100644 index 0000000000..8f7c0c4203 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/create_segment_request.py @@ -0,0 +1,47 @@ +from __future__ import annotations + +from dify_oapi.core.enum import HttpMethod +from dify_oapi.core.model.base_request import BaseRequest +from .create_segment_request_body import CreateSegmentRequestBody + + +class CreateSegmentRequest(BaseRequest): + def __init__(self): + super().__init__() + self.dataset_id: str | None = None + self.document_id: str | None = None + self.request_body: CreateSegmentRequestBody | None = None + + @staticmethod + def builder() -> CreateSegmentRequestBuilder: + return CreateSegmentRequestBuilder() + + +class CreateSegmentRequestBuilder(object): + def __init__(self): + create_segment_request = CreateSegmentRequest() + create_segment_request.http_method = HttpMethod.POST + create_segment_request.uri = ( + "/v1/datasets/:dataset_id/documents/:document_id/segments" + ) + self._create_segment_request = create_segment_request + + def build(self) -> CreateSegmentRequest: + return self._create_segment_request + + def dataset_id(self, dataset_id: str) -> CreateSegmentRequestBuilder: + self._create_segment_request.dataset_id = dataset_id + self._create_segment_request.paths["dataset_id"] = dataset_id + return self + + def document_id(self, document_id: str) -> CreateSegmentRequestBuilder: + self._create_segment_request.document_id = document_id + self._create_segment_request.paths["document_id"] = document_id + return self + + def request_body( + self, request_body: CreateSegmentRequestBody + ) -> CreateSegmentRequestBuilder: + self._create_segment_request.request_body = request_body + self._create_segment_request.body = request_body.model_dump(exclude_none=True) + return self diff --git a/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/create_segment_request_body.py b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/create_segment_request_body.py new file mode 100644 index 0000000000..7b52a481be --- /dev/null +++ b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/create_segment_request_body.py @@ -0,0 +1,25 @@ +from __future__ import annotations +from pydantic import BaseModel +from .create_segment_request_body_segment import CreateSegmentRequestBodySegment + + +class CreateSegmentRequestBody(BaseModel): + segments: list[CreateSegmentRequestBodySegment] | None = None + + @staticmethod + def builder() -> CreateSegmentRequestBodyBuilder: + return CreateSegmentRequestBodyBuilder() + + +class CreateSegmentRequestBodyBuilder(object): + def __init__(self): + self._create_segment_request_body = CreateSegmentRequestBody() + + def build(self) -> CreateSegmentRequestBody: + return self._create_segment_request_body + + def segments( + self, segments: list[CreateSegmentRequestBodySegment] + ) -> CreateSegmentRequestBodyBuilder: + self._create_segment_request_body.segments = segments + return self diff --git a/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/create_segment_request_body_segment.py b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/create_segment_request_body_segment.py new file mode 100644 index 0000000000..2dd34b8294 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/create_segment_request_body_segment.py @@ -0,0 +1,32 @@ +from __future__ import annotations +from pydantic import BaseModel + + +class CreateSegmentRequestBodySegment(BaseModel): + content: str | None = None + answer: str | None = None + keywords: list[str] | None = None + + @staticmethod + def builder() -> CreateSegmentRequestBodySegmentBuilder: + return CreateSegmentRequestBodySegmentBuilder() + + +class CreateSegmentRequestBodySegmentBuilder(object): + def __init__(self): + self._create_segment_request_body_segment = CreateSegmentRequestBodySegment() + + def build(self) -> CreateSegmentRequestBodySegment: + return self._create_segment_request_body_segment + + def content(self, content: str) -> CreateSegmentRequestBodySegmentBuilder: + self._create_segment_request_body_segment.content = content + return self + + def answer(self, answer: str) -> CreateSegmentRequestBodySegmentBuilder: + self._create_segment_request_body_segment.answer = answer + return self + + def keywords(self, keywords: list[str]) -> CreateSegmentRequestBodySegmentBuilder: + self._create_segment_request_body_segment.keywords = keywords + return self diff --git a/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/create_segment_response.py b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/create_segment_response.py new file mode 100644 index 0000000000..efa75bb379 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/create_segment_response.py @@ -0,0 +1,10 @@ +from __future__ import annotations + + +from dify_oapi.core.model.base_response import BaseResponse +from .segment import Segment + + +class CreateSegmentResponse(BaseResponse): + data: list[Segment] | None = None + doc_form: str | None = None diff --git a/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/dataset.py b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/dataset.py new file mode 100644 index 0000000000..21ec00e4a1 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/dataset.py @@ -0,0 +1,54 @@ +from __future__ import annotations +from pydantic import BaseModel + + +class Dataset(BaseModel): + id: str | None = None + name: str | None = None + description: str | None = None + provider: str | None = None + permission: str | None = None + data_source_type: str | None = None + indexing_technique: str | None = None + app_count: int | None = None + document_count: int | None = None + word_count: int | None = None + created_by: str | None = None + created_at: int | None = None + updated_by: str | None = None + updated_at: int | None = None + embedding_model: str | None = None + embedding_model_provider: str | None = None + embedding_available: bool | None = None + retrieval_model_dict: DatasetResponseRetrievalModel | None = None + tags: list | None = None + external_knowledge_info: DatasetResponseExternalKnowledgeInfo | None = None + external_retrieval_model: DatasetResponseExternalRetrievalModel | None = None + + +class DatasetResponseRetrievalModel(BaseModel): + search_method: str | None = None + reranking_enable: bool | None = None + reranking_mode: str | None = None + reranking_model: DatasetResponseRerankingModel | None = None + weights: float | None = None + top_k: int | None = None + score_threshold_enabled: bool | None = None + score_threshold: float | None = None + + +class DatasetResponseRerankingModel(BaseModel): + reranking_provider_name: str | None = None + reranking_model_name: str | None = None + + +class DatasetResponseExternalKnowledgeInfo(BaseModel): + external_knowledge_id: str | None = None + external_knowledge_api_id: str | None = None + external_knowledge_api_name: str | None = None + external_knowledge_api_endpoint: str | None = None + + +class DatasetResponseExternalRetrievalModel(BaseModel): + top_k: int | None = None + score_threshold: float | None = None diff --git a/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/delete_dataset_request.py b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/delete_dataset_request.py new file mode 100644 index 0000000000..e130e25307 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/delete_dataset_request.py @@ -0,0 +1,30 @@ +from __future__ import annotations + +from dify_oapi.core.enum import HttpMethod +from dify_oapi.core.model.base_request import BaseRequest + + +class DeleteDatasetRequest(BaseRequest): + def __init__(self): + super().__init__() + self.dataset_id: str | None = None + + @staticmethod + def builder() -> DeleteDatasetRequestBuilder: + return DeleteDatasetRequestBuilder() + + +class DeleteDatasetRequestBuilder(object): + def __init__(self): + delete_dataset_request = DeleteDatasetRequest() + delete_dataset_request.http_method = HttpMethod.DELETE + delete_dataset_request.uri = "/v1/datasets/:dataset_id" + self._delete_dataset_request = delete_dataset_request + + def build(self) -> DeleteDatasetRequest: + return self._delete_dataset_request + + def dataset_id(self, dataset_id: str) -> DeleteDatasetRequestBuilder: + self._delete_dataset_request.dataset_id = dataset_id + self._delete_dataset_request.paths["dataset_id"] = dataset_id + return self diff --git a/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/delete_dataset_response.py b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/delete_dataset_response.py new file mode 100644 index 0000000000..fa873e1bd0 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/delete_dataset_response.py @@ -0,0 +1,4 @@ +from dify_oapi.core.model.base_response import BaseResponse + + +class DeleteDatasetResponse(BaseResponse): ... diff --git a/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/delete_document_request.py b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/delete_document_request.py new file mode 100644 index 0000000000..06e34bbfd9 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/delete_document_request.py @@ -0,0 +1,36 @@ +from __future__ import annotations + +from dify_oapi.core.enum import HttpMethod +from dify_oapi.core.model.base_request import BaseRequest + + +class DeleteDocumentRequest(BaseRequest): + def __init__(self): + super().__init__() + self.dataset_id: str | None = None + self.document_id: str | None = None + + @staticmethod + def builder() -> DeleteDocumentRequestBuilder: + return DeleteDocumentRequestBuilder() + + +class DeleteDocumentRequestBuilder(object): + def __init__(self): + delete_document_request = DeleteDocumentRequest() + delete_document_request.http_method = HttpMethod.DELETE + delete_document_request.uri = "/v1/datasets/:dataset_id/documents/:document_id" + self._delete_document_request = delete_document_request + + def build(self) -> DeleteDocumentRequest: + return self._delete_document_request + + def dataset_id(self, dataset_id: str) -> DeleteDocumentRequestBuilder: + self._delete_document_request.dataset_id = dataset_id + self._delete_document_request.paths["dataset_id"] = dataset_id + return self + + def document_id(self, document_id: str) -> DeleteDocumentRequestBuilder: + self._delete_document_request.document_id = document_id + self._delete_document_request.paths["document_id"] = document_id + return self diff --git a/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/delete_document_response.py b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/delete_document_response.py new file mode 100644 index 0000000000..89b47643d3 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/delete_document_response.py @@ -0,0 +1,5 @@ +from dify_oapi.core.model.base_response import BaseResponse + + +class DeleteDocumentResponse(BaseResponse): + result: str | None = None diff --git a/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/delete_segment_request.py b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/delete_segment_request.py new file mode 100644 index 0000000000..1c2c107e47 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/delete_segment_request.py @@ -0,0 +1,44 @@ +from __future__ import annotations + +from dify_oapi.core.enum import HttpMethod +from dify_oapi.core.model.base_request import BaseRequest + + +class DeleteSegmentRequest(BaseRequest): + def __init__(self): + super().__init__() + self.dataset_id: str | None = None + self.document_id: str | None = None + self.segment_id: str | None = None + + @staticmethod + def builder() -> DeleteSegmentRequestBuilder: + return DeleteSegmentRequestBuilder() + + +class DeleteSegmentRequestBuilder(object): + def __init__(self): + delete_segment_request = DeleteSegmentRequest() + delete_segment_request.http_method = HttpMethod.DELETE + delete_segment_request.uri = ( + "/v1/datasets/:dataset_id/documents/:document_id/segments/:segment_id" + ) + self._delete_segment_request = delete_segment_request + + def build(self) -> DeleteSegmentRequest: + return self._delete_segment_request + + def dataset_id(self, dataset_id: str) -> DeleteSegmentRequestBuilder: + self._delete_segment_request.dataset_id = dataset_id + self._delete_segment_request.paths["dataset_id"] = dataset_id + return self + + def document_id(self, document_id: str) -> DeleteSegmentRequestBuilder: + self._delete_segment_request.document_id = document_id + self._delete_segment_request.paths["document_id"] = document_id + return self + + def segment_id(self, segment_id: str) -> DeleteSegmentRequestBuilder: + self._delete_segment_request.segment_id = segment_id + self._delete_segment_request.paths["segment_id"] = segment_id + return self diff --git a/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/delete_segment_response.py b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/delete_segment_response.py new file mode 100644 index 0000000000..01814476f4 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/delete_segment_response.py @@ -0,0 +1,5 @@ +from dify_oapi.core.model.base_response import BaseResponse + + +class DeleteSegmentResponse(BaseResponse): + result: str | None = None diff --git a/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/document.py b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/document.py new file mode 100644 index 0000000000..69c72bbe71 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/document.py @@ -0,0 +1,45 @@ +from __future__ import annotations + +from pydantic import BaseModel + + +class Document(BaseModel): + id: str | None = None + position: int | None = None + data_source_type: str | None = None + data_source_info: DocumentDataSourceInfo | None = None + data_source_detail_dict: DocumentDataSourceDetailDict | None = None + dataset_process_rule_id: str | None = None + name: str | None = None + created_from: str | None = None + created_by: str | None = None + created_at: int | None = None + tokens: int | None = None + indexing_status: str | None = None + error: str | None = None + enabled: bool | None = None + disabled_at: int | None = None + disabled_by: str | None = None + archived: bool | None = None + display_status: str | None = None + word_count: int | None = None + hit_count: int | None = None + doc_form: str | None = None + + +class DocumentDataSourceInfo(BaseModel): + upload_file_id: str | None = None + + +class DocumentDataSourceDetailDict(BaseModel): + upload_file: DocumentDataSourceDetailDictUploadFile | None = None + + +class DocumentDataSourceDetailDictUploadFile(BaseModel): + id: str | None = None + name: str | None = None + size: int | None = None + extension: str | None = None + mime_type: str | None = None + created_by: str | None = None + created_at: float | None = None diff --git a/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/document_request_pre_processing_rule.py b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/document_request_pre_processing_rule.py new file mode 100644 index 0000000000..fc801ce3a4 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/document_request_pre_processing_rule.py @@ -0,0 +1,32 @@ +from __future__ import annotations + +from typing import Literal + +from pydantic import BaseModel + + +class DocumentRequestPreProcessingRule(BaseModel): + id: str | None = None + enabled: bool | None = None + + @staticmethod + def builder() -> DocumentRequestPreProcessingRuleBuilder: + return DocumentRequestPreProcessingRuleBuilder() + + +class DocumentRequestPreProcessingRuleBuilder(object): + def __init__(self): + self._document_request_pre_processing_rule = DocumentRequestPreProcessingRule() + + def build(self) -> DocumentRequestPreProcessingRule: + return self._document_request_pre_processing_rule + + def id( + self, id_: Literal["remove_extra_spaces", "remove_urls_emails"] + ) -> DocumentRequestPreProcessingRuleBuilder: + self._document_request_pre_processing_rule.id = id_ + return self + + def enabled(self, enabled: bool) -> DocumentRequestPreProcessingRuleBuilder: + self._document_request_pre_processing_rule.enabled = enabled + return self diff --git a/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/document_request_process_rule.py b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/document_request_process_rule.py new file mode 100644 index 0000000000..f236a517ca --- /dev/null +++ b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/document_request_process_rule.py @@ -0,0 +1,33 @@ +from __future__ import annotations + +from typing import Literal + +from pydantic import BaseModel +from .document_request_rules import DocumentRequestRules + + +class DocumentRequestProcessRule(BaseModel): + mode: str | None = None + rules: DocumentRequestRules | None = None + + @staticmethod + def builder() -> DocumentRequestProcessRuleBuilder: + return DocumentRequestProcessRuleBuilder() + + +class DocumentRequestProcessRuleBuilder(object): + def __init__(self): + self._document_request_process_rule = DocumentRequestProcessRule() + + def build(self) -> DocumentRequestProcessRule: + return self._document_request_process_rule + + def mode( + self, mode: Literal["automatic", "custom"] + ) -> DocumentRequestProcessRuleBuilder: + self._document_request_process_rule.mode = mode + return self + + def rules(self, rules: DocumentRequestRules) -> DocumentRequestProcessRuleBuilder: + self._document_request_process_rule.rules = rules + return self diff --git a/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/document_request_rules.py b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/document_request_rules.py new file mode 100644 index 0000000000..41080186b1 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/document_request_rules.py @@ -0,0 +1,33 @@ +from __future__ import annotations +from pydantic import BaseModel +from .document_request_segmentation import DocumentRequestSegmentation +from .document_request_pre_processing_rule import DocumentRequestPreProcessingRule + + +class DocumentRequestRules(BaseModel): + pre_processing_rules: list[DocumentRequestPreProcessingRule] | None = None + segmentation: DocumentRequestSegmentation | None = None + + @staticmethod + def builder() -> DocumentRequestRulesBuilder: + return DocumentRequestRulesBuilder() + + +class DocumentRequestRulesBuilder(object): + def __init__(self): + self._document_request_rules = DocumentRequestRules() + + def build(self) -> DocumentRequestRules: + return self._document_request_rules + + def pre_processing_rules( + self, pre_processing_rules: list[DocumentRequestPreProcessingRule] + ) -> DocumentRequestRulesBuilder: + self._document_request_rules.pre_processing_rules = pre_processing_rules + return self + + def segmentation( + self, segmentation: DocumentRequestSegmentation + ) -> DocumentRequestRulesBuilder: + self._document_request_rules.segmentation = segmentation + return self diff --git a/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/document_request_segmentation.py b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/document_request_segmentation.py new file mode 100644 index 0000000000..9df4a104af --- /dev/null +++ b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/document_request_segmentation.py @@ -0,0 +1,27 @@ +from __future__ import annotations +from pydantic import BaseModel + + +class DocumentRequestSegmentation(BaseModel): + separator: str | None = None + max_tokens: int | None = None + + @staticmethod + def builder() -> DocumentRequestSegmentationBuilder: + return DocumentRequestSegmentationBuilder() + + +class DocumentRequestSegmentationBuilder(object): + def __init__(self): + self._document_request_segmentation = DocumentRequestSegmentation() + + def build(self) -> DocumentRequestSegmentation: + return self._document_request_segmentation + + def separator(self, separator: str) -> DocumentRequestSegmentationBuilder: + self._document_request_segmentation.separator = separator + return self + + def max_tokens(self, max_tokens: int) -> DocumentRequestSegmentationBuilder: + self._document_request_segmentation.max_tokens = max_tokens + return self diff --git a/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/hit_test_request.py b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/hit_test_request.py new file mode 100644 index 0000000000..afdb053e99 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/hit_test_request.py @@ -0,0 +1,37 @@ +from __future__ import annotations + +from dify_oapi.core.enum import HttpMethod +from dify_oapi.core.model.base_request import BaseRequest +from .hit_test_request_body import HitTestRequestBody + + +class HitTestRequest(BaseRequest): + def __init__(self): + super().__init__() + self.dataset_id: str | None = None + self.request_body: HitTestRequestBody | None = None + + @staticmethod + def builder() -> HitTestRequestBuilder: + return HitTestRequestBuilder() + + +class HitTestRequestBuilder(object): + def __init__(self): + hit_test_request = HitTestRequest() + hit_test_request.http_method = HttpMethod.POST + hit_test_request.uri = "/v1/datasets/:dataset_id/hit-testing" + self._hit_test_request = hit_test_request + + def build(self) -> HitTestRequest: + return self._hit_test_request + + def dataset_id(self, dataset_id: str) -> HitTestRequestBuilder: + self._hit_test_request.dataset_id = dataset_id + self._hit_test_request.paths["dataset_id"] = dataset_id + return self + + def request_body(self, request_body: HitTestRequestBody) -> HitTestRequestBuilder: + self._hit_test_request.request_body = request_body + self._hit_test_request.body = request_body.model_dump(exclude_none=True) + return self diff --git a/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/hit_test_request_body.py b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/hit_test_request_body.py new file mode 100644 index 0000000000..89c943bca2 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/hit_test_request_body.py @@ -0,0 +1,37 @@ +from __future__ import annotations +from pydantic import BaseModel +from .hit_test_request_body_retrieval_model import HitTestRequestBodyRetrievalModel + + +class HitTestRequestBody(BaseModel): + query: str | None = None + retrieval_model: HitTestRequestBodyRetrievalModel | None = None + external_retrieval_model: dict | None = None + + @staticmethod + def builder() -> HitTestRequestBodyBuilder: + return HitTestRequestBodyBuilder() + + +class HitTestRequestBodyBuilder(object): + def __init__(self): + self._hit_test_request_body = HitTestRequestBody() + + def build(self) -> HitTestRequestBody: + return self._hit_test_request_body + + def query(self, query: str) -> HitTestRequestBodyBuilder: + self._hit_test_request_body.query = query + return self + + def retrieval_model( + self, retrieval_model: HitTestRequestBodyRetrievalModel + ) -> HitTestRequestBodyBuilder: + self._hit_test_request_body.retrieval_model = retrieval_model + return self + + def external_retrieval_model( + self, external_retrieval_model: dict + ) -> HitTestRequestBodyBuilder: + self._hit_test_request_body.external_retrieval_model = external_retrieval_model + return self diff --git a/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/hit_test_request_body_retrieval_model.py b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/hit_test_request_body_retrieval_model.py new file mode 100644 index 0000000000..1e4dcd8c8f --- /dev/null +++ b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/hit_test_request_body_retrieval_model.py @@ -0,0 +1,70 @@ +from __future__ import annotations + +from typing import Literal + +from pydantic import BaseModel + + +class HitTestRequestBodyRetrievalModel(BaseModel): + search_method: str | None = None + reranking_enable: bool | None = None + reranking_mode: dict | None = None + weights: float | None = None + top_k: int | None = None + score_threshold_enabled: bool | None = None + score_threshold: float | None = None + + @staticmethod + def builder() -> HitTestRequestBodyRetrievalModelBuilder: + return HitTestRequestBodyRetrievalModelBuilder() + + +class HitTestRequestBodyRetrievalModelBuilder(object): + def __init__(self): + self._hit_test_request_body_retrieval_model = HitTestRequestBodyRetrievalModel() + + def build(self) -> HitTestRequestBodyRetrievalModel: + return self._hit_test_request_body_retrieval_model + + def set_search_method( + self, + search_method: Literal[ + "keyword_search", "semantic_search", "full_text_search", "hybrid_search" + ], + ): + self._hit_test_request_body_retrieval_model.search_method = search_method + return self + + def reranking_enable(self, reranking_enable: bool): + self._hit_test_request_body_retrieval_model.reranking_enable = reranking_enable + return self + + def reranking_provider_name(self, reranking_provider_name: str): + self._hit_test_request_body_retrieval_model.reranking_mode[ + "reranking_provider_name" + ] = reranking_provider_name + return self + + def reranking_model_name(self, reranking_model_name: str): + self._hit_test_request_body_retrieval_model.reranking_mode[ + "reranking_model_name" + ] = reranking_model_name + return self + + def weights(self, weights: float): + self._hit_test_request_body_retrieval_model.weights = weights + return self + + def top_k(self, top_k: int): + self._hit_test_request_body_retrieval_model.top_k = top_k + return self + + def score_threshold(self, score_threshold: float): + self._hit_test_request_body_retrieval_model.score_threshold = score_threshold + return self + + def score_threshold_enabled(self, score_threshold_enabled: bool): + self._hit_test_request_body_retrieval_model.score_threshold_enabled = ( + score_threshold_enabled + ) + return self diff --git a/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/hit_test_response.py b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/hit_test_response.py new file mode 100644 index 0000000000..6eba285f47 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/hit_test_response.py @@ -0,0 +1,51 @@ +from __future__ import annotations + +from dify_oapi.core.model.base_response import BaseResponse +from pydantic import BaseModel + + +class HitTestResponse(BaseResponse): + query: Query | None = None + records: list[Record] | None = None + + +class Query(BaseModel): + content: str | None = None + + +class Record(BaseModel): + segment: Segment | None = None + score: float | None = None + tsne_position: float | None = None + + +class Segment(BaseModel): + id: str | None = None + position: int | None = None + document_id: str | None = None + content: str | None = None + answer: str | None = None + word_count: int | None = None + tokens: int | None = None + keywords: list[str] | None = None + index_node_id: str | None = None + index_node_hash: str | None = None + hit_count: int | None = None + enabled: bool | None = None + disabled_at: int | None = None + disabled_by: str | None = None + status: str | None = None + created_by: str | None = None + created_at: int | None = None + indexing_at: int | None = None + completed_at: int | None = None + error: str | None = None + stopped_at: int | None = None + document: Document + + +class Document(BaseModel): + id: str | None = None + data_source_type: str | None = None + name: str | None = None + doc_type: str | None = None diff --git a/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/index_status_request.py b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/index_status_request.py new file mode 100644 index 0000000000..6d78d58611 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/index_status_request.py @@ -0,0 +1,38 @@ +from __future__ import annotations + +from dify_oapi.core.enum import HttpMethod +from dify_oapi.core.model.base_request import BaseRequest + + +class IndexStatusRequest(BaseRequest): + def __init__(self): + super().__init__() + self.dataset_id: str | None = None + self.batch: str | None = None + + @staticmethod + def builder() -> IndexStatusRequestBuilder: + return IndexStatusRequestBuilder() + + +class IndexStatusRequestBuilder(object): + def __init__(self): + index_status_request = IndexStatusRequest() + index_status_request.http_method = HttpMethod.GET + index_status_request.uri = ( + "/v1/datasets/:dataset_id/documents/:batch/indexing-status" + ) + self._index_status_request = index_status_request + + def build(self) -> IndexStatusRequest: + return self._index_status_request + + def dataset(self, dataset_id: str) -> IndexStatusRequestBuilder: + self._index_status_request.dataset_id = dataset_id + self._index_status_request.paths["dataset_id"] = dataset_id + return self + + def batch(self, batch: str) -> IndexStatusRequestBuilder: + self._index_status_request.batch = batch + self._index_status_request.paths["batch"] = batch + return self diff --git a/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/index_status_response.py b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/index_status_response.py new file mode 100644 index 0000000000..e947a66eb7 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/index_status_response.py @@ -0,0 +1,24 @@ +from __future__ import annotations + +from pydantic import BaseModel + +from dify_oapi.core.model.base_response import BaseResponse + + +class IndexStatusResponse(BaseResponse): + data: list[IndexStatusResponseData] | None = None + + +class IndexStatusResponseData(BaseModel): + id: str | None = None + indexing_status: str | None = None + processing_started_at: float | None = None + parsing_completed_at: float | None = None + cleaning_completed_at: float | None = None + splitting_completed_at: float | None = None + completed_at: float | None = None + paused_at: float | None = None + error: str | None = None + stopped_at: float | None = None + completed_segments: int | None = None + total_segments: int | None = None diff --git a/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/list_dataset_request.py b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/list_dataset_request.py new file mode 100644 index 0000000000..aef8e181ff --- /dev/null +++ b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/list_dataset_request.py @@ -0,0 +1,36 @@ +from __future__ import annotations + +from dify_oapi.core.enum import HttpMethod +from dify_oapi.core.model.base_request import BaseRequest + + +class ListDatasetRequest(BaseRequest): + def __init__(self): + super().__init__() + self.page: int | None = None + self.limit: int | None = None + + @staticmethod + def builder() -> ListDatasetRequestBuilder: + return ListDatasetRequestBuilder() + + +class ListDatasetRequestBuilder(object): + def __init__(self): + list_dataset_request = ListDatasetRequest() + list_dataset_request.http_method = HttpMethod.GET + list_dataset_request.uri = "/v1/datasets" + self._list_dataset_request = list_dataset_request + + def build(self) -> ListDatasetRequest: + return self._list_dataset_request + + def page(self, page: int) -> ListDatasetRequestBuilder: + self._list_dataset_request.page = page + self._list_dataset_request.add_query("page", page) + return self + + def limit(self, limit: int) -> ListDatasetRequestBuilder: + self._list_dataset_request.limit = limit + self._list_dataset_request.add_query("limit", limit) + return self diff --git a/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/list_dataset_response.py b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/list_dataset_response.py new file mode 100644 index 0000000000..89c52f6a6b --- /dev/null +++ b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/list_dataset_response.py @@ -0,0 +1,11 @@ +from __future__ import annotations +from dify_oapi.core.model.base_response import BaseResponse +from .dataset import Dataset + + +class ListDatasetResponse(BaseResponse): + data: list[Dataset] | None = None + has_more: bool | None = None + limit: int | None = None + total: int | None = None + page: int | None = None diff --git a/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/list_document_request.py b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/list_document_request.py new file mode 100644 index 0000000000..7b89eddadb --- /dev/null +++ b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/list_document_request.py @@ -0,0 +1,48 @@ +from __future__ import annotations + +from dify_oapi.core.enum import HttpMethod +from dify_oapi.core.model.base_request import BaseRequest + + +class ListDocumentRequest(BaseRequest): + def __init__(self): + super().__init__() + self.dataset_id: str | None = None + self.keyword: str | None = None + self.page: int | None = None + self.limit: int | None = None + + @staticmethod + def builder() -> ListDocumentRequestBuilder: + return ListDocumentRequestBuilder() + + +class ListDocumentRequestBuilder(object): + def __init__(self): + list_document_request = ListDocumentRequest() + list_document_request.http_method = HttpMethod.GET + list_document_request.uri = "/v1/datasets/:dataset_id/documents" + self._list_document_request = list_document_request + + def build(self) -> ListDocumentRequest: + return self._list_document_request + + def dataset_id(self, dataset_id: str) -> ListDocumentRequestBuilder: + self._list_document_request.dataset_id = dataset_id + self._list_document_request.paths["dataset_id"] = dataset_id + return self + + def keyword(self, keyword: str) -> ListDocumentRequestBuilder: + self._list_document_request.keyword = keyword + self._list_document_request.add_query("keyword", keyword) + return self + + def page(self, page: int) -> ListDocumentRequestBuilder: + self._list_document_request.page = page + self._list_document_request.add_query("page", page) + return self + + def limit(self, limit: int) -> ListDocumentRequestBuilder: + self._list_document_request.limit = limit + self._list_document_request.add_query("limit", limit) + return self diff --git a/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/list_document_response.py b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/list_document_response.py new file mode 100644 index 0000000000..9e46fa54bd --- /dev/null +++ b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/list_document_response.py @@ -0,0 +1,11 @@ +from dify_oapi.core.model.base_response import BaseResponse + +from .document import Document + + +class ListDocumentResponse(BaseResponse): + data: list[Document] | None = None + has_more: bool | None = None + limit: int | None = None + total: int | None = None + page: int | None = None diff --git a/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/list_segment_request.py b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/list_segment_request.py new file mode 100644 index 0000000000..dff68558a9 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/list_segment_request.py @@ -0,0 +1,50 @@ +from __future__ import annotations + +from dify_oapi.core.enum import HttpMethod +from dify_oapi.core.model.base_request import BaseRequest + + +class ListSegmentRequest(BaseRequest): + def __init__(self): + super().__init__() + self.dataset_id: str | None = None + self.document_id: str | None = None + self.keyword: str | None = None + self.status: str | None = None + + @staticmethod + def builder() -> ListSegmentRequestBuilder: + return ListSegmentRequestBuilder() + + +class ListSegmentRequestBuilder(object): + def __init__(self): + list_segment_request = ListSegmentRequest() + list_segment_request.http_method = HttpMethod.GET + list_segment_request.uri = ( + "/v1/datasets/:dataset_id/documents/:document_id/segments" + ) + self._list_segment_request = list_segment_request + + def build(self) -> ListSegmentRequest: + return self._list_segment_request + + def dataset_id(self, dataset_id: str) -> ListSegmentRequestBuilder: + self._list_segment_request.dataset_id = dataset_id + self._list_segment_request.paths["dataset_id"] = dataset_id + return self + + def document_id(self, document_id: str) -> ListSegmentRequestBuilder: + self._list_segment_request.document_id = document_id + self._list_segment_request.paths["document_id"] = document_id + return self + + def keyword(self, keyword: str) -> ListSegmentRequestBuilder: + self._list_segment_request.keyword = keyword + self._list_segment_request.add_query("keyword", keyword) + return self + + def status(self, status: str) -> ListSegmentRequestBuilder: + self._list_segment_request.status = status + self._list_segment_request.add_query("status", status) + return self diff --git a/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/list_segment_response.py b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/list_segment_response.py new file mode 100644 index 0000000000..e2cfbcc0c9 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/list_segment_response.py @@ -0,0 +1,7 @@ +from dify_oapi.core.model.base_response import BaseResponse +from .segment import Segment + + +class ListSegmentResponse(BaseResponse): + data: list[Segment] | None = None + doc_form: str | None = None diff --git a/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/segment.py b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/segment.py new file mode 100644 index 0000000000..3a555d47b0 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/segment.py @@ -0,0 +1,25 @@ +from pydantic import BaseModel + + +class Segment(BaseModel): + id: str | None = None + position: int | None = None + document_id: str | None = None + content: str | None = None + answer: str | None = None + word_count: int | None = None + tokens: int | None = None + keywords: list[str] | None = None + index_node_id: str | None = None + index_node_hash: str | None = None + hit_count: int | None = None + enabled: bool | None = None + disabled_at: int | None = None + disabled_by: str | None = None + status: str | None = None + created_by: str | None = None + created_at: int | None = None + indexing_at: int | None = None + completed_at: int | None = None + error: str | None = None + stopped_at: int | None = None diff --git a/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/update_document_by_file_request.py b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/update_document_by_file_request.py new file mode 100644 index 0000000000..a2c904003c --- /dev/null +++ b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/update_document_by_file_request.py @@ -0,0 +1,60 @@ +from __future__ import annotations + +from io import BytesIO + +from dify_oapi.core.enum import HttpMethod +from dify_oapi.core.model.base_request import BaseRequest +from .update_document_by_file_request_body import UpdateDocumentByFileRequestBody + + +class UpdateDocumentByFileRequest(BaseRequest): + def __init__(self): + super().__init__() + self.dataset_id: str | None = None + self.document_id: str | None = None + self.request_body: UpdateDocumentByFileRequestBody | None = None + self.file: BytesIO | None = None + + @staticmethod + def builder() -> UpdateDocumentByFileRequestBuilder: + return UpdateDocumentByFileRequestBuilder() + + +class UpdateDocumentByFileRequestBuilder(object): + def __init__(self): + update_document_by_file_request = UpdateDocumentByFileRequest() + update_document_by_file_request.http_method = HttpMethod.POST + update_document_by_file_request.uri = ( + "/v1/datasets/:dataset_id/documents/:document_id/update_by_file" + ) + self._update_document_by_file_request = update_document_by_file_request + + def build(self) -> UpdateDocumentByFileRequest: + return self._update_document_by_file_request + + def dataset_id(self, dataset_id: str) -> UpdateDocumentByFileRequestBuilder: + self._update_document_by_file_request.dataset_id = dataset_id + self._update_document_by_file_request.paths["dataset_id"] = dataset_id + return self + + def document_id(self, document_id: str) -> UpdateDocumentByFileRequestBuilder: + self._update_document_by_file_request.document_id = document_id + self._update_document_by_file_request.paths["document_id"] = document_id + return self + + def request_body( + self, request_body: UpdateDocumentByFileRequestBody + ) -> UpdateDocumentByFileRequestBuilder: + self._update_document_by_file_request.request_body = request_body + self._update_document_by_file_request.body = request_body.model_dump( + exclude_none=True + ) + return self + + def file( + self, file: BytesIO, file_name: str | None = None + ) -> UpdateDocumentByFileRequestBuilder: + self._update_document_by_file_request.file = file + file_name = file_name or "upload" + self._update_document_by_file_request.files = {"file": (file_name, file)} + return self diff --git a/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/update_document_by_file_request_body.py b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/update_document_by_file_request_body.py new file mode 100644 index 0000000000..fc08f36b6d --- /dev/null +++ b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/update_document_by_file_request_body.py @@ -0,0 +1,33 @@ +from __future__ import annotations + +from pydantic import BaseModel +from .document_request_process_rule import DocumentRequestProcessRule + + +class UpdateDocumentByFileRequestBody(BaseModel): + name: str | None = None + process_rule: str | None = None + + @staticmethod + def builder() -> UpdateDocumentByFileRequestBodyBuilder: + return UpdateDocumentByFileRequestBodyBuilder() + + +class UpdateDocumentByFileRequestBodyBuilder(object): + def __init__(self): + self._update_document_by_file_request_body = UpdateDocumentByFileRequestBody() + + def build(self) -> UpdateDocumentByFileRequestBody: + return self._update_document_by_file_request_body + + def name(self, name: str) -> UpdateDocumentByFileRequestBodyBuilder: + self._update_document_by_file_request_body.name = name + return self + + def process_rule( + self, process_rule: DocumentRequestProcessRule + ) -> UpdateDocumentByFileRequestBodyBuilder: + self._update_document_by_file_request_body.process_rule = ( + process_rule.model_dump_json(exclude_none=True) + ) + return self diff --git a/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/update_document_by_text_request.py b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/update_document_by_text_request.py new file mode 100644 index 0000000000..03d1eb7d59 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/update_document_by_text_request.py @@ -0,0 +1,49 @@ +from __future__ import annotations + +from dify_oapi.core.enum import HttpMethod +from dify_oapi.core.model.base_request import BaseRequest +from .update_document_by_text_request_body import UpdateDocumentByTextRequestBody + + +class UpdateDocumentByTextRequest(BaseRequest): + def __init__(self): + super().__init__() + self.dataset_id: str | None = None + self.document_id: str | None = None + self.request_body: UpdateDocumentByTextRequestBody | None = None + + @staticmethod + def builder() -> UpdateDocumentByTextRequestBuilder: + return UpdateDocumentByTextRequestBuilder() + + +class UpdateDocumentByTextRequestBuilder(object): + def __init__(self): + create_document_by_text_request = UpdateDocumentByTextRequest() + create_document_by_text_request.http_method = HttpMethod.POST + create_document_by_text_request.uri = ( + "/v1/datasets/:dataset_id/documents/:document_id/update_by_text" + ) + self._create_document_by_text_request = create_document_by_text_request + + def build(self) -> UpdateDocumentByTextRequest: + return self._create_document_by_text_request + + def dataset_id(self, dataset_id: str) -> UpdateDocumentByTextRequestBuilder: + self._create_document_by_text_request.dataset_id = dataset_id + self._create_document_by_text_request.paths["dataset_id"] = dataset_id + return self + + def document_id(self, document_id: str) -> UpdateDocumentByTextRequestBuilder: + self._create_document_by_text_request.document_id = document_id + self._create_document_by_text_request.paths["document_id"] = document_id + return self + + def request_body( + self, request_body: UpdateDocumentByTextRequestBody + ) -> UpdateDocumentByTextRequestBuilder: + self._create_document_by_text_request.request_body = request_body + self._create_document_by_text_request.body = request_body.model_dump( + exclude_none=True + ) + return self diff --git a/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/update_document_by_text_request_body.py b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/update_document_by_text_request_body.py new file mode 100644 index 0000000000..13a1c4624e --- /dev/null +++ b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/update_document_by_text_request_body.py @@ -0,0 +1,37 @@ +from __future__ import annotations + + +from pydantic import BaseModel +from .document_request_process_rule import DocumentRequestProcessRule + + +class UpdateDocumentByTextRequestBody(BaseModel): + name: str | None = None + text: str | None = None + process_rule: DocumentRequestProcessRule | None = None + + @staticmethod + def builder() -> UpdateDocumentByTextRequestBodyBuilder: + return UpdateDocumentByTextRequestBodyBuilder() + + +class UpdateDocumentByTextRequestBodyBuilder(object): + def __init__(self): + self._update_document_by_text_request_body = UpdateDocumentByTextRequestBody() + + def build(self) -> UpdateDocumentByTextRequestBody: + return self._update_document_by_text_request_body + + def name(self, name: str) -> UpdateDocumentByTextRequestBodyBuilder: + self._update_document_by_text_request_body.name = name + return self + + def text(self, text: str) -> UpdateDocumentByTextRequestBodyBuilder: + self._update_document_by_text_request_body.text = text + return self + + def process_rule( + self, process_rule: DocumentRequestProcessRule + ) -> UpdateDocumentByTextRequestBodyBuilder: + self._update_document_by_text_request_body.process_rule = process_rule + return self diff --git a/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/update_document_response.py b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/update_document_response.py new file mode 100644 index 0000000000..76e0ac6ef0 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/update_document_response.py @@ -0,0 +1,56 @@ +from __future__ import annotations + +from pydantic import BaseModel + +from dify_oapi.core.model.base_response import BaseResponse + + +class UpdateDocumentResponse(BaseResponse): + document: UpdateDocumentResponseDocument | None = None + batch: str | None = None + + +class UpdateDocumentResponseDocument(BaseModel): + id: str | None = None + position: int | None = None + data_source_type: str | None = None + data_source_info: UpdateDocumentResponseDocumentDataSourceInfo | None = None + data_source_detail_dict: ( + UpdateDocumentResponseDocumentDataSourceDetailDict | None + ) = None + dataset_process_rule_id: str | None = None + name: str | None = None + created_from: str | None = None + created_by: str | None = None + created_at: int | None = None + tokens: int | None = None + indexing_status: str | None = None + error: str | None = None + enabled: bool | None = None + disabled_at: int | None = None + disabled_by: str | None = None + archived: bool | None = None + display_status: str | None = None + word_count: int | None = None + hit_count: int | None = None + doc_form: str | None = None + + +class UpdateDocumentResponseDocumentDataSourceInfo(BaseModel): + upload_file_id: str | None = None + + +class UpdateDocumentResponseDocumentDataSourceDetailDict(BaseModel): + upload_file: UpdateDocumentResponseDocumentDataSourceDetailDictUploadFile | None = ( + None + ) + + +class UpdateDocumentResponseDocumentDataSourceDetailDictUploadFile(BaseModel): + id: str | None = None + name: str | None = None + size: int | None = None + extension: str | None = None + mime_type: str | None = None + created_by: str | None = None + created_at: float | None = None diff --git a/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/update_segment_request.py b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/update_segment_request.py new file mode 100644 index 0000000000..dcac103780 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/update_segment_request.py @@ -0,0 +1,53 @@ +from __future__ import annotations + +from dify_oapi.core.enum import HttpMethod +from dify_oapi.core.model.base_request import BaseRequest +from .update_segment_request_body import UpdateSegmentRequestBody + + +class UpdateSegmentRequest(BaseRequest): + def __init__(self): + super().__init__() + self.dataset_id: str | None = None + self.document_id: str | None = None + self.segment_id: str | None = None + self.request_body: UpdateSegmentRequestBody | None = None + + @staticmethod + def builder() -> UpdateSegmentRequestBuilder: + return UpdateSegmentRequestBuilder() + + +class UpdateSegmentRequestBuilder(object): + def __init__(self): + update_segment_request = UpdateSegmentRequest() + update_segment_request.http_method = HttpMethod.POST + update_segment_request.uri = ( + "/v1/datasets/:dataset_id/documents/:document_id/segments/:segment_id" + ) + self._update_segment_request = update_segment_request + + def build(self) -> UpdateSegmentRequest: + return self._update_segment_request + + def dataset_id(self, dataset_id: str) -> UpdateSegmentRequestBuilder: + self._update_segment_request.dataset_id = dataset_id + self._update_segment_request.paths["dataset_id"] = dataset_id + return self + + def document_id(self, document_id: str) -> UpdateSegmentRequestBuilder: + self._update_segment_request.document_id = document_id + self._update_segment_request.paths["document_id"] = document_id + return self + + def segment_id(self, segment_id: str) -> UpdateSegmentRequestBuilder: + self._update_segment_request.segment_id = segment_id + self._update_segment_request.paths["segment_id"] = segment_id + return self + + def request_body( + self, request_body: UpdateSegmentRequestBody + ) -> UpdateSegmentRequestBuilder: + self._update_segment_request.request_body = request_body + self._update_segment_request.body = request_body.model_dump(exclude_none=True) + return self diff --git a/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/update_segment_request_body.py b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/update_segment_request_body.py new file mode 100644 index 0000000000..5f7f575f7c --- /dev/null +++ b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/update_segment_request_body.py @@ -0,0 +1,25 @@ +from __future__ import annotations +from pydantic import BaseModel +from .update_segment_request_body_segment import UpdateSegmentRequestBodySegment + + +class UpdateSegmentRequestBody(BaseModel): + segment: UpdateSegmentRequestBodySegment | None = None + + @staticmethod + def builder() -> UpdateSegmentRequestBodyBuilder: + return UpdateSegmentRequestBodyBuilder() + + +class UpdateSegmentRequestBodyBuilder(object): + def __init__(self): + self._update_segment_request_body = UpdateSegmentRequestBody() + + def build(self) -> UpdateSegmentRequestBody: + return self._update_segment_request_body + + def segment( + self, segment: UpdateSegmentRequestBodySegment + ) -> UpdateSegmentRequestBodyBuilder: + self._update_segment_request_body.segment = segment + return self diff --git a/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/update_segment_request_body_segment.py b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/update_segment_request_body_segment.py new file mode 100644 index 0000000000..942d887375 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/update_segment_request_body_segment.py @@ -0,0 +1,37 @@ +from __future__ import annotations +from pydantic import BaseModel + + +class UpdateSegmentRequestBodySegment(BaseModel): + content: str | None = None + answer: str | None = None + keywords: list | None = None + enabled: bool | None = None + + @staticmethod + def builder() -> UpdateSegmentRequestBodySegmentBuilder: + return UpdateSegmentRequestBodySegmentBuilder() + + +class UpdateSegmentRequestBodySegmentBuilder(object): + def __init__(self): + self._update_segment_request_body_segment = UpdateSegmentRequestBodySegment() + + def build(self) -> UpdateSegmentRequestBodySegment: + return self._update_segment_request_body_segment + + def content(self, content: str) -> UpdateSegmentRequestBodySegmentBuilder: + self._update_segment_request_body_segment.content = content + return self + + def answer(self, answer: str) -> UpdateSegmentRequestBodySegmentBuilder: + self._update_segment_request_body_segment.answer = answer + return self + + def keywords(self, keywords: list[str]) -> UpdateSegmentRequestBodySegmentBuilder: + self._update_segment_request_body_segment.keywords = keywords + return self + + def enabled(self, enabled: bool) -> UpdateSegmentRequestBodySegmentBuilder: + self._update_segment_request_body_segment.enabled = enabled + return self diff --git a/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/update_segment_response.py b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/update_segment_response.py new file mode 100644 index 0000000000..1dee3af1e3 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/knowledge_base/v1/model/update_segment_response.py @@ -0,0 +1,7 @@ +from dify_oapi.core.model.base_response import BaseResponse +from .segment import Segment + + +class UpdateSegmentResponse(BaseResponse): + data: Segment | None = None + doc_form: str | None = None diff --git a/sdks/python-client/dify_oapi/api/knowledge_base/v1/resource/__init__.py b/sdks/python-client/dify_oapi/api/knowledge_base/v1/resource/__init__.py new file mode 100644 index 0000000000..f467f22d30 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/knowledge_base/v1/resource/__init__.py @@ -0,0 +1,3 @@ +from .dataset import * # noqa 403 +from .document import * # noqa 403 +from .segment import * # noqa 403 diff --git a/sdks/python-client/dify_oapi/api/knowledge_base/v1/resource/dataset.py b/sdks/python-client/dify_oapi/api/knowledge_base/v1/resource/dataset.py new file mode 100644 index 0000000000..a051d87711 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/knowledge_base/v1/resource/dataset.py @@ -0,0 +1,73 @@ +from dify_oapi.core.http.transport import ATransport, Transport +from dify_oapi.core.model.config import Config +from dify_oapi.core.model.request_option import RequestOption + +from ..model.create_dataset_request import CreateDatasetRequest +from ..model.create_dataset_response import CreateDatasetResponse +from ..model.list_dataset_request import ListDatasetRequest +from ..model.list_dataset_response import ListDatasetResponse +from ..model.delete_dataset_request import DeleteDatasetRequest +from ..model.delete_dataset_response import DeleteDatasetResponse +from ..model.hit_test_request import HitTestRequest +from ..model.hit_test_response import HitTestResponse + + +class Dataset: + def __init__(self, config: Config) -> None: + self.config: Config = config + + def create( + self, request: CreateDatasetRequest, option: RequestOption | None = None + ) -> CreateDatasetResponse: + return Transport.execute( + self.config, request, unmarshal_as=CreateDatasetResponse, option=option + ) + + async def acreate( + self, request: CreateDatasetRequest, option: RequestOption | None = None + ) -> CreateDatasetResponse: + return await ATransport.aexecute( + self.config, request, unmarshal_as=CreateDatasetResponse, option=option + ) + + def list( + self, request: ListDatasetRequest, option: RequestOption | None = None + ) -> ListDatasetResponse: + return Transport.execute( + self.config, request, unmarshal_as=ListDatasetResponse, option=option + ) + + async def alist( + self, request: ListDatasetRequest, option: RequestOption | None = None + ) -> ListDatasetResponse: + return await ATransport.aexecute( + self.config, request, unmarshal_as=ListDatasetResponse, option=option + ) + + def delete( + self, request: DeleteDatasetRequest, option: RequestOption | None = None + ) -> DeleteDatasetResponse: + return Transport.execute( + self.config, request, unmarshal_as=DeleteDatasetResponse, option=option + ) + + async def adelete( + self, request: DeleteDatasetRequest, option: RequestOption | None = None + ) -> DeleteDatasetResponse: + return await ATransport.aexecute( + self.config, request, unmarshal_as=DeleteDatasetResponse, option=option + ) + + def hit_test( + self, request: HitTestRequest, option: RequestOption | None = None + ) -> HitTestResponse: + return Transport.execute( + self.config, request, unmarshal_as=HitTestResponse, option=option + ) + + async def ahit_test( + self, request: HitTestRequest, option: RequestOption | None = None + ) -> HitTestResponse: + return await ATransport.aexecute( + self.config, request, unmarshal_as=HitTestResponse, option=option + ) diff --git a/sdks/python-client/dify_oapi/api/knowledge_base/v1/resource/document.py b/sdks/python-client/dify_oapi/api/knowledge_base/v1/resource/document.py new file mode 100644 index 0000000000..a9b634640d --- /dev/null +++ b/sdks/python-client/dify_oapi/api/knowledge_base/v1/resource/document.py @@ -0,0 +1,119 @@ +from dify_oapi.core.http.transport import ATransport, Transport +from dify_oapi.core.model.config import Config +from dify_oapi.core.model.request_option import RequestOption + +from ..model.create_document_by_text_request import CreateDocumentByTextRequest +from ..model.create_document_by_file_request import CreateDocumentByFileRequest +from ..model.create_document_response import CreateDocumentResponse +from ..model.update_document_by_text_request import UpdateDocumentByTextRequest +from ..model.update_document_by_file_request import UpdateDocumentByFileRequest +from ..model.update_document_response import UpdateDocumentResponse +from ..model.delete_document_request import DeleteDocumentRequest +from ..model.delete_document_response import DeleteDocumentResponse +from ..model.list_document_request import ListDocumentRequest +from ..model.list_document_response import ListDocumentResponse +from ..model.index_status_request import IndexStatusRequest +from ..model.index_status_response import IndexStatusResponse + + +class Document: + def __init__(self, config: Config) -> None: + self.config: Config = config + + def create_by_text( + self, request: CreateDocumentByTextRequest, option: RequestOption | None = None + ) -> CreateDocumentResponse: + return Transport.execute( + self.config, request, unmarshal_as=CreateDocumentResponse, option=option + ) + + async def acreate_by_text( + self, request: CreateDocumentByTextRequest, option: RequestOption | None = None + ) -> CreateDocumentResponse: + return await ATransport.aexecute( + self.config, request, unmarshal_as=CreateDocumentResponse, option=option + ) + + def update_by_text( + self, request: UpdateDocumentByTextRequest, option: RequestOption | None = None + ) -> UpdateDocumentResponse: + return Transport.execute( + self.config, request, unmarshal_as=UpdateDocumentResponse, option=option + ) + + async def aupdate_by_text( + self, request: UpdateDocumentByTextRequest, option: RequestOption | None = None + ) -> UpdateDocumentResponse: + return await ATransport.aexecute( + self.config, request, unmarshal_as=UpdateDocumentResponse, option=option + ) + + def create_by_file( + self, request: CreateDocumentByFileRequest, option: RequestOption | None = None + ) -> CreateDocumentResponse: + return Transport.execute( + self.config, request, unmarshal_as=CreateDocumentResponse, option=option + ) + + async def acreate_by_file( + self, request: CreateDocumentByFileRequest, option: RequestOption | None = None + ) -> CreateDocumentResponse: + return await ATransport.aexecute( + self.config, request, unmarshal_as=CreateDocumentResponse, option=option + ) + + def update_by_file( + self, request: UpdateDocumentByFileRequest, option: RequestOption | None = None + ) -> UpdateDocumentResponse: + return Transport.execute( + self.config, request, unmarshal_as=UpdateDocumentResponse, option=option + ) + + async def aupdate_by_file( + self, request: UpdateDocumentByFileRequest, option: RequestOption | None = None + ) -> UpdateDocumentResponse: + return await ATransport.aexecute( + self.config, request, unmarshal_as=UpdateDocumentResponse, option=option + ) + + def list( + self, request: ListDocumentRequest, option: RequestOption | None = None + ) -> ListDocumentResponse: + return Transport.execute( + self.config, request, unmarshal_as=ListDocumentResponse, option=option + ) + + async def alist( + self, request: ListDocumentRequest, option: RequestOption | None = None + ) -> ListDocumentResponse: + return await ATransport.aexecute( + self.config, request, unmarshal_as=ListDocumentResponse, option=option + ) + + def delete( + self, request: DeleteDocumentRequest, option: RequestOption | None = None + ) -> DeleteDocumentResponse: + return Transport.execute( + self.config, request, unmarshal_as=DeleteDocumentResponse, option=option + ) + + async def adelete( + self, request: DeleteDocumentRequest, option: RequestOption | None = None + ) -> DeleteDocumentResponse: + return await ATransport.aexecute( + self.config, request, unmarshal_as=DeleteDocumentResponse, option=option + ) + + def indexing_status( + self, request: IndexStatusRequest, option: RequestOption | None = None + ) -> IndexStatusResponse: + return Transport.execute( + self.config, request, unmarshal_as=IndexStatusResponse, option=option + ) + + async def aindexing_status( + self, request: IndexStatusRequest, option: RequestOption | None = None + ) -> IndexStatusResponse: + return await ATransport.aexecute( + self.config, request, unmarshal_as=IndexStatusResponse, option=option + ) diff --git a/sdks/python-client/dify_oapi/api/knowledge_base/v1/resource/segment.py b/sdks/python-client/dify_oapi/api/knowledge_base/v1/resource/segment.py new file mode 100644 index 0000000000..aeced98640 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/knowledge_base/v1/resource/segment.py @@ -0,0 +1,73 @@ +from dify_oapi.core.http.transport import ATransport, Transport +from dify_oapi.core.model.config import Config +from dify_oapi.core.model.request_option import RequestOption + +from ..model.create_segment_request import CreateSegmentRequest +from ..model.create_segment_response import CreateSegmentResponse +from ..model.list_segment_request import ListSegmentRequest +from ..model.list_segment_response import ListSegmentResponse +from ..model.delete_segment_request import DeleteSegmentRequest +from ..model.delete_segment_response import DeleteSegmentResponse +from ..model.update_segment_request import UpdateSegmentRequest +from ..model.update_segment_response import UpdateSegmentResponse + + +class Segment: + def __init__(self, config: Config) -> None: + self.config: Config = config + + def create( + self, request: CreateSegmentRequest, option: RequestOption | None = None + ) -> CreateSegmentResponse: + return Transport.execute( + self.config, request, unmarshal_as=CreateSegmentResponse, option=option + ) + + async def acreate( + self, request: CreateSegmentRequest, option: RequestOption | None = None + ) -> CreateSegmentResponse: + return await ATransport.aexecute( + self.config, request, unmarshal_as=CreateSegmentResponse, option=option + ) + + def list( + self, request: ListSegmentRequest, option: RequestOption | None = None + ) -> ListSegmentResponse: + return Transport.execute( + self.config, request, unmarshal_as=ListSegmentResponse, option=option + ) + + async def alist( + self, request: ListSegmentRequest, option: RequestOption | None = None + ) -> ListSegmentResponse: + return await ATransport.aexecute( + self.config, request, unmarshal_as=ListSegmentResponse, option=option + ) + + def delete( + self, request: DeleteSegmentRequest, option: RequestOption | None = None + ) -> DeleteSegmentResponse: + return Transport.execute( + self.config, request, unmarshal_as=DeleteSegmentResponse, option=option + ) + + async def adelete( + self, request: DeleteSegmentRequest, option: RequestOption | None = None + ) -> DeleteSegmentResponse: + return await ATransport.aexecute( + self.config, request, unmarshal_as=DeleteSegmentResponse, option=option + ) + + def update( + self, request: UpdateSegmentRequest, option: RequestOption | None = None + ) -> UpdateSegmentResponse: + return Transport.execute( + self.config, request, unmarshal_as=UpdateSegmentResponse, option=option + ) + + async def aupdate( + self, request: UpdateSegmentRequest, option: RequestOption | None = None + ) -> UpdateSegmentResponse: + return await ATransport.aexecute( + self.config, request, unmarshal_as=UpdateSegmentResponse, option=option + ) diff --git a/sdks/python-client/dify_oapi/api/knowledge_base/v1/version.py b/sdks/python-client/dify_oapi/api/knowledge_base/v1/version.py new file mode 100644 index 0000000000..5288d813cd --- /dev/null +++ b/sdks/python-client/dify_oapi/api/knowledge_base/v1/version.py @@ -0,0 +1,10 @@ +from dify_oapi.core.model.config import Config + +from .resource import Dataset, Document, Segment + + +class V1: + def __init__(self, config: Config): + self.dataset: Dataset = Dataset(config) + self.document: Document = Document(config) + self.segment: Segment = Segment(config) diff --git a/sdks/python-client/dify_oapi/api/workflow/__init__.py b/sdks/python-client/dify_oapi/api/workflow/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/sdks/python-client/dify_oapi/api/workflow/service.py b/sdks/python-client/dify_oapi/api/workflow/service.py new file mode 100644 index 0000000000..8a5a9c4aa0 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/workflow/service.py @@ -0,0 +1,8 @@ +from dify_oapi.core.model.config import Config + +from .v1.version import V1 + + +class WorkflowService: + def __init__(self, config: Config) -> None: + self.v1: V1 = V1(config) diff --git a/sdks/python-client/dify_oapi/api/workflow/v1/__init__.py b/sdks/python-client/dify_oapi/api/workflow/v1/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/sdks/python-client/dify_oapi/api/workflow/v1/model/__init__.py b/sdks/python-client/dify_oapi/api/workflow/v1/model/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/sdks/python-client/dify_oapi/api/workflow/v1/model/get_workflow_result_request.py b/sdks/python-client/dify_oapi/api/workflow/v1/model/get_workflow_result_request.py new file mode 100644 index 0000000000..c796574e40 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/workflow/v1/model/get_workflow_result_request.py @@ -0,0 +1,30 @@ +from __future__ import annotations + +from dify_oapi.core.enum import HttpMethod +from dify_oapi.core.model.base_request import BaseRequest + + +class GetWorkflowResultRequest(BaseRequest): + def __init__(self): + super().__init__() + self.workflow_id: str | None = None + + @staticmethod + def builder() -> GetWorkflowResultRequestBuilder: + return GetWorkflowResultRequestBuilder() + + +class GetWorkflowResultRequestBuilder(object): + def __init__(self): + get_workflow_request = GetWorkflowResultRequest() + get_workflow_request.http_method = HttpMethod.GET + get_workflow_request.uri = "/v1/workflows/run/:workflow_id" + self._get_workflow_request = get_workflow_request + + def build(self): + return self._get_workflow_request + + def workflow_id(self, workflow_id: str) -> GetWorkflowResultRequestBuilder: + self._get_workflow_request.workflow_id = workflow_id + self._get_workflow_request.paths["workflow_id"] = workflow_id + return self diff --git a/sdks/python-client/dify_oapi/api/workflow/v1/model/get_workflow_result_response.py b/sdks/python-client/dify_oapi/api/workflow/v1/model/get_workflow_result_response.py new file mode 100644 index 0000000000..9ce801acbc --- /dev/null +++ b/sdks/python-client/dify_oapi/api/workflow/v1/model/get_workflow_result_response.py @@ -0,0 +1,18 @@ +from __future__ import annotations + + +from dify_oapi.core.model.base_response import BaseResponse + + +class GetWorkflowResultResponse(BaseResponse): + id: str | None = None + workflow_id: str | None = None + status: str | None = None + inputs: str | None = None + outputs: str | None = None + error: str | None = None + elapsed_time: float | None = None + total_tokens: int | None = None + total_steps: int | None = None + created_at: str | None = None + finished_at: str | None = None diff --git a/sdks/python-client/dify_oapi/api/workflow/v1/model/run_workflow_request.py b/sdks/python-client/dify_oapi/api/workflow/v1/model/run_workflow_request.py new file mode 100644 index 0000000000..6494f3cdee --- /dev/null +++ b/sdks/python-client/dify_oapi/api/workflow/v1/model/run_workflow_request.py @@ -0,0 +1,34 @@ +from __future__ import annotations + +from dify_oapi.core.enum import HttpMethod +from dify_oapi.core.model.base_request import BaseRequest + +from .run_workflow_request_body import RunWorkflowRequestBody + + +class RunWorkflowRequest(BaseRequest): + def __init__(self) -> None: + super().__init__() + self.request_body: RunWorkflowRequestBody | None = None + + @staticmethod + def builder() -> RunWorkflowRequestBuilder: + return RunWorkflowRequestBuilder() + + +class RunWorkflowRequestBuilder: + def __init__(self) -> None: + run_workflow_request = RunWorkflowRequest() + run_workflow_request.http_method = HttpMethod.POST + run_workflow_request.uri = "/v1/workflows/run" + self._run_workflow_request: RunWorkflowRequest = run_workflow_request + + def request_body( + self, request_body: RunWorkflowRequestBody + ) -> RunWorkflowRequestBuilder: + self._run_workflow_request.request_body = request_body + self._run_workflow_request.body = request_body.model_dump(exclude_none=True) + return self + + def build(self) -> RunWorkflowRequest: + return self._run_workflow_request diff --git a/sdks/python-client/dify_oapi/api/workflow/v1/model/run_workflow_request_body.py b/sdks/python-client/dify_oapi/api/workflow/v1/model/run_workflow_request_body.py new file mode 100644 index 0000000000..a55095547e --- /dev/null +++ b/sdks/python-client/dify_oapi/api/workflow/v1/model/run_workflow_request_body.py @@ -0,0 +1,43 @@ +from __future__ import annotations + +from pydantic import BaseModel +from .run_workflow_request_file import RunWorkflowRequestFile + + +class RunWorkflowRequestBody(BaseModel): + inputs: dict | None = None + response_mode: str | None = None + user: str | None = None + files: list[RunWorkflowRequestFile] | None = None + + @staticmethod + def builder() -> RunWorkflowRequestBodyBuilder: + return RunWorkflowRequestBodyBuilder() + + +class RunWorkflowRequestBodyBuilder(object): + def __init__(self): + self._run_workflow_body = RunWorkflowRequestBody() + + def build(self): + return self._run_workflow_body + + def inputs(self, inputs: dict) -> RunWorkflowRequestBodyBuilder: + self._run_workflow_body.inputs = inputs + return self + + def response_mode(self, response_mode: str) -> RunWorkflowRequestBodyBuilder: + if response_mode not in ["streaming", "blocking"]: + raise ValueError('response_mode must be either "streaming" or "blocking"') + self._run_workflow_body.response_mode = response_mode + return self + + def user(self, user: str) -> RunWorkflowRequestBodyBuilder: + self._run_workflow_body.user = user + return self + + def files( + self, files: list[RunWorkflowRequestFile] + ) -> RunWorkflowRequestBodyBuilder: + self._run_workflow_body.files = files + return self diff --git a/sdks/python-client/dify_oapi/api/workflow/v1/model/run_workflow_request_file.py b/sdks/python-client/dify_oapi/api/workflow/v1/model/run_workflow_request_file.py new file mode 100755 index 0000000000..d0fa545370 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/workflow/v1/model/run_workflow_request_file.py @@ -0,0 +1,54 @@ +from __future__ import annotations + +from pydantic import BaseModel, HttpUrl + + +class RunWorkflowRequestFile(BaseModel): + type: str | None = None + transfer_method: str | None = None + url: HttpUrl | None = None + upload_file_id: str | None = None + + @staticmethod + def builder() -> RunWorkflowRequestFileBuilder: + return RunWorkflowRequestFileBuilder() + + +class RunWorkflowRequestFileBuilder: + def __init__(self): + self._run_workflow_request_file = RunWorkflowRequestFile() + + def type(self, type_: str): + self._run_workflow_request_file.type = type_ + return self + + def transfer_method(self, transfer_method: str): + if transfer_method not in ("remote_url", "local_file"): + raise ValueError("Only 'remote_url' and 'local_file' are supported") + self._run_workflow_request_file.transfer_method = transfer_method + return self + + def url(self, url: str): + self._run_workflow_request_file.url = HttpUrl(url=url) + return self + + def upload_file_id(self, upload_file_id: str): + self._run_workflow_request_file.upload_file_id = upload_file_id + return self + + def build(self) -> RunWorkflowRequestFile: + if ( + self._run_workflow_request_file.transfer_method == "remote_url" + and self._run_workflow_request_file.url is None + ): + raise ValueError( + "Url needs to be set when transfer_method is set as remote_url" + ) + if ( + self._run_workflow_request_file.transfer_method == "local_file" + and self._run_workflow_request_file.upload_file_id is None + ): + raise ValueError( + "Upload file_id needs to be set when transfer_method is set as local_file" + ) + return self._run_workflow_request_file diff --git a/sdks/python-client/dify_oapi/api/workflow/v1/model/run_workflow_response.py b/sdks/python-client/dify_oapi/api/workflow/v1/model/run_workflow_response.py new file mode 100644 index 0000000000..e2c1ca52b7 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/workflow/v1/model/run_workflow_response.py @@ -0,0 +1,24 @@ +from __future__ import annotations + +from pydantic import BaseModel + +from dify_oapi.core.model.base_response import BaseResponse + + +class RunWorkflowResponse(BaseResponse): + workflow_run_id: str | None = None + task_id: str | None = None + data: RunWorkflowResponseData | None = None + + +class RunWorkflowResponseData(BaseModel): + id: str | None = None + workflow_id: str | None = None + status: str | None = None + outputs: dict | None = None + error: str | None = None + elapsed_time: float | None = None + total_tokens: int | None = None + total_steps: int | None = None + created_at: int | None = None + finished_at: int | None = None diff --git a/sdks/python-client/dify_oapi/api/workflow/v1/model/stop_workflow_request.py b/sdks/python-client/dify_oapi/api/workflow/v1/model/stop_workflow_request.py new file mode 100755 index 0000000000..e7ddf745fa --- /dev/null +++ b/sdks/python-client/dify_oapi/api/workflow/v1/model/stop_workflow_request.py @@ -0,0 +1,40 @@ +from __future__ import annotations + +from dify_oapi.core.enum import HttpMethod +from dify_oapi.core.model.base_request import BaseRequest + +from .stop_workflow_request_body import StopWorkflowRequestBody + + +class StopWorkflowRequest(BaseRequest): + def __init__(self) -> None: + super().__init__() + self.task_id: str | None = None + self.request_body: StopWorkflowRequestBody | None = None + + @staticmethod + def builder() -> StopWorkflowRequestBuilder: + return StopWorkflowRequestBuilder() + + +class StopWorkflowRequestBuilder: + def __init__(self) -> None: + stop_Workflow_request = StopWorkflowRequest() + stop_Workflow_request.http_method = HttpMethod.POST + stop_Workflow_request.uri = "/v1/workflows/tasks/:task_id/stop" + self._stop_workflow_request: StopWorkflowRequest = stop_Workflow_request + + def task_id(self, task_id: str) -> StopWorkflowRequestBuilder: + self._stop_workflow_request.task_id = task_id + self._stop_workflow_request.paths["task_id"] = str(task_id) + return self + + def request_body( + self, request_body: StopWorkflowRequestBody + ) -> StopWorkflowRequestBuilder: + self._stop_workflow_request.request_body = request_body + self._stop_workflow_request.body = request_body.model_dump(exclude_none=True) + return self + + def build(self) -> StopWorkflowRequest: + return self._stop_workflow_request diff --git a/sdks/python-client/dify_oapi/api/workflow/v1/model/stop_workflow_request_body.py b/sdks/python-client/dify_oapi/api/workflow/v1/model/stop_workflow_request_body.py new file mode 100755 index 0000000000..5bc8c61db7 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/workflow/v1/model/stop_workflow_request_body.py @@ -0,0 +1,23 @@ +from __future__ import annotations + +from pydantic import BaseModel + + +class StopWorkflowRequestBody(BaseModel): + user: str | None = None + + @staticmethod + def builder() -> StopWorkflowRequestBodyBuilder: + return StopWorkflowRequestBodyBuilder() + + +class StopWorkflowRequestBodyBuilder: + def __init__(self): + self._stop_workflow_request_body = StopWorkflowRequestBody() + + def user(self, user: str) -> StopWorkflowRequestBodyBuilder: + self._stop_workflow_request_body.user = user + return self + + def build(self) -> StopWorkflowRequestBody: + return self._stop_workflow_request_body diff --git a/sdks/python-client/dify_oapi/api/workflow/v1/model/stop_workflow_response.py b/sdks/python-client/dify_oapi/api/workflow/v1/model/stop_workflow_response.py new file mode 100755 index 0000000000..d540be358c --- /dev/null +++ b/sdks/python-client/dify_oapi/api/workflow/v1/model/stop_workflow_response.py @@ -0,0 +1,5 @@ +from dify_oapi.core.model.base_response import BaseResponse + + +class StopWorkflowResponse(BaseResponse): + result: str | None = None diff --git a/sdks/python-client/dify_oapi/api/workflow/v1/resource/__init__.py b/sdks/python-client/dify_oapi/api/workflow/v1/resource/__init__.py new file mode 100644 index 0000000000..33260bb476 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/workflow/v1/resource/__init__.py @@ -0,0 +1 @@ +from .workflow import * # noqa 403 diff --git a/sdks/python-client/dify_oapi/api/workflow/v1/resource/workflow.py b/sdks/python-client/dify_oapi/api/workflow/v1/resource/workflow.py new file mode 100644 index 0000000000..c92dca0350 --- /dev/null +++ b/sdks/python-client/dify_oapi/api/workflow/v1/resource/workflow.py @@ -0,0 +1,123 @@ +from collections.abc import AsyncGenerator, Generator +from typing import Literal, overload + +from dify_oapi.core.const import APPLICATION_JSON, CONTENT_TYPE +from dify_oapi.core.http.transport import ATransport, Transport +from dify_oapi.core.model.config import Config +from dify_oapi.core.model.request_option import RequestOption + +from ..model.run_workflow_request import RunWorkflowRequest +from ..model.run_workflow_response import RunWorkflowResponse +from ..model.stop_workflow_request import StopWorkflowRequest +from ..model.stop_workflow_response import StopWorkflowResponse +from ..model.get_workflow_result_request import GetWorkflowResultRequest +from ..model.get_workflow_result_response import GetWorkflowResultResponse + + +class Workflow: + def __init__(self, config: Config) -> None: + self.config: Config = config + + @overload + def run( + self, + request: RunWorkflowRequest, + option: RequestOption | None, + stream: Literal[True], + ) -> Generator[bytes, None, None]: ... + + @overload + def run( + self, + request: RunWorkflowRequest, + option: RequestOption | None, + stream: Literal[False], + ) -> RunWorkflowResponse: ... + + @overload + def run( + self, request: RunWorkflowRequest, option: RequestOption | None + ) -> RunWorkflowResponse: ... + + def run( + self, + request: RunWorkflowRequest, + option: RequestOption | None = None, + stream: bool = False, + ): + if request.body is not None: + option.headers[CONTENT_TYPE] = f"{APPLICATION_JSON}; charset=utf-8" + if stream: + return Transport.execute(self.config, request, option=option, stream=True) + else: + return Transport.execute( + self.config, request, unmarshal_as=RunWorkflowResponse, option=option + ) + + @overload + async def arun( + self, + request: RunWorkflowRequest, + option: RequestOption | None, + stream: Literal[True], + ) -> AsyncGenerator[bytes, None]: ... + + @overload + def arun( + self, + request: RunWorkflowRequest, + option: RequestOption | None, + stream: Literal[False], + ) -> RunWorkflowResponse: ... + + @overload + async def arun( + self, request: RunWorkflowRequest, option: RequestOption | None + ) -> RunWorkflowResponse: ... + + async def arun( + self, + request: RunWorkflowRequest, + option: RequestOption | None = None, + stream: bool = False, + ): + if stream: + return await ATransport.aexecute( + self.config, request, option=option, stream=True + ) + else: + return await ATransport.aexecute( + self.config, request, unmarshal_as=RunWorkflowResponse, option=option + ) + + def stop( + self, request: StopWorkflowRequest, option: RequestOption | None = None + ) -> StopWorkflowResponse: + if request.body is not None: + option.headers[CONTENT_TYPE] = f"{APPLICATION_JSON}; charset=utf-8" + return Transport.execute( + self.config, request, unmarshal_as=StopWorkflowResponse, option=option + ) + + async def astop( + self, request: StopWorkflowRequest, option: RequestOption | None = None + ) -> StopWorkflowResponse: + return await ATransport.aexecute( + self.config, request, unmarshal_as=StopWorkflowResponse, option=option + ) + + def result( + self, request: GetWorkflowResultRequest, option: RequestOption | None = None + ) -> GetWorkflowResultResponse: + if request.body is not None: + option.headers[CONTENT_TYPE] = f"{APPLICATION_JSON}; charset=utf-8" + return Transport.execute( + self.config, request, unmarshal_as=GetWorkflowResultResponse, option=option + ) + + async def aresult( + self, request: GetWorkflowResultRequest, option: RequestOption | None = None + ) -> GetWorkflowResultResponse: + return await ATransport.aexecute( + self.config, request, unmarshal_as=GetWorkflowResultResponse, option=option + ) diff --git a/sdks/python-client/dify_oapi/api/workflow/v1/version.py b/sdks/python-client/dify_oapi/api/workflow/v1/version.py new file mode 100644 index 0000000000..b66391df7c --- /dev/null +++ b/sdks/python-client/dify_oapi/api/workflow/v1/version.py @@ -0,0 +1,8 @@ +from dify_oapi.core.model.config import Config + +from .resource import Workflow + + +class V1: + def __init__(self, config: Config): + self.workflow: Workflow = Workflow(config) diff --git a/sdks/python-client/dify_oapi/client.py b/sdks/python-client/dify_oapi/client.py new file mode 100755 index 0000000000..35c69dd27e --- /dev/null +++ b/sdks/python-client/dify_oapi/client.py @@ -0,0 +1,56 @@ +from __future__ import annotations + +from .api.chat.service import ChatService +from .api.completion.service import CompletionService +from .api.dify.service import DifyService +from .api.workflow.service import WorkflowService +from .api.knowledge_base.service import KnowledgeBaseService +from .core.http.transport import Transport +from .core.log import logger +from .core.model.base_request import BaseRequest +from .core.model.config import Config + + +class Client: + def __init__(self): + self._config: Config | None = None + self.chat: ChatService | None = None + self.completion: CompletionService | None = None + self.dify: DifyService | None = None + self.workflow: WorkflowService | None = None + self.knowledge_base: KnowledgeBaseService | None = None + + def request(self, request: BaseRequest): + resp = Transport.execute(self._config, request) + return resp + + @staticmethod + def builder() -> ClientBuilder: + return ClientBuilder() + + +class ClientBuilder: + def __init__(self) -> None: + self._config = Config() + + def domain(self, domain: str) -> ClientBuilder: + self._config.domain = domain + return self + + def build(self) -> Client: + client: Client = Client() + client._config = self._config + + # 初始化日志 + self._init_logger() + + # 初始化 服务 + client.chat = ChatService(self._config) + client.completion = CompletionService(self._config) + client.dify = DifyService(self._config) + client.workflow = WorkflowService(self._config) + client.knowledge_base = KnowledgeBaseService(self._config) + return client + + def _init_logger(self): + logger.setLevel(int(self._config.log_level.value)) diff --git a/sdks/python-client/dify_oapi/core/__init__.py b/sdks/python-client/dify_oapi/core/__init__.py new file mode 100755 index 0000000000..e69de29bb2 diff --git a/sdks/python-client/dify_oapi/core/const.py b/sdks/python-client/dify_oapi/core/const.py new file mode 100755 index 0000000000..7eb8c4a051 --- /dev/null +++ b/sdks/python-client/dify_oapi/core/const.py @@ -0,0 +1,12 @@ +# # Info +# VERSION = "1.2.6" + +# Header +USER_AGENT = "User-Agent" +AUTHORIZATION = "Authorization" +CONTENT_TYPE = "Content-Type" + +# Content-Type +APPLICATION_JSON = "application/json" + +UTF_8 = "UTF-8" diff --git a/sdks/python-client/dify_oapi/core/enum.py b/sdks/python-client/dify_oapi/core/enum.py new file mode 100755 index 0000000000..94a6a48e89 --- /dev/null +++ b/sdks/python-client/dify_oapi/core/enum.py @@ -0,0 +1,21 @@ +from enum import Enum, auto + + +class HttpMethod(Enum): + GET = auto() + HEAD = auto() + POST = auto() + PUT = auto() + PATCH = auto() + DELETE = auto() + CONNECT = auto() + OPTIONS = auto() + TRACE = auto() + + +class LogLevel(Enum): + DEBUG = 10 + INFO = 20 + WARNING = 30 + ERROR = 40 + CRITICAL = 50 diff --git a/sdks/python-client/dify_oapi/core/http/__init__.py b/sdks/python-client/dify_oapi/core/http/__init__.py new file mode 100755 index 0000000000..e69de29bb2 diff --git a/sdks/python-client/dify_oapi/core/http/transport.py b/sdks/python-client/dify_oapi/core/http/transport.py new file mode 100755 index 0000000000..2fc7204e84 --- /dev/null +++ b/sdks/python-client/dify_oapi/core/http/transport.py @@ -0,0 +1,288 @@ +import json +from collections.abc import AsyncGenerator, Coroutine, Generator +from typing import Literal, overload + +import httpx + +from dify_oapi.core.const import APPLICATION_JSON, AUTHORIZATION, UTF_8 +from dify_oapi.core.json import JSON +from dify_oapi.core.log import logger +from dify_oapi.core.model.base_request import BaseRequest +from dify_oapi.core.model.base_response import BaseResponse +from dify_oapi.core.model.config import Config +from dify_oapi.core.model.raw_response import RawResponse +from dify_oapi.core.model.request_option import RequestOption +from dify_oapi.core.type import T + + +class Transport: + @staticmethod + @overload + def execute( + conf: Config, + req: BaseRequest, + *, + stream: Literal[True], + option: RequestOption | None, + ) -> Generator[bytes, None, None]: ... + + @staticmethod + @overload + def execute(conf: Config, req: BaseRequest) -> BaseResponse: ... + + @staticmethod + @overload + def execute( + conf: Config, req: BaseRequest, *, option: RequestOption | None + ) -> BaseResponse: ... + + @staticmethod + @overload + def execute( + conf: Config, + req: BaseRequest, + *, + unmarshal_as: type[T], + option: RequestOption | None, + ) -> T: ... + + @staticmethod + def execute( + conf: Config, + req: BaseRequest, + *, + stream: bool = False, + unmarshal_as: type[T] | None = None, + option: RequestOption | None = None, + ): + if unmarshal_as is None: + unmarshal_as = BaseResponse + if option is None: + option = RequestOption() + # 拼接url + url: str = _build_url(conf.domain, req.uri, req.paths) + # 组装header + headers: dict[str, str] = _build_header(req, option) + json_, files, data = None, None, None + if req.files: + # multipart/form-data + files = req.files + if req.body is not None: + data = json.loads(JSON.marshal(req.body)) + elif req.body is not None: + # application/json + json_ = json.loads(JSON.marshal(req.body)) + + if stream: + + def _stream_generator() -> Generator[bytes, None, None]: + with ( + httpx.Client() as _client, + _client.stream( + str(req.http_method.name), + url, + headers=headers, + params=req.queries, + json=json_, + data=data, + files=files, + timeout=conf.timeout, + ) as async_response, + ): + logger.debug( + f"{str(req.http_method.name)} {url} {async_response.status_code}, " + f"headers: {JSON.marshal(headers)}, " + f"params: {JSON.marshal(req.queries)}, " + f"stream response" + ) + yield from async_response.iter_bytes() + + return _stream_generator() + with httpx.Client() as client: + response = client.request( + str(req.http_method.name), + url, + headers=headers, + params=req.queries, + json=json_, + data=data, + files=files, + timeout=conf.timeout, + ) + logger.debug( + f"{str(req.http_method.name)} {url} {response.status_code}, " + f"headers: {JSON.marshal(headers)}, " + f"params: {JSON.marshal(req.queries)}, " + f"body: {str(data, UTF_8) if isinstance(data, bytes) else data}" + ) + + raw_resp = RawResponse() + raw_resp.status_code = response.status_code + raw_resp.headers = dict(response.headers) + raw_resp.content = response.content + return _unmarshaller(raw_resp, unmarshal_as) + + +class ATransport: + @staticmethod + @overload + def aexecute( + conf: Config, + req: BaseRequest, + *, + stream: Literal[True], + option: RequestOption | None, + ) -> Coroutine[None, None, AsyncGenerator[bytes, None]]: ... + + @staticmethod + @overload + def aexecute( + conf: Config, req: BaseRequest + ) -> Coroutine[None, None, BaseResponse]: ... + + @staticmethod + @overload + def aexecute( + conf: Config, req: BaseRequest, *, option: RequestOption | None + ) -> Coroutine[None, None, BaseResponse]: ... + + @staticmethod + @overload + def aexecute( + conf: Config, + req: BaseRequest, + *, + unmarshal_as: type[T], + option: RequestOption | None, + ) -> Coroutine[None, None, T]: ... + + @staticmethod + async def aexecute( + conf: Config, + req: BaseRequest, + *, + stream: bool = False, + unmarshal_as: type[T] | None = None, + option: RequestOption | None = None, + ): + if option is None: + option = RequestOption() + + # 拼接url + url: str = _build_url(conf.domain, req.uri, req.paths) + + # 组装header + headers: dict[str, str] = _build_header(req, option) + + json_, files, data = None, None, None + if req.files: + # multipart/form-data + files = req.files + if req.body is not None: + data = json.loads(JSON.marshal(req.body)) + elif req.body is not None: + # application/json + json_ = json.loads(JSON.marshal(req.body)) + + if stream: + + async def _async_stream_generator(): + async with ( + httpx.AsyncClient() as _client, + _client.stream( + str(req.http_method.name), + url, + headers=req.headers, + params=req.queries, + json=json_, + data=data, + files=files, + timeout=conf.timeout, + ) as async_response, + ): + logger.debug( + f"{str(req.http_method.name)} {url} {async_response.status_code}, " + f"headers: {JSON.marshal(headers)}, " + f"params: {JSON.marshal(req.queries)}, " + f"stream response" + ) + async for chunk in async_response.aiter_bytes(): + yield chunk + + return _async_stream_generator() + async with httpx.AsyncClient() as client: + response = await client.request( + str(req.http_method.name), + url, + headers=req.headers, + params=req.queries, + json=json_, + data=data, + files=files, + timeout=conf.timeout, + ) + + logger.debug( + f"{str(req.http_method.name)} {url} {response.status_code}" + f"{f', headers: {JSON.marshal(headers)}' if headers else ''}" + f"{f', params: {JSON.marshal(req.queries)}' if req.queries else ''}" + f"{f', body: {JSON.marshal(_merge_dicts(json_, files, data))}' if json_ or files or data else ''}" + ) + + raw_resp = RawResponse() + raw_resp.status_code = response.status_code + raw_resp.headers = dict(response.headers) + raw_resp.content = response.content + + return _unmarshaller(raw_resp, unmarshal_as) + + +def _build_url(domain: str, uri: str, paths: dict[str, str]) -> str: + if paths is None: + paths = {} + for key in paths: + uri = uri.replace(":" + key, paths[key]) + if domain.endswith("/") and uri.startswith("/"): + domain = domain[:-1] + return domain + uri + + +def _build_header(request: BaseRequest, option: RequestOption) -> dict[str, str]: + headers = request.headers + # 附加header + if option.headers is not None: + for key in option.headers: + headers[key] = option.headers[key] + if option.api_key is not None: + headers[AUTHORIZATION] = f"Bearer {option.api_key}" + return headers + + +def _merge_dicts(*dicts): + res = {} + for d in dicts: + if d is not None: + res.update(d) + return res + + +def _unmarshaller(raw_resp: RawResponse, unmarshal_as: type[T]) -> T: + if not (200 <= raw_resp.status_code < 300): + resp = unmarshal_as( + raw=raw_resp, code=raw_resp.status_code, msg=raw_resp.content.decode() + ) + return resp + resp = unmarshal_as() + if raw_resp.content_type is not None and raw_resp.content_type.startswith( + APPLICATION_JSON + ): + content = str(raw_resp.content, UTF_8) + if content != "": + try: + resp = JSON.unmarshal(content, unmarshal_as) + except Exception as e: + logger.error(f"Failed to unmarshal to {unmarshal_as} from {content}") + raise e + resp.raw = raw_resp + resp.code = 0 + return resp diff --git a/sdks/python-client/dify_oapi/core/json.py b/sdks/python-client/dify_oapi/core/json.py new file mode 100755 index 0000000000..faa0498fec --- /dev/null +++ b/sdks/python-client/dify_oapi/core/json.py @@ -0,0 +1,50 @@ +import copy +import datetime +import io +from json import JSONEncoder, dumps, loads +from typing import Any + +from .const import UTF_8 +from .type import T + + +class JSON: + @staticmethod + def marshal(obj: Any, indent=None) -> str | None: + if obj is None: + return None + return dumps(obj, cls=Encoder, indent=indent, ensure_ascii=False) + + @staticmethod + def unmarshal(json_str: str, clazz: type[T]) -> T: + dict_obj = loads(json_str) + return clazz(**dict_obj) + + +class Encoder(JSONEncoder): + def default(self, o: Any) -> Any: + if isinstance(o, io.BufferedReader): + return o.__str__() + if hasattr(o, "__dict__"): + return filter_null(copy.deepcopy(vars(o))) + if isinstance(o, datetime.datetime): + return o.strftime("%Y-%m-%d %H:%M:%S") + if isinstance(o, bytes): + return str(o, encoding=UTF_8) + if isinstance(o, int): + return int(o) + if isinstance(o, float): + return float(o) + if isinstance(o, set): + return list(o) + + +def filter_null(d: dict) -> dict: + if isinstance(d, dict): + for k, v in list(d.items()): + if isinstance(v, dict): + filter_null(v) + elif v is None: + del d[k] + + return d diff --git a/sdks/python-client/dify_oapi/core/log.py b/sdks/python-client/dify_oapi/core/log.py new file mode 100755 index 0000000000..6439b22af1 --- /dev/null +++ b/sdks/python-client/dify_oapi/core/log.py @@ -0,0 +1,10 @@ +import logging +import sys + +logger = logging.getLogger("Dify") +handler = logging.StreamHandler(sys.stdout) +handler.setFormatter( + logging.Formatter("[Dify] [%(asctime)s] [%(levelname)s] %(message)s") +) +logger.addHandler(handler) +logger.setLevel(logging.WARNING) diff --git a/sdks/python-client/dify_oapi/core/model/__init__.py b/sdks/python-client/dify_oapi/core/model/__init__.py new file mode 100755 index 0000000000..e69de29bb2 diff --git a/sdks/python-client/dify_oapi/core/model/base_request.py b/sdks/python-client/dify_oapi/core/model/base_request.py new file mode 100755 index 0000000000..e4cde452b0 --- /dev/null +++ b/sdks/python-client/dify_oapi/core/model/base_request.py @@ -0,0 +1,22 @@ +from typing import Any + +from dify_oapi.core.enum import HttpMethod + + +class BaseRequest: + def __init__(self) -> None: + self.http_method: HttpMethod | None = None + self.uri: str | None = None + self.body: dict | None = None + self.paths: dict[str, str] = {} + self.queries: list[tuple[str, str]] = [] + self.headers: dict[str, str] = {} + self.body: dict = {} + self.files: dict | None = None + + def add_query(self, k: str, v: Any) -> None: + if isinstance(v, list | tuple): + for i in v: + self.queries.append((k, str(i))) + else: + self.queries.append((k, str(v))) diff --git a/sdks/python-client/dify_oapi/core/model/base_response.py b/sdks/python-client/dify_oapi/core/model/base_response.py new file mode 100755 index 0000000000..2d3b7fb367 --- /dev/null +++ b/sdks/python-client/dify_oapi/core/model/base_response.py @@ -0,0 +1,14 @@ +from pydantic import BaseModel, Field, ConfigDict + +from .raw_response import RawResponse + + +class BaseResponse(BaseModel): + model_config = ConfigDict(arbitrary_types_allowed=True) + raw: RawResponse | None = None + code: int | None = Field(default=None, exclude=True) + msg: str | None = Field(default=None, exclude=True) + + @property + def success(self): + return self.code is not None and self.code == 0 diff --git a/sdks/python-client/dify_oapi/core/model/config.py b/sdks/python-client/dify_oapi/core/model/config.py new file mode 100755 index 0000000000..b2fdbb7503 --- /dev/null +++ b/sdks/python-client/dify_oapi/core/model/config.py @@ -0,0 +1,8 @@ +from dify_oapi.core.enum import LogLevel + + +class Config: + def __init__(self): + self.domain: str | None = None + self.timeout: float | None = None # 客户端超时时间, 单位秒, 默认永不超时 + self.log_level: LogLevel = LogLevel.WARNING # 日志级别, 默认为 WARNING diff --git a/sdks/python-client/dify_oapi/core/model/raw_request.py b/sdks/python-client/dify_oapi/core/model/raw_request.py new file mode 100755 index 0000000000..b6798732c6 --- /dev/null +++ b/sdks/python-client/dify_oapi/core/model/raw_request.py @@ -0,0 +1,5 @@ +class RawRequest: + def __init__(self): + self.uri: str | None = None + self.headers: dict[str, str] = {} + self.body: bytes | None = None diff --git a/sdks/python-client/dify_oapi/core/model/raw_response.py b/sdks/python-client/dify_oapi/core/model/raw_response.py new file mode 100755 index 0000000000..02bf6bb980 --- /dev/null +++ b/sdks/python-client/dify_oapi/core/model/raw_response.py @@ -0,0 +1,18 @@ +from dify_oapi.core.const import CONTENT_TYPE + + +class RawResponse: + def __init__(self): + self.status_code: int | None = None + self.headers: dict[str, str] = {} + self.content: bytes | None = None + + def set_content_type(self, content_type: str) -> None: + self.headers[CONTENT_TYPE] = content_type + + @property + def content_type(self) -> str | None: + content_type = self.headers.get(CONTENT_TYPE) or self.headers.get( + CONTENT_TYPE.lower() + ) + return content_type diff --git a/sdks/python-client/dify_oapi/core/model/request_option.py b/sdks/python-client/dify_oapi/core/model/request_option.py new file mode 100755 index 0000000000..5ec799fc11 --- /dev/null +++ b/sdks/python-client/dify_oapi/core/model/request_option.py @@ -0,0 +1,27 @@ +from __future__ import annotations + + +class RequestOption: + def __init__(self): + self.api_key: str | None = None + self.headers: dict[str, str] = {} + + @staticmethod + def builder() -> RequestOptionBuilder: + return RequestOptionBuilder() + + +class RequestOptionBuilder: + def __init__(self) -> None: + self._request_option: RequestOption = RequestOption() + + def api_key(self, api_key: str) -> RequestOptionBuilder: + self._request_option.api_key = api_key + return self + + def headers(self, headers: dict[str, str]) -> RequestOptionBuilder: + self._request_option.headers = headers + return self + + def build(self) -> RequestOption: + return self._request_option diff --git a/sdks/python-client/dify_oapi/core/type.py b/sdks/python-client/dify_oapi/core/type.py new file mode 100755 index 0000000000..9a78385193 --- /dev/null +++ b/sdks/python-client/dify_oapi/core/type.py @@ -0,0 +1,5 @@ +from typing import TypeVar + +from dify_oapi.core.model.base_response import BaseResponse + +T = TypeVar("T", bound=BaseResponse) diff --git a/sdks/python-client/dify_oapi/core/utils/__init__.py b/sdks/python-client/dify_oapi/core/utils/__init__.py new file mode 100755 index 0000000000..e69de29bb2 diff --git a/sdks/python-client/dify_oapi/core/utils/strings.py b/sdks/python-client/dify_oapi/core/utils/strings.py new file mode 100755 index 0000000000..74e8eb432d --- /dev/null +++ b/sdks/python-client/dify_oapi/core/utils/strings.py @@ -0,0 +1,8 @@ +class Strings: + @staticmethod + def is_not_empty(s: str | None) -> bool: + return not Strings.is_empty(s) + + @staticmethod + def is_empty(s: str | None) -> bool: + return s is None or len(s) == 0 diff --git a/sdks/python-client/setup.py b/sdks/python-client/setup.py index 7340fffb4c..628ebc51ff 100644 --- a/sdks/python-client/setup.py +++ b/sdks/python-client/setup.py @@ -4,8 +4,8 @@ with open("README.md", "r", encoding="utf-8") as fh: long_description = fh.read() setup( - name="dify-client", - version="0.1.12", + name="dify-oapi", + version="0.0.1", author="Dify", author_email="hello@dify.ai", description="A package for interacting with the Dify Service-API", @@ -13,14 +13,14 @@ setup( long_description_content_type="text/markdown", url="https://github.com/langgenius/dify", license="MIT", - packages=["dify_client"], + packages=["dify_oapi"], classifiers=[ "Programming Language :: Python :: 3", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", ], python_requires=">=3.6", - install_requires=["requests"], + install_requires=["pydantic", "httpx"], keywords="dify nlp ai language-processing", include_package_data=True, ) diff --git a/sdks/python-client/tests/.gitignore b/sdks/python-client/tests/.gitignore new file mode 100644 index 0000000000..1273ec8ee8 --- /dev/null +++ b/sdks/python-client/tests/.gitignore @@ -0,0 +1 @@ +pytest.ini \ No newline at end of file diff --git a/sdks/python-client/tests/pytest.ini.example b/sdks/python-client/tests/pytest.ini.example new file mode 100644 index 0000000000..7a159a4a54 --- /dev/null +++ b/sdks/python-client/tests/pytest.ini.example @@ -0,0 +1,9 @@ +# pytest.ini +[pytest] +env = + # DOMAIN= + APP_KEY= + CHAT_KEY= + COMPLETION_KEY= + WORKFLOW_KEY= + DATASET_KEY= diff --git a/sdks/python-client/tests/test_chat.py b/sdks/python-client/tests/test_chat.py new file mode 100644 index 0000000000..1ce97b4278 --- /dev/null +++ b/sdks/python-client/tests/test_chat.py @@ -0,0 +1,162 @@ +import os +import time +import unittest +from io import BytesIO +from pathlib import Path +from types import GeneratorType + +from dify_oapi.api.chat.v1.model.audio_to_text_request import AudioToTextRequest +from dify_oapi.api.chat.v1.model.audio_to_text_request_body import AudioToTextRequestBody +from dify_oapi.api.chat.v1.model.chat_request import ChatRequest +from dify_oapi.api.chat.v1.model.chat_request_body import ChatRequestBody +from dify_oapi.api.chat.v1.model.chat_request_file import ChatRequestFile +from dify_oapi.api.chat.v1.model.delete_conversation_request import DeleteConversationRequest +from dify_oapi.api.chat.v1.model.delete_conversation_request_body import DeleteConversationRequestBody +from dify_oapi.api.chat.v1.model.get_conversation_list_request import GetConversationListRequest +from dify_oapi.api.chat.v1.model.message_history_request import MessageHistoryRequest +from dify_oapi.api.chat.v1.model.message_suggested_request import MessageSuggestedRequest +from dify_oapi.api.chat.v1.model.rename_conversation_request import RenameConversationRequest +from dify_oapi.api.chat.v1.model.rename_conversation_request_body import RenameConversationRequestBody +from dify_oapi.api.chat.v1.model.stop_chat_request import StopChatRequest +from dify_oapi.api.chat.v1.model.stop_chat_request_body import StopChatRequestBody +from dify_oapi.client import Client +from dify_oapi.core.model.request_option import RequestOption + + +class TestChatClient(unittest.TestCase): + def setUp(self): + chat_key = os.environ.get("CHAT_KEY") + self.assertIsNotNone(chat_key, "CHAT_KEY must be set") + self.client = Client.builder().domain(os.environ.get("DOMAIN", "https://api.dify.ai")).build() + self.req_option = RequestOption.builder().api_key(chat_key).build() + + self._audio_file_path = Path(__file__) / "audio.mp3" + self._conversation_id: str | None = None + self._message_id: str | None = None + self._task_id: str | None = None + + @property + def audio_file_path(self) -> Path: + if not self._audio_file_path.exists(): + self.skipTest("Audio file not found.") + return self._audio_file_path + + @property + def conversation_id(self) -> str: + if self._conversation_id is None: + self.skipTest("conversation_id is not set") + return self._conversation_id + + @property + def message_id(self) -> str: + if self._message_id is None: + self.skipTest("message_id is not set") + return self._message_id + + @property + def task_id(self) -> str: + if self._task_id is None: + self.skipTest("task_id is not set") + return self._task_id + + def test_main(self): + self._test_001_block_chat() + time.sleep(0.5) + self._test_002_stream_chat() + time.sleep(0.5) + self._test_003_stop_chat() + time.sleep(0.5) + self._test_004_suggest_message() + time.sleep(0.5) + self._test_005_message_history() + time.sleep(0.5) + self._test_006_list_conversations() + time.sleep(0.5) + self._test_007_rename_conversation() + time.sleep(0.5) + self._test_008_delete_conversation() + time.sleep(0.5) + self._test_009_audio_to_text() + time.sleep(0.5) + + def _test_001_block_chat(self): + req_file = ChatRequestFile.builder() \ + .type("image") \ + .transfer_method("remote_url") \ + .url("https://cloud.dify.ai/logo/logo-site.png") \ + .build() + req_body = ChatRequestBody.builder() \ + .inputs({}) \ + .query("What are the specs of the iPhone 13 Pro Max?") \ + .response_mode("blocking") \ + .user("abc-123") \ + .files([req_file]) \ + .build() + req = ChatRequest.builder().request_body(req_body).build() + response = self.client.chat.v1.chat.chat(req, self.req_option, False) + self.assertTrue(response.success, response.msg) + self._conversation_id = response.conversation_id + self._message_id = response.message_id + + def _test_002_stream_chat(self): + req_file = ChatRequestFile.builder() \ + .type("image") \ + .transfer_method("remote_url") \ + .url("https://cloud.dify.ai/logo/logo-site.png") \ + .build() + req_body = ChatRequestBody.builder() \ + .inputs({}) \ + .query("What are the specs of the iPhone 13 Pro Max?") \ + .response_mode("streaming") \ + .user("abc-123") \ + .files([req_file]) \ + .build() + req = ChatRequest.builder().request_body(req_body).build() + response = self.client.chat.v1.chat.chat(req, self.req_option, True) + if not isinstance(response, GeneratorType): + self.fail(response.msg) + + def _test_003_stop_chat(self): + req_body = StopChatRequestBody.builder().user("abc-123").build() + req = StopChatRequest.builder().request_body(req_body).task_id(self.task_id).build() + response = self.client.chat.v1.chat.stop(req, self.req_option) + self.assertTrue(response.success, response.msg) + + def _test_004_suggest_message(self): + req = MessageSuggestedRequest.builder().user("abc-123").message_id(self.message_id).build() + response = self.client.chat.v1.message.suggested(req, self.req_option) + self.assertTrue(response.success, response.msg) + + def _test_005_message_history(self): + req = MessageHistoryRequest.builder().user("abc-123").conversation_id(self.conversation_id).build() + response = self.client.chat.v1.message.history(req, self.req_option) + self.assertTrue(response.success, response.msg) + + def _test_006_list_conversations(self): + req = GetConversationListRequest.builder().user("abc-123").build() + response = self.client.chat.v1.conversation.list(req, self.req_option) + self.assertTrue(response.success, response.msg) + + def _test_007_rename_conversation(self): + req_body = RenameConversationRequestBody.builder().user("abc-123").name("newname").builder() + req = RenameConversationRequest.builder().request_body(req_body).conversation_id(self.conversation_id).build() + response = self.client.chat.v1.conversation.rename(req, self.req_option) + self.assertTrue(response.success, response.msg) + + def _test_008_delete_conversation(self): + req_body = DeleteConversationRequestBody.builder().user("abc-123").build() + req = DeleteConversationRequest.builder().conversation_id(self.conversation_id).request_body(req_body).build() + response = self.client.chat.v1.conversation.delete(req, self.req_option) + self.assertTrue(response.success, response.msg) + + def _test_009_audio_to_text(self): + req_body = AudioToTextRequestBody.builder().user("abc-123").build() + with self.audio_file_path.open(mode="rb") as f: + data = f.read() + req = AudioToTextRequest.builder().request_body(req_body).file(BytesIO(data), self.audio_file_path.name).build() + response = self.client.chat.v1.audio.to_text(req, self.req_option) + self.assertTrue(response.success, response.msg) + + +if __name__ == "__main__": + unittest.main() diff --git a/sdks/python-client/tests/test_client.py b/sdks/python-client/tests/test_client.py deleted file mode 100644 index 0e8913c5f0..0000000000 --- a/sdks/python-client/tests/test_client.py +++ /dev/null @@ -1,274 +0,0 @@ -import os -import time -import unittest - -from dify_client.client import ( - ChatClient, - CompletionClient, - DifyClient, - KnowledgeBaseClient, -) - -API_KEY = os.environ.get("API_KEY") -APP_ID = os.environ.get("APP_ID") -API_BASE_URL = os.environ.get("API_BASE_URL", "https://api.dify.ai/v1") -FILE_PATH_BASE = os.path.dirname(__file__) - - -class TestKnowledgeBaseClient(unittest.TestCase): - def setUp(self): - self.knowledge_base_client = KnowledgeBaseClient(API_KEY, base_url=API_BASE_URL) - self.README_FILE_PATH = os.path.abspath( - os.path.join(FILE_PATH_BASE, "../README.md") - ) - self.dataset_id = None - self.document_id = None - self.segment_id = None - self.batch_id = None - - def _get_dataset_kb_client(self): - self.assertIsNotNone(self.dataset_id) - return KnowledgeBaseClient( - API_KEY, base_url=API_BASE_URL, dataset_id=self.dataset_id - ) - - def test_001_create_dataset(self): - response = self.knowledge_base_client.create_dataset(name="test_dataset") - data = response.json() - self.assertIn("id", data) - self.dataset_id = data["id"] - self.assertEqual("test_dataset", data["name"]) - - # the following tests require to be executed in order because they use - # the dataset/document/segment ids from the previous test - self._test_002_list_datasets() - self._test_003_create_document_by_text() - time.sleep(1) - self._test_004_update_document_by_text() - # self._test_005_batch_indexing_status() - time.sleep(1) - self._test_006_update_document_by_file() - time.sleep(1) - self._test_007_list_documents() - self._test_008_delete_document() - self._test_009_create_document_by_file() - time.sleep(1) - self._test_010_add_segments() - self._test_011_query_segments() - self._test_012_update_document_segment() - self._test_013_delete_document_segment() - self._test_014_delete_dataset() - - def _test_002_list_datasets(self): - response = self.knowledge_base_client.list_datasets() - data = response.json() - self.assertIn("data", data) - self.assertIn("total", data) - - def _test_003_create_document_by_text(self): - client = self._get_dataset_kb_client() - response = client.create_document_by_text("test_document", "test_text") - data = response.json() - self.assertIn("document", data) - self.document_id = data["document"]["id"] - self.batch_id = data["batch"] - - def _test_004_update_document_by_text(self): - client = self._get_dataset_kb_client() - self.assertIsNotNone(self.document_id) - response = client.update_document_by_text( - self.document_id, "test_document_updated", "test_text_updated" - ) - data = response.json() - self.assertIn("document", data) - self.assertIn("batch", data) - self.batch_id = data["batch"] - - def _test_005_batch_indexing_status(self): - client = self._get_dataset_kb_client() - response = client.batch_indexing_status(self.batch_id) - data = response.json() - self.assertEqual(response.status_code, 200) - - def _test_006_update_document_by_file(self): - client = self._get_dataset_kb_client() - self.assertIsNotNone(self.document_id) - response = client.update_document_by_file( - self.document_id, self.README_FILE_PATH - ) - data = response.json() - self.assertIn("document", data) - self.assertIn("batch", data) - self.batch_id = data["batch"] - - def _test_007_list_documents(self): - client = self._get_dataset_kb_client() - response = client.list_documents() - data = response.json() - self.assertIn("data", data) - - def _test_008_delete_document(self): - client = self._get_dataset_kb_client() - self.assertIsNotNone(self.document_id) - response = client.delete_document(self.document_id) - data = response.json() - self.assertIn("result", data) - self.assertEqual("success", data["result"]) - - def _test_009_create_document_by_file(self): - client = self._get_dataset_kb_client() - response = client.create_document_by_file(self.README_FILE_PATH) - data = response.json() - self.assertIn("document", data) - self.document_id = data["document"]["id"] - self.batch_id = data["batch"] - - def _test_010_add_segments(self): - client = self._get_dataset_kb_client() - response = client.add_segments( - self.document_id, [{"content": "test text segment 1"}] - ) - data = response.json() - self.assertIn("data", data) - self.assertGreater(len(data["data"]), 0) - segment = data["data"][0] - self.segment_id = segment["id"] - - def _test_011_query_segments(self): - client = self._get_dataset_kb_client() - response = client.query_segments(self.document_id) - data = response.json() - self.assertIn("data", data) - self.assertGreater(len(data["data"]), 0) - - def _test_012_update_document_segment(self): - client = self._get_dataset_kb_client() - self.assertIsNotNone(self.segment_id) - response = client.update_document_segment( - self.document_id, - self.segment_id, - {"content": "test text segment 1 updated"}, - ) - data = response.json() - self.assertIn("data", data) - self.assertGreater(len(data["data"]), 0) - segment = data["data"] - self.assertEqual("test text segment 1 updated", segment["content"]) - - def _test_013_delete_document_segment(self): - client = self._get_dataset_kb_client() - self.assertIsNotNone(self.segment_id) - response = client.delete_document_segment(self.document_id, self.segment_id) - data = response.json() - self.assertIn("result", data) - self.assertEqual("success", data["result"]) - - def _test_014_delete_dataset(self): - client = self._get_dataset_kb_client() - response = client.delete_dataset() - self.assertEqual(204, response.status_code) - - -class TestChatClient(unittest.TestCase): - def setUp(self): - self.chat_client = ChatClient(API_KEY) - - def test_create_chat_message(self): - response = self.chat_client.create_chat_message( - {}, "Hello, World!", "test_user" - ) - self.assertIn("answer", response.text) - - def test_create_chat_message_with_vision_model_by_remote_url(self): - files = [ - {"type": "image", "transfer_method": "remote_url", "url": "your_image_url"} - ] - response = self.chat_client.create_chat_message( - {}, "Describe the picture.", "test_user", files=files - ) - self.assertIn("answer", response.text) - - def test_create_chat_message_with_vision_model_by_local_file(self): - files = [ - { - "type": "image", - "transfer_method": "local_file", - "upload_file_id": "your_file_id", - } - ] - response = self.chat_client.create_chat_message( - {}, "Describe the picture.", "test_user", files=files - ) - self.assertIn("answer", response.text) - - def test_get_conversation_messages(self): - response = self.chat_client.get_conversation_messages( - "test_user", "your_conversation_id" - ) - self.assertIn("answer", response.text) - - def test_get_conversations(self): - response = self.chat_client.get_conversations("test_user") - self.assertIn("data", response.text) - - -class TestCompletionClient(unittest.TestCase): - def setUp(self): - self.completion_client = CompletionClient(API_KEY) - - def test_create_completion_message(self): - response = self.completion_client.create_completion_message( - {"query": "What's the weather like today?"}, "blocking", "test_user" - ) - self.assertIn("answer", response.text) - - def test_create_completion_message_with_vision_model_by_remote_url(self): - files = [ - {"type": "image", "transfer_method": "remote_url", "url": "your_image_url"} - ] - response = self.completion_client.create_completion_message( - {"query": "Describe the picture."}, "blocking", "test_user", files - ) - self.assertIn("answer", response.text) - - def test_create_completion_message_with_vision_model_by_local_file(self): - files = [ - { - "type": "image", - "transfer_method": "local_file", - "upload_file_id": "your_file_id", - } - ] - response = self.completion_client.create_completion_message( - {"query": "Describe the picture."}, "blocking", "test_user", files - ) - self.assertIn("answer", response.text) - - -class TestDifyClient(unittest.TestCase): - def setUp(self): - self.dify_client = DifyClient(API_KEY) - - def test_message_feedback(self): - response = self.dify_client.message_feedback( - "your_message_id", "like", "test_user" - ) - self.assertIn("success", response.text) - - def test_get_application_parameters(self): - response = self.dify_client.get_application_parameters("test_user") - self.assertIn("user_input_form", response.text) - - def test_file_upload(self): - file_path = "your_image_file_path" - file_name = "panda.jpeg" - mime_type = "image/jpeg" - - with open(file_path, "rb") as file: - files = {"file": (file_name, file, mime_type)} - response = self.dify_client.file_upload("test_user", files) - self.assertIn("name", response.text) - - -if __name__ == "__main__": - unittest.main() diff --git a/sdks/python-client/tests/test_completion.py b/sdks/python-client/tests/test_completion.py new file mode 100644 index 0000000000..ecdc4f13a3 --- /dev/null +++ b/sdks/python-client/tests/test_completion.py @@ -0,0 +1,94 @@ +import os +import time +import unittest +from types import GeneratorType + +from dify_oapi.api.completion.v1.model.stop_completion_request import StopCompletionRequest +from dify_oapi.api.completion.v1.model.stop_completion_request_body import StopCompletionRequestBody +from dify_oapi.client import Client +from dify_oapi.core.model.request_option import RequestOption + +from dify_oapi.api.completion.v1.model.completion_request import CompletionRequest +from dify_oapi.api.completion.v1.model.completion_request_body import CompletionRequestBody +from dify_oapi.api.completion.v1.model.completion_request_file import CompletionRequestFile +from dify_oapi.api.completion.v1.model.completion_request_body_input import CompletionRequestBodyInput + + +class TestCompletionClient(unittest.TestCase): + def setUp(self): + completion_key = os.environ.get("COMPLETION_KEY") + self.assertIsNotNone(completion_key, "COMPLETION_KEY must be set") + self.client = Client.builder().domain(os.environ.get("DOMAIN", "https://api.dify.ai")).build() + self.req_option = RequestOption.builder().api_key(completion_key).build() + + self._message_id: str | None = None + self._task_id: str | None = None + + @property + def message_id(self) -> str: + if self._message_id is None: + self.skipTest("message_id is not set") + return self._message_id + + @property + def task_id(self) -> str: + if self._task_id is None: + self.skipTest("task_id is not set") + return self._task_id + + def test_main(self): + self._test_001_block_chat() + time.sleep(0.5) + self._test_002_stream_chat() + time.sleep(0.5) + self._test_003_stop_chat() + + def _test_001_block_chat(self): + req_file = CompletionRequestFile.builder() \ + .type("image") \ + .transfer_method("remote_url") \ + .url("https://cloud.dify.ai/logo/logo-site.png") \ + .build() + req_input = CompletionRequestBodyInput.builder() \ + .query("What are the specs of the iPhone 13 Pro Max?") \ + .build() + req_body = CompletionRequestBody.builder() \ + .inputs(req_input) \ + .response_mode("blocking") \ + .user("abc-123") \ + .files([req_file]) \ + .build() + req = CompletionRequest.builder().request_body(req_body).build() + response = self.client.completion.v1.completion.completion(req, self.req_option, False) + self.assertTrue(response.success, response.msg) + self._message_id = response.message_id + + def _test_002_stream_chat(self): + req_file = CompletionRequestFile.builder() \ + .type("image") \ + .transfer_method("remote_url") \ + .url("https://cloud.dify.ai/logo/logo-site.png") \ + .build() + req_input = CompletionRequestBodyInput.builder() \ + .query("What are the specs of the iPhone 13 Pro Max?") \ + .build() + req_body = CompletionRequestBody.builder() \ + .inputs(req_input) \ + .response_mode("streaming") \ + .user("abc-123") \ + .files([req_file]) \ + .build() + req = CompletionRequest.builder().request_body(req_body).build() + response = self.client.completion.v1.completion.completion(req, self.req_option, True) + if not isinstance(response, GeneratorType): + self.fail(response.msg) + + def _test_003_stop_chat(self): + req_body = StopCompletionRequestBody.builder().user("abc-123").build() + req = StopCompletionRequest.builder().request_body(req_body).task_id(self.task_id).build() + response = self.client.completion.v1.completion.stop(req, self.req_option) + self.assertTrue(response.success, response.msg) + + +if __name__ == "__main__": + unittest.main() diff --git a/sdks/python-client/tests/test_dify.py b/sdks/python-client/tests/test_dify.py new file mode 100644 index 0000000000..dd83825bf0 --- /dev/null +++ b/sdks/python-client/tests/test_dify.py @@ -0,0 +1,70 @@ +import os +import unittest +from io import BytesIO +from pathlib import Path + +from dify_oapi.api.dify.v1.model.get_parameter_request import GetParameterRequest +from dify_oapi.api.dify.v1.model.message_feedback_request import MessageFeedbackRequest +from dify_oapi.api.dify.v1.model.message_feedback_request_body import MessageFeedbackRequestBody +from dify_oapi.api.dify.v1.model.upload_file_request import UploadFileRequest +from dify_oapi.api.dify.v1.model.upload_file_body import UploadFileBody + +from dify_oapi.api.dify.v1.model.get_meta_request import GetMetaRequest +from dify_oapi.api.dify.v1.model.text_to_audio_request import TextToAudioRequest +from dify_oapi.api.dify.v1.model.text_to_audio_request_body import ( + TextToAudioRequestBody, +) +from dify_oapi.client import Client +from dify_oapi.core.model.request_option import RequestOption + + +class TestDifyClient(unittest.TestCase): + + def setUp(self): + app_key = os.environ.get("APP_KEY") + self.assertIsNotNone(app_key, "APP_KEY must be set") + self.client = Client.builder().domain(os.environ.get("DOMAIN", "https://api.dify.ai")).build() + self.req_option = RequestOption.builder().api_key(app_key).build() + + self.readme_file_path = Path(__file__).parents[1] / "README.md" + self._message_id: str | None = None + + @property + def message_id(self): + if self._message_id is None: + self.skipTest("Message id not set") + return self._message_id + + def test_upload_file(self): + req_body = UploadFileBody.builder().user("abc-123").build() + with self.readme_file_path.open("rb") as f: + data = f.read() + req = UploadFileRequest.builder().request_body(req_body).file(BytesIO(data), self.readme_file_path.name).build() + response = self.client.dify.v1.file.upload(req, self.req_option) + self.assertTrue(response.success, response.msg) + + def test_get_meta(self): + req = GetMetaRequest.builder().user("abc-123").build() + response = self.client.dify.v1.meta.get(req, self.req_option) + self.assertTrue(response.success, response.msg) + + def test_text_to_audio(self): + req_body = TextToAudioRequestBody.builder().user("abc-123").text("Hello Dify").build() + req = TextToAudioRequest.builder().request_body(req_body).build() + response = self.client.dify.v1.audio.from_text(req, self.req_option) + self.assertTrue(response.success, response.msg) + + def test_get_parameter(self): + req = GetParameterRequest.builder().user("abc-123").build() + response = self.client.dify.v1.parameter.get(req, self.req_option) + self.assertTrue(response.success, response.msg) + + def test_message_feedback(self): + req_body = MessageFeedbackRequestBody.builder().user("abc-123").rating("like").build() + req = MessageFeedbackRequest.builder().message_id(self.message_id).request_body(req_body).build() + response = self.client.dify.v1.message.feedback(req, self.req_option) + self.assertTrue(response.success, response.msg) + + +if __name__ == "__main__": + unittest.main() diff --git a/sdks/python-client/tests/test_knowledge.py b/sdks/python-client/tests/test_knowledge.py new file mode 100644 index 0000000000..18c92c8f38 --- /dev/null +++ b/sdks/python-client/tests/test_knowledge.py @@ -0,0 +1,226 @@ +import os +import time +import unittest +from pathlib import Path +from io import BytesIO + +from dify_oapi.api.knowledge_base.v1.model.create_dataset_request import CreateDatasetRequest +from dify_oapi.api.knowledge_base.v1.model.create_dataset_request_body import CreateDatasetRequestBody +from dify_oapi.api.knowledge_base.v1.model.list_dataset_request import ListDatasetRequest +from dify_oapi.api.knowledge_base.v1.model.delete_dataset_request import DeleteDatasetRequest +from dify_oapi.api.knowledge_base.v1.model.hit_test_request import HitTestRequest +from dify_oapi.api.knowledge_base.v1.model.hit_test_request_body import HitTestRequestBody +from dify_oapi.api.knowledge_base.v1.model.index_status_request import IndexStatusRequest +from dify_oapi.api.knowledge_base.v1.model.create_document_by_text_request import CreateDocumentByTextRequest +from dify_oapi.api.knowledge_base.v1.model.create_document_by_text_request_body import CreateDocumentByTextRequestBody +from dify_oapi.api.knowledge_base.v1.model.document_request_process_rule import DocumentRequestProcessRule +from dify_oapi.api.knowledge_base.v1.model.create_document_by_file_request import CreateDocumentByFileRequest +from dify_oapi.api.knowledge_base.v1.model.create_document_by_file_request_body import CreateDocumentByFileRequestBody +from dify_oapi.api.knowledge_base.v1.model.create_document_by_file_request_body_data import CreateDocumentByTextRequestBodyData +from dify_oapi.api.knowledge_base.v1.model.update_document_by_text_request import UpdateDocumentByTextRequest +from dify_oapi.api.knowledge_base.v1.model.update_document_by_text_request_body import UpdateDocumentByTextRequestBody +from dify_oapi.api.knowledge_base.v1.model.delete_document_request import DeleteDocumentRequest +from dify_oapi.api.knowledge_base.v1.model.list_document_request import ListDocumentRequest +from dify_oapi.api.knowledge_base.v1.model.list_segment_request import ListSegmentRequest +from dify_oapi.api.knowledge_base.v1.model.create_segment_request import CreateSegmentRequest +from dify_oapi.api.knowledge_base.v1.model.create_segment_request_body import CreateSegmentRequestBody +from dify_oapi.api.knowledge_base.v1.model.create_segment_request_body_segment import CreateSegmentRequestBodySegment +from dify_oapi.api.knowledge_base.v1.model.delete_segment_request import DeleteSegmentRequest +from dify_oapi.api.knowledge_base.v1.model.update_segment_request import UpdateSegmentRequest +from dify_oapi.api.knowledge_base.v1.model.update_segment_request_body import UpdateSegmentRequestBody +from dify_oapi.api.knowledge_base.v1.model.update_segment_request_body_segment import UpdateSegmentRequestBodySegment +from dify_oapi.client import Client +from dify_oapi.core.model.request_option import RequestOption + + +class TestKnowledgeBaseClient(unittest.TestCase): + def setUp(self): + dataset_key = os.environ.get("DATASET_KEY") + self.assertNotIn(dataset_key, [None, ""], "DATASET_KEY must be set") + self.client = Client.builder().domain(os.environ.get("DOMAIN", "https://api.dify.ai")).build() + self.req_option = RequestOption.builder().api_key(dataset_key).build() + + self.readme_file_path = Path(__file__).parents[1] / "README.md" + self._dataset_id: str | None = None + self._document_id: str | None = None + self._batch: str | None = None + self._segment_id: str | None = None + + @property + def dataset_id(self): + if self._dataset_id is None: + self.skipTest("Dataset key is not set") + return self._dataset_id + + @property + def document_id(self): + if self._document_id is None: + self.skipTest("Document key is not set") + return self._document_id + + @property + def batch(self): + if self._batch is None: + self.skipTest("Batch is not set") + return self._batch + + @property + def segment_id(self): + if self._segment_id is None: + self.skipTest("Segment key is not set") + return self._segment_id + + def tearDown(self): + if self._dataset_id is not None: + self._test_014_delete_dataset() + + def test_main(self): + self._test_001_create_dataset() + time.sleep(0.5) + self._test_002_list_dataset() + time.sleep(0.5) + self._test_003_create_document_by_text() + time.sleep(0.5) + self._test_004_create_document_by_file() + time.sleep(0.5) + self._test_005_update_document_by_text() + time.sleep(0.5) + self._test_006_list_document() + time.sleep(0.5) + self._test_007_create_segment() + time.sleep(0.5) + self._test_008_list_segment() + time.sleep(0.5) + self._test_009_update_segment() + # time.sleep(0.5) + # self._test_010_hit_status() + time.sleep(0.5) + self._test_011_index_status() + time.sleep(0.5) + self._test_012_delete_segment() + time.sleep(0.5) + self._test_013_delete_document() + time.sleep(0.5) + self._test_014_delete_dataset() + + def _test_001_create_dataset(self): + req_body = CreateDatasetRequestBody.builder().name("test").build() + req = CreateDatasetRequest.builder().request_body(req_body).build() + response = self.client.knowledge_base.v1.dataset.create(req, self.req_option) + self.assertTrue(response.success, response.msg) + self._dataset_id = response.id + + def _test_002_list_dataset(self): + req = ListDatasetRequest.builder().build() + response = self.client.knowledge_base.v1.dataset.list(req, self.req_option) + self.assertTrue(response.success, response.msg) + + def _test_003_create_document_by_text(self): + document_process_rule = DocumentRequestProcessRule.builder().mode("automatic").build() + req_body = CreateDocumentByTextRequestBody.builder() \ + .indexing_technique("economy") \ + .text("imtext") \ + .name("imname") \ + .process_rule(document_process_rule) \ + .build() + req = CreateDocumentByTextRequest.builder().dataset_id(self.dataset_id).request_body(req_body).build() + response = self.client.knowledge_base.v1.document.create_by_text(req, self.req_option) + self.assertTrue(response.success, response.msg) + self._document_id = response.document.id + self._batch = response.batch + + def _test_004_create_document_by_file(self): + document_process_rule = DocumentRequestProcessRule.builder().mode("automatic").build() + data = CreateDocumentByTextRequestBodyData.builder().process_rule(document_process_rule).build() + req_body = CreateDocumentByFileRequestBody.builder().data(data).build() + with self.readme_file_path.open(mode="rb") as f: + data = f.read() + req = CreateDocumentByFileRequest.builder() \ + .dataset_id(self.dataset_id) \ + .request_body(req_body).file(BytesIO(data), self.readme_file_path.name) \ + .build() + response = self.client.knowledge_base.v1.document.create_by_file(req, self.req_option) + self.assertTrue(response.success, response.msg) + self._batch = response.batch + self._document_id = response.document.id + + def _test_005_update_document_by_text(self): + req_body = UpdateDocumentByTextRequestBody.builder().text("imtext2").name("imname2").build() + req = UpdateDocumentByTextRequest.builder() \ + .request_body(req_body) \ + .dataset_id(self.dataset_id) \ + .document_id(self.document_id) \ + .build() + response = self.client.knowledge_base.v1.document.update_by_text(req, self.req_option) + self.assertTrue(response.success, response.msg) + + def _test_006_list_document(self): + req = ListDocumentRequest.builder().dataset_id(self.dataset_id).build() + response = self.client.knowledge_base.v1.document.list(req, self.req_option) + self.assertTrue(response.success, response.msg) + + def _test_007_create_segment(self): + segment = CreateSegmentRequestBodySegment.builder().content("im segment content").keywords(["content"]).build() + req_body = CreateSegmentRequestBody.builder().segments([segment]).build() + req = CreateSegmentRequest.builder() \ + .request_body(req_body) \ + .dataset_id(self.dataset_id) \ + .document_id(self.document_id) \ + .build() + response = self.client.knowledge_base.v1.segment.create(req, self.req_option) + self.assertTrue(response.success, response.msg) + self._segment_id = response.data[0].id + + def _test_008_list_segment(self): + req = ListSegmentRequest.builder().dataset_id(self.dataset_id).document_id(self.document_id).build() + response = self.client.knowledge_base.v1.segment.list(req, self.req_option) + self.assertTrue(response.success, response.msg) + if self._segment_id is None and len(response.data) > 0: + self._segment_id = response.data[0].id + + def _test_009_update_segment(self): + segment = UpdateSegmentRequestBodySegment.builder().content("im segment content2").build() + req_body = UpdateSegmentRequestBody.builder().segment(segment).build() + req = UpdateSegmentRequest.builder() \ + .request_body(req_body) \ + .dataset_id(self.dataset_id) \ + .document_id(self.document_id) \ + .segment_id(self.segment_id) \ + .build() + response = self.client.knowledge_base.v1.segment.update(req, self.req_option) + self.assertTrue(response.success, response.msg) + + def _test_010_hit_status(self): + req_body = HitTestRequestBody.builder().query("hello dify").build() + req = HitTestRequest.builder().dataset_id(self.dataset_id).request_body(req_body).build() + response = self.client.knowledge_base.v1.dataset.hit_test(req, self.req_option) + self.assertTrue(response.success, response.msg) + + def _test_011_index_status(self): + req = IndexStatusRequest.builder().dataset(self.dataset_id).batch(self.batch).build() + response = self.client.knowledge_base.v1.document.indexing_status(req, self.req_option) + self.assertTrue(response.success, response.msg) + + def _test_012_delete_segment(self): + req = DeleteSegmentRequest.builder() \ + .dataset_id(self.dataset_id) \ + .document_id(self.document_id) \ + .segment_id(self.segment_id) \ + .build() + response = self.client.knowledge_base.v1.segment.delete(req, self.req_option) + self.assertTrue(response.success, response.msg) + + def _test_013_delete_document(self): + req = DeleteDocumentRequest.builder().dataset_id(self.dataset_id).document_id(self.document_id).build() + response = self.client.knowledge_base.v1.document.delete(req, self.req_option) + self.assertTrue(response.success, response.msg) + + def _test_014_delete_dataset(self): + req = DeleteDatasetRequest.builder().dataset_id(self.dataset_id).build() + delete_response = self.client.knowledge_base.v1.dataset.delete(request=req, option=self.req_option) + self.assertTrue(delete_response.success, delete_response.msg) + self._dataset_id = None + + +if __name__ == "__main__": + unittest.main() diff --git a/sdks/python-client/tests/test_workflow.py b/sdks/python-client/tests/test_workflow.py new file mode 100644 index 0000000000..90113ef43a --- /dev/null +++ b/sdks/python-client/tests/test_workflow.py @@ -0,0 +1,93 @@ +import os +import time +import unittest +from types import GeneratorType + +from dify_oapi.api.workflow.v1.model.get_workflow_result_request import GetWorkflowResultRequest +from dify_oapi.api.workflow.v1.model.run_workflow_request import RunWorkflowRequest +from dify_oapi.api.workflow.v1.model.run_workflow_request_body import RunWorkflowRequestBody +from dify_oapi.api.workflow.v1.model.run_workflow_request_file import RunWorkflowRequestFile +from dify_oapi.api.workflow.v1.model.stop_workflow_request import StopWorkflowRequest +from dify_oapi.api.workflow.v1.model.stop_workflow_request_body import StopWorkflowRequestBody +from dify_oapi.client import Client +from dify_oapi.core.model.request_option import RequestOption + + +class TestChatClient(unittest.TestCase): + def setUp(self): + workflow_key = os.environ.get("WORKFLOW_KEY") + self.assertIsNotNone(workflow_key, "WORKFLOW_KEY must be set") + self.client = Client.builder().domain(os.environ.get("DOMAIN", "https://api.dify.ai")).build() + self.req_option = RequestOption.builder().api_key(workflow_key).build() + + self._workflow_id: str | None = None + self._task_id: str | None = None + + @property + def workflow_id(self): + if self._workflow_id is None: + self.skipTest("workflow_id is not set") + return self._workflow_id + + @property + def task_id(self): + if self._task_id is None: + self.skipTest("task_id is not set") + return self._task_id + + def test_main(self): + self._test_001_block_workflow() + time.sleep(0.5) + self._test_002_stream_workflow() + time.sleep(0.5) + self._test_003_result() + + def _test_001_block_workflow(self): + req_file = RunWorkflowRequestFile.builder() \ + .type("image") \ + .transfer_method("remote_url") \ + .url("https://cloud.dify.ai/logo/logo-site.png") \ + .build() + req_body = RunWorkflowRequestBody.builder() \ + .inputs({}) \ + .response_mode("blocking") \ + .user("abc-123") \ + .files([req_file]) \ + .build() + req = RunWorkflowRequest.builder().request_body(req_body).build() + response = self.client.workflow.v1.workflow.run(req, self.req_option, False) + self.assertTrue(response.success, response.msg) + self._workflow_id = response.workflow_run_id + self._task_id = response.task_id + + def _test_002_stream_workflow(self): + req_file = RunWorkflowRequestFile.builder() \ + .type("image") \ + .transfer_method("remote_url") \ + .url("https://cloud.dify.ai/logo/logo-site.png") \ + .build() + req_body = RunWorkflowRequestBody.builder() \ + .inputs({}) \ + .response_mode("streaming") \ + .user("abc-123") \ + .files([req_file]) \ + .build() + req = RunWorkflowRequest.builder().request_body(req_body).build() + response = self.client.workflow.v1.workflow.run(req, self.req_option, True) + if not isinstance(response, GeneratorType): + self.fail(response.msg) + + def _test_003_result(self): + req = GetWorkflowResultRequest.builder().workflow_id(self.workflow_id).build() + response = self.client.workflow.v1.workflow.result(req, self.req_option) + self.assertTrue(response.success, response.msg) + + def _test_004_stop(self): + req_body = StopWorkflowRequestBody.builder().user("abc-123").build() + req = StopWorkflowRequest.builder().request_body(req_body).task_id(self.task_id).build() + response = self.client.workflow.v1.workflow.stop(req, self.req_option) + self.assertTrue(response.success, response.msg) + + +if __name__ == "__main__": + unittest.main()