refactor: python-client

This commit is contained in:
QiMington 2024-11-07 23:54:33 +08:00
parent de850262b8
commit ed07ce1098
176 changed files with 5366 additions and 885 deletions

View File

@ -1 +1 @@
recursive-include dify_client *.py
recursive-include dify_oapi *.py

View File

@ -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("<your-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("<your-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()
```

View File

@ -1 +0,0 @@
from dify_client.client import ChatClient, CompletionClient, DifyClient

View File

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

View File

View File

View File

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

View File

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

View File

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

View File

@ -0,0 +1,5 @@
from dify_oapi.core.model.base_response import BaseResponse
class AudioToTextResponse(BaseResponse):
text: str | None = None

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,5 @@
from dify_oapi.core.model.base_response import BaseResponse
class DeleteConversationResponse(BaseResponse):
result: str | None = None

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,5 @@
from dify_oapi.core.model.base_response import BaseResponse
class StopChatResponse(BaseResponse):
result: str | None = None

View File

@ -0,0 +1,4 @@
from .chat import * # noqa F403
from .conversation import * # noqa 403
from .message import * # noqa 403
from .audio import * # noqa 403

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,5 @@
from dify_oapi.core.model.base_response import BaseResponse
class StopCompletionResponse(BaseResponse):
result: str | None = None

View File

@ -0,0 +1 @@
from .completion import * # noqa 403

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,5 @@
from dify_oapi.core.model.base_response import BaseResponse
class MessageFeedbackResponse(BaseResponse):
result: str | None = None

View File

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

View File

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

View File

@ -0,0 +1,4 @@
from dify_oapi.core.model.base_response import BaseResponse
class TextToAudioResponse(BaseResponse): ...

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,4 @@
from dify_oapi.core.model.base_response import BaseResponse
class DeleteDatasetResponse(BaseResponse): ...

View File

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

View File

@ -0,0 +1,5 @@
from dify_oapi.core.model.base_response import BaseResponse
class DeleteDocumentResponse(BaseResponse):
result: str | None = None

View File

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

Some files were not shown because too many files have changed in this diff Show More