diff --git a/README.md b/README.md
index c12ccee..729f716 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# Dify x OpenAPI
-[](https://github.com/langgenius/dify)
+[](https://github.com/langgenius/dify)
[](https://github.com/astral-sh/ruff)
[](LICENSE)
[](https://github.com/astral-sh/uv)
@@ -39,7 +39,7 @@ Provides OpenAPI Schema for [Dify](https://github.com/langgenius/dify) API, whic
> [!tip]
> This indicates that the API has passed at least one test case request. If you find any API errors, feel free to submit an issue or PR!
-- Knowledge Base: [OpenAPI Schema(中文)](./schema/knowledge_base.zh.yaml) | [OpenAPI Schema(English)](./schema/knowledge_base.en.yaml) | [Official Documentation Source](https://github.com/langgenius/dify/tree/1.7.1/web/app/(commonLayout)/datasets/template)
+- Knowledge Base: [OpenAPI Schema(中文)](./schema/knowledge_base.zh.yaml) | [OpenAPI Schema(English)](./schema/knowledge_base.en.yaml) | [Official Documentation Source](https://github.com/langgenius/dify/tree/1.7.2/web/app/(commonLayout)/datasets/template)
- [x] POST /datasets - Create empty knowledge base
- [x] POST /datasets/{dataset_id} - Update knowledge base
- [x] GET /datasets/{dataset_id}/documents - Get document list
@@ -71,7 +71,7 @@ Provides OpenAPI Schema for [Dify](https://github.com/langgenius/dify) API, whic
- [x] POST /datasets/{dataset_id}/tags - Query dataset bound tags
- [x] POST /datasets/{dataset_id}/retrieval - Retrieve with metadata filtering conditions
-- Chat Application: [OpenAPI Schema(中文)](./schema/app_chat.zh.yaml) | [OpenAPI Schema(English)](./schema/app_chat.en.yaml) | [Official Documentation Source](https://github.com/langgenius/dify/tree/1.7.1/web/app/components/develop/template)
+- Chat Application: [OpenAPI Schema(中文)](./schema/app_chat.zh.yaml) | [OpenAPI Schema(English)](./schema/app_chat.en.yaml) | [Official Documentation Source](https://github.com/langgenius/dify/tree/1.7.2/web/app/components/develop/template)
- [x] POST /chat-messages - Send conversation message
- [x] POST /files/upload - Upload file
- [x] POST /messages/{message_id}/feedbacks - Message feedback
@@ -84,7 +84,7 @@ Provides OpenAPI Schema for [Dify](https://github.com/langgenius/dify) API, whic
- [x] GET /info - Get application basic information
- [x] GET /parameters - Get application parameters
-- Advanced Chat Application: [OpenAPI Schema(中文)](./schema/app_advanced_chat.zh.yaml) | [OpenAPI Schema(English)](./schema/app_advanced_chat.en.yaml) | [Official Documentation Source](https://github.com/langgenius/dify/tree/1.7.1/web/app/components/develop/template)
+- Advanced Chat Application: [OpenAPI Schema(中文)](./schema/app_advanced_chat.zh.yaml) | [OpenAPI Schema(English)](./schema/app_advanced_chat.en.yaml) | [Official Documentation Source](https://github.com/langgenius/dify/tree/1.7.2/web/app/components/develop/template)
- [x] POST /audio-to-text - Speech to text
- [x] POST /text-to-audio - Text to speech
- [x] GET /apps/annotations - Get annotation list
@@ -100,10 +100,10 @@ Provides OpenAPI Schema for [Dify](https://github.com/langgenius/dify) API, whic
- [x] GET /parameters - Get application parameters
-- Text Generation Application: [OpenAPI Schema(中文)](./schema/app_generation.zh.yaml) | [OpenAPI Schema(English)](./schema/app_generation.en.yaml) | [Official Documentation Source](https://github.com/langgenius/dify/tree/1.7.1/web/app/components/develop/template)
+- Text Generation Application: [OpenAPI Schema(中文)](./schema/app_generation.zh.yaml) | [OpenAPI Schema(English)](./schema/app_generation.en.yaml) | [Official Documentation Source](https://github.com/langgenius/dify/tree/1.7.2/web/app/components/develop/template)
- [x] POST /completion-messages - Send message
-- Workflow Application: [OpenAPI Schema(中文)](./schema/app_workflow.zh.yaml) | [OpenAPI Schema(English)](./schema/app_workflow.en.yaml) | [Official Documentation Source](https://github.com/langgenius/dify/tree/1.7.1/web/app/components/develop/template)
+- Workflow Application: [OpenAPI Schema(中文)](./schema/app_workflow.zh.yaml) | [OpenAPI Schema(English)](./schema/app_workflow.en.yaml) | [Official Documentation Source](https://github.com/langgenius/dify/tree/1.7.2/web/app/components/develop/template)
- [x] POST /workflows/run - Execute workflow
- [x] GET /workflows/run/{workflow_run_id} - Get workflow execution status
- [x] POST /workflows/tasks/{task_id}/stop - Stop response
diff --git a/README.zh.md b/README.zh.md
index 4f1bd01..00a6dea 100644
--- a/README.zh.md
+++ b/README.zh.md
@@ -1,6 +1,6 @@
# Dify x OpenAPI
-[](https://github.com/langgenius/dify)
+[](https://github.com/langgenius/dify)
[](https://github.com/astral-sh/ruff)
[](LICENSE)
[](https://github.com/astral-sh/uv)
@@ -41,7 +41,7 @@
> [!tip]
> 这里指至少可以通过一次测试用例请求, 如果你发现有哪些API错误, 欢迎提issue或者pr!
-- 知识库: [OpenAPI Schema(中文)](./schema/knowledge_base.zh.yaml) | [OpenAPI Schema(English)](./schema/knowledge_base.en.yaml) | [官方文档源码](https://github.com/langgenius/dify/tree/1.7.1/web/app/(commonLayout)/datasets/template)
+- 知识库: [OpenAPI Schema(中文)](./schema/knowledge_base.zh.yaml) | [OpenAPI Schema(English)](./schema/knowledge_base.en.yaml) | [官方文档源码](https://github.com/langgenius/dify/tree/1.7.2/web/app/(commonLayout)/datasets/template)
- [x] POST /datasets - 创建空知识库
- [x] POST /datasets/{dataset_id} - 更新知识库
- [x] GET /datasets/{dataset_id}/documents - 获取文档列表
@@ -73,7 +73,7 @@
- [x] POST /datasets/{dataset_id}/tags - 查询知识库已绑定的标签
- [x] POST /datasets/{dataset_id}/retrieval - 带元数据过滤条件的检索
-- 聊天应用: [OpenAPI Schema(中文)](./schema/app_chat.zh.yaml) | [OpenAPI Schema(English)](./schema/app_chat.en.yaml) | [官方文档源码](https://github.com/langgenius/dify/tree/1.7.1/web/app/components/develop/template)
+- 聊天应用: [OpenAPI Schema(中文)](./schema/app_chat.zh.yaml) | [OpenAPI Schema(English)](./schema/app_chat.en.yaml) | [官方文档源码](https://github.com/langgenius/dify/tree/1.7.2/web/app/components/develop/template)
- [x] POST /chat-messages - 发送对话消息
- [x] POST /files/upload - 上传文件
- [x] POST /messages/{message_id}/feedbacks - 消息反馈
@@ -86,7 +86,7 @@
- [x] GET /info - 获取应用基本信息
- [x] GET /parameters - 获取应用参数
-- 高级聊天应用: [OpenAPI Schema(中文)](./schema/app_advanced_chat.zh.yaml) | [OpenAPI Schema(English)](./schema/app_advanced_chat.en.yaml) | [官方文档源码](https://github.com/langgenius/dify/tree/1.7.1/web/app/components/develop/template)
+- 高级聊天应用: [OpenAPI Schema(中文)](./schema/app_advanced_chat.zh.yaml) | [OpenAPI Schema(English)](./schema/app_advanced_chat.en.yaml) | [官方文档源码](https://github.com/langgenius/dify/tree/1.7.2/web/app/components/develop/template)
- [x] POST /audio-to-text - 语音转文字
- [x] POST /text-to-audio - 文字转语音
- [x] GET /apps/annotations - 获取标注列表
@@ -101,10 +101,10 @@
- [x] GET /info - 获取应用基本信息
- [x] GET /parameters - 获取应用参数(包含文字转语音设置)
-- 文本生成应用: [OpenAPI Schema(中文)](./schema/app_generation.zh.yaml) | [OpenAPI Schema(English)](./schema/app_generation.en.yaml) | [官方文档源码](https://github.com/langgenius/dify/tree/1.7.1/web/app/components/develop/template)
+- 文本生成应用: [OpenAPI Schema(中文)](./schema/app_generation.zh.yaml) | [OpenAPI Schema(English)](./schema/app_generation.en.yaml) | [官方文档源码](https://github.com/langgenius/dify/tree/1.7.2/web/app/components/develop/template)
- [x] POST /completion-messages - 发送消息
-- 工作流应用: [OpenAPI Schema(中文)](./schema/app_workflow.zh.yaml) | [OpenAPI Schema(English)](./schema/app_workflow.en.yaml) | [官方文档源码](https://github.com/langgenius/dify/tree/1.7.1/web/app/components/develop/template)
+- 工作流应用: [OpenAPI Schema(中文)](./schema/app_workflow.zh.yaml) | [OpenAPI Schema(English)](./schema/app_workflow.en.yaml) | [官方文档源码](https://github.com/langgenius/dify/tree/1.7.2/web/app/components/develop/template)
- [x] POST /workflows/run - 执行工作流
- [x] GET /workflows/run/{workflow_run_id} - 获取工作流执行状态
- [x] POST /workflows/tasks/{task_id}/stop - 停止响应
diff --git a/libs/dify b/libs/dify
index 79ea944..658157e 160000
--- a/libs/dify
+++ b/libs/dify
@@ -1 +1 @@
-Subproject commit 79ea94483ef8aa2bd30f088acd0f474ee3c93d16
+Subproject commit 658157e9a1fded47732688083fbdefadeafba784
diff --git a/misc/official_api_doc_changes/1.7.1__1.7.2.diff b/misc/official_api_doc_changes/1.7.1__1.7.2.diff
new file mode 100644
index 0000000..8a0c809
--- /dev/null
+++ b/misc/official_api_doc_changes/1.7.1__1.7.2.diff
@@ -0,0 +1,1313 @@
+diff --git a/web/app/(commonLayout)/datasets/template/template.zh.mdx b/web/app/(commonLayout)/datasets/template/template.zh.mdx
+index c21ce3bf5f..b7ea889a46 100644
+--- a/web/app/(commonLayout)/datasets/template/template.zh.mdx
++++ b/web/app/(commonLayout)/datasets/template/template.zh.mdx
+@@ -25,7 +25,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
+
+
+
+-
++
+
+
+
+
+-
++
+
+
+
+
+-
++
+
+
+
+
+-
++
+
+
+
+
+-
++
+
+
+
+
+-
++
+
+
+
+
+-
++
+
+
+
+
+-
++
+
+
+
+
+-
++
+
+
+
+
+-
++
+
+
+
+
+-
++
+
+
+
+
+-
++
+
+
+
+
+-
++
+
+
+
+ ___
+-
++
+
+
+
+
+
+-
++
+
+
+
+
+-
++
+
+
+
+
+-
++
+
+
+
+
+-
++
+
+
+
+
+-
++
+
+
+
+
+-
++
+
+
+
+
+-
++
+
+
+
+
+-
++
+
+
+
+
+-
++
+
+
+
+@@ -1915,7 +1915,7 @@ ___
+
+
+
+-
++
+
+
+
+
+-
++
+
+
+
+
+-
++
+
+
+
+
+-
++
+
+
+
+
+-
++
+
+
+
+
+-
++
+
+
+
+
+-
++
+
+
+
+
+-
++
+
+
+
+
+-
++
+
+
+
+
+-
++
+
+
+
+
+-
++
+
+
+
+
+-
++
+
+
+
+
+-
++
+
+
+
+
+-
++
+
+
+
+
+
+-
++
+
+
+
+
+-
++
+
+
+
+
+-
++
+
+
+
+
+-
++
+
+
+
+diff --git a/web/app/components/develop/template/template.zh.mdx b/web/app/components/develop/template/template.zh.mdx
+index a5eea3d193..16a2a36c49 100755
+--- a/web/app/components/develop/template/template.zh.mdx
++++ b/web/app/components/develop/template/template.zh.mdx
+@@ -252,6 +252,86 @@ import { Row, Col, Properties, Property, Heading, SubProperty } from '../md.tsx'
+
+
+ ---
++
++
++
++
++ 预览或下载已上传的文件。此端点允许您访问先前通过文件上传 API 上传的文件。
++
++ 文件只能在属于请求应用程序的消息范围内访问。
++
++ ### 路径参数
++ - `file_id` (string) 必需
++ 要预览的文件的唯一标识符,从文件上传 API 响应中获得。
++
++ ### 查询参数
++ - `as_attachment` (boolean) 可选
++ 是否强制将文件作为附件下载。默认为 `false`(在浏览器中预览)。
++
++ ### 响应
++ 返回带有适当浏览器显示或下载标头的文件内容。
++ - `Content-Type` 根据文件 MIME 类型设置
++ - `Content-Length` 文件大小(以字节为单位,如果可用)
++ - `Content-Disposition` 如果 `as_attachment=true` 则设置为 "attachment"
++ - `Cache-Control` 用于性能的缓存标头
++ - `Accept-Ranges` 对于音频/视频文件设置为 "bytes"
++
++ ### 错误
++ - 400, `invalid_param`, 参数输入异常
++ - 403, `file_access_denied`, 文件访问被拒绝或文件不属于当前应用程序
++ - 404, `file_not_found`, 文件未找到或已被删除
++ - 500, 服务内部错误
++
++
++
++ ### 请求示例
++
++
++ ```bash {{ title: 'cURL' }}
++ curl -X GET '${props.appDetail.api_base_url}/files/72fa9618-8f89-4a37-9b33-7e1178a24a67/preview' \
++ --header 'Authorization: Bearer {api_key}'
++ ```
++
++
++
++ ### 作为附件下载
++
++
++ ```bash {{ title: 'cURL' }}
++ curl -X GET '${props.appDetail.api_base_url}/files/72fa9618-8f89-4a37-9b33-7e1178a24a67/preview?as_attachment=true' \
++ --header 'Authorization: Bearer {api_key}' \
++ --output downloaded_file.png
++ ```
++
++
++
++ ### 响应标头示例
++
++ ```http {{ title: 'Headers - 图片预览' }}
++ Content-Type: image/png
++ Content-Length: 1024
++ Cache-Control: public, max-age=3600
++ ```
++
++
++ ### 文件下载响应标头
++
++ ```http {{ title: 'Headers - 文件下载' }}
++ Content-Type: image/png
++ Content-Length: 1024
++ Content-Disposition: attachment; filename*=UTF-8''example.png
++ Cache-Control: public, max-age=3600
++ ```
++
++
++
++---
++
+
+
+
+diff --git a/web/app/components/develop/template/template_advanced_chat.zh.mdx b/web/app/components/develop/template/template_advanced_chat.zh.mdx
+index 30068d93a2..1a7060abc0 100755
+--- a/web/app/components/develop/template/template_advanced_chat.zh.mdx
++++ b/web/app/components/develop/template/template_advanced_chat.zh.mdx
+@@ -78,6 +78,9 @@ import { Row, Col, Properties, Property, Heading, SubProperty } from '../md.tsx'
+
+ (选填)自动生成标题,默认 `true`。 若设置为 `false`,则可通过调用会话重命名接口并设置 `auto_generate` 为 `true` 实现异步生成标题。
+
++
++ (选填)工作流ID,用于指定特定版本,如果不提供则使用默认的已发布版本。
++
+
+ (选填)链路追踪ID。适用于与业务系统已有的trace组件打通,实现端到端分布式追踪等场景。如果未指定,系统会自动生成trace_id。支持以下三种方式传递,具体优先级依次为:
+ - Header:通过 HTTP Header X-Trace-Id 传递,优先级最高。
+@@ -224,6 +227,9 @@ import { Row, Col, Properties, Property, Heading, SubProperty } from '../md.tsx'
+ - 400,`provider_not_initialize`,无可用模型凭据配置
+ - 400,`provider_quota_exceeded`,模型调用额度不足
+ - 400,`model_currently_not_support`,当前模型不可用
++ - 400,`workflow_not_found`,指定的工作流版本未找到
++ - 400,`draft_workflow_error`,无法使用草稿工作流版本
++ - 400,`workflow_id_format_error`,工作流ID格式错误,需要UUID格式
+ - 400,`completion_request_error`,文本生成失败
+ - 500,服务内部异常
+
+@@ -393,6 +399,86 @@ import { Row, Col, Properties, Property, Heading, SubProperty } from '../md.tsx'
+
+
+ ---
++
++
++
++
++ 预览或下载已上传的文件。此端点允许您访问先前通过文件上传 API 上传的文件。
++
++ 文件只能在属于请求应用程序的消息范围内访问。
++
++ ### 路径参数
++ - `file_id` (string) 必需
++ 要预览的文件的唯一标识符,从文件上传 API 响应中获得。
++
++ ### 查询参数
++ - `as_attachment` (boolean) 可选
++ 是否强制将文件作为附件下载。默认为 `false`(在浏览器中预览)。
++
++ ### 响应
++ 返回带有适当浏览器显示或下载标头的文件内容。
++ - `Content-Type` 根据文件 MIME 类型设置
++ - `Content-Length` 文件大小(以字节为单位,如果可用)
++ - `Content-Disposition` 如果 `as_attachment=true` 则设置为 "attachment"
++ - `Cache-Control` 用于性能的缓存标头
++ - `Accept-Ranges` 对于音频/视频文件设置为 "bytes"
++
++ ### 错误
++ - 400, `invalid_param`, 参数输入异常
++ - 403, `file_access_denied`, 文件访问被拒绝或文件不属于当前应用程序
++ - 404, `file_not_found`, 文件未找到或已被删除
++ - 500, 服务内部错误
++
++
++
++ ### 请求示例
++
++
++ ```bash {{ title: 'cURL' }}
++ curl -X GET '${props.appDetail.api_base_url}/files/72fa9618-8f89-4a37-9b33-7e1178a24a67/preview' \
++ --header 'Authorization: Bearer {api_key}'
++ ```
++
++
++
++ ### 作为附件下载
++
++
++ ```bash {{ title: 'cURL' }}
++ curl -X GET '${props.appDetail.api_base_url}/files/72fa9618-8f89-4a37-9b33-7e1178a24a67/preview?as_attachment=true' \
++ --header 'Authorization: Bearer {api_key}' \
++ --output downloaded_file.png
++ ```
++
++
++
++ ### 响应标头示例
++
++ ```http {{ title: 'Headers - 图片预览' }}
++ Content-Type: image/png
++ Content-Length: 1024
++ Cache-Control: public, max-age=3600
++ ```
++
++
++ ### 文件下载响应标头
++
++ ```http {{ title: 'Headers - 文件下载' }}
++ Content-Type: image/png
++ Content-Length: 1024
++ Content-Disposition: attachment; filename*=UTF-8''example.png
++ Cache-Control: public, max-age=3600
++ ```
++
++
++
++---
++
+
++
++
++ 更新特定对话变量的值。此端点允许您修改在对话过程中捕获的变量值,同时保留其名称、类型和描述。
++
++ ### 路径参数
++
++
++
++ 包含要更新变量的对话ID。
++
++
++ 要更新的变量ID。
++
++
++
++ ### 请求体
++
++
++
++ 变量的新值。必须匹配变量的预期类型(字符串、数字、对象等)。
++
++
++ 用户标识符,由开发人员定义的规则,在应用程序内必须唯一。
++
++
++
++ ### 响应
++
++ 返回包含以下内容的更新变量对象:
++ - `id` (string) 变量ID
++ - `name` (string) 变量名称
++ - `value_type` (string) 变量类型(字符串、数字、对象等)
++ - `value` (any) 更新后的变量值
++ - `description` (string) 变量描述
++ - `created_at` (int) 创建时间戳
++ - `updated_at` (int) 最后更新时间戳
++
++ ### 错误
++ - 400, `Type mismatch: variable expects {expected_type}, but got {actual_type} type`, 值类型与变量的预期类型不匹配
++ - 404, `conversation_not_exists`, 对话不存在
++ - 404, `conversation_variable_not_exists`, 变量不存在
++
++
++
++
++
++
++ ```bash {{ title: 'cURL' }}
++ curl -X PUT '${props.appDetail.api_base_url}/conversations/{conversation_id}/variables/{variable_id}' \
++ --header 'Content-Type: application/json' \
++ --header 'Authorization: Bearer {api_key}' \
++ --data-raw '{
++ "value": "Updated Value",
++ "user": "abc-123"
++ }'
++ ```
++
++
++
++
++ ```bash {{ title: '字符串值' }}
++ curl -X PUT '${props.appDetail.api_base_url}/conversations/{conversation_id}/variables/{variable_id}' \
++ --header 'Content-Type: application/json' \
++ --header 'Authorization: Bearer {api_key}' \
++ --data-raw '{
++ "value": "新的字符串值",
++ "user": "abc-123"
++ }'
++ ```
++
++ ```bash {{ title: '数字值' }}
++ curl -X PUT '${props.appDetail.api_base_url}/conversations/{conversation_id}/variables/{variable_id}' \
++ --header 'Content-Type: application/json' \
++ --header 'Authorization: Bearer {api_key}' \
++ --data-raw '{
++ "value": 42,
++ "user": "abc-123"
++ }'
++ ```
++
++ ```bash {{ title: '对象值' }}
++ curl -X PUT '${props.appDetail.api_base_url}/conversations/{conversation_id}/variables/{variable_id}' \
++ --header 'Content-Type: application/json' \
++ --header 'Authorization: Bearer {api_key}' \
++ --data-raw '{
++ "value": {"product": "Widget", "quantity": 10, "price": 29.99},
++ "user": "abc-123"
++ }'
++ ```
++
++
++
++ ```json {{ title: 'Response' }}
++ {
++ "id": "variable-uuid-1",
++ "name": "customer_name",
++ "value_type": "string",
++ "value": "Updated Value",
++ "description": "客户名称(从对话中提取)",
++ "created_at": 1650000000000,
++ "updated_at": 1650000001000
++ }
++ ```
++
++
++
++
++---
++
+
+
+
+@@ -1101,7 +1302,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty } from '../md.tsx'
+ url='/text-to-audio'
+ method='POST'
+ title='文字转语音'
+- name='#audio'
++ name='#text-to-audio'
+ />
+
+
+diff --git a/web/app/components/develop/template/template_chat.zh.mdx b/web/app/components/develop/template/template_chat.zh.mdx
+index a7127d614b..c975749c10 100644
+--- a/web/app/components/develop/template/template_chat.zh.mdx
++++ b/web/app/components/develop/template/template_chat.zh.mdx
+@@ -73,6 +73,9 @@ import { Row, Col, Properties, Property, Heading, SubProperty } from '../md.tsx'
+
+ (选填)自动生成标题,默认 `true`。 若设置为 `false`,则可通过调用会话重命名接口并设置 `auto_generate` 为 `true` 实现异步生成标题。
+
++
++ (选填)工作流ID,用于指定特定版本,如果不提供则使用默认的已发布版本。
++
+
+ (选填)链路追踪ID。适用于与业务系统已有的trace组件打通,实现端到端分布式追踪等场景。如果未指定,系统会自动生成trace_id。支持以下三种方式传递,具体优先级依次为:
+ - Header:通过 HTTP Header X-Trace-Id 传递,优先级最高。
+@@ -181,6 +184,9 @@ import { Row, Col, Properties, Property, Heading, SubProperty } from '../md.tsx'
+ - 400,`provider_not_initialize`,无可用模型凭据配置
+ - 400,`provider_quota_exceeded`,模型调用额度不足
+ - 400,`model_currently_not_support`,当前模型不可用
++ - 400,`workflow_not_found`,指定的工作流版本未找到
++ - 400,`draft_workflow_error`,无法使用草稿工作流版本
++ - 400,`workflow_id_format_error`,工作流ID格式错误,需要UUID格式
+ - 400,`completion_request_error`,文本生成失败
+ - 500,服务内部异常
+
+@@ -365,6 +371,86 @@ import { Row, Col, Properties, Property, Heading, SubProperty } from '../md.tsx'
+
+
+ ---
++
++
++
++
++ 预览或下载已上传的文件。此端点允许您访问先前通过文件上传 API 上传的文件。
++
++ 文件只能在属于请求应用程序的消息范围内访问。
++
++ ### 路径参数
++ - `file_id` (string) 必需
++ 要预览的文件的唯一标识符,从文件上传 API 响应中获得。
++
++ ### 查询参数
++ - `as_attachment` (boolean) 可选
++ 是否强制将文件作为附件下载。默认为 `false`(在浏览器中预览)。
++
++ ### 响应
++ 返回带有适当浏览器显示或下载标头的文件内容。
++ - `Content-Type` 根据文件 MIME 类型设置
++ - `Content-Length` 文件大小(以字节为单位,如果可用)
++ - `Content-Disposition` 如果 `as_attachment=true` 则设置为 "attachment"
++ - `Cache-Control` 用于性能的缓存标头
++ - `Accept-Ranges` 对于音频/视频文件设置为 "bytes"
++
++ ### 错误
++ - 400, `invalid_param`, 参数输入异常
++ - 403, `file_access_denied`, 文件访问被拒绝或文件不属于当前应用程序
++ - 404, `file_not_found`, 文件未找到或已被删除
++ - 500, 服务内部错误
++
++
++
++ ### 请求示例
++
++
++ ```bash {{ title: 'cURL' }}
++ curl -X GET '${props.appDetail.api_base_url}/files/72fa9618-8f89-4a37-9b33-7e1178a24a67/preview' \
++ --header 'Authorization: Bearer {api_key}'
++ ```
++
++
++
++ ### 作为附件下载
++
++
++ ```bash {{ title: 'cURL' }}
++ curl -X GET '${props.appDetail.api_base_url}/files/72fa9618-8f89-4a37-9b33-7e1178a24a67/preview?as_attachment=true' \
++ --header 'Authorization: Bearer {api_key}' \
++ --output downloaded_file.png
++ ```
++
++
++
++ ### 响应标头示例
++
++ ```http {{ title: 'Headers - 图片预览' }}
++ Content-Type: image/png
++ Content-Length: 1024
++ Cache-Control: public, max-age=3600
++ ```
++
++
++ ### 文件下载响应标头
++
++ ```http {{ title: 'Headers - 文件下载' }}
++ Content-Type: image/png
++ Content-Length: 1024
++ Content-Disposition: attachment; filename*=UTF-8''example.png
++ Cache-Control: public, max-age=3600
++ ```
++
++
++
++---
++
+
++
++
++ 更新特定对话变量的值。此端点允许您修改在对话过程中捕获的变量值,同时保留其名称、类型和描述。
++
++ ### 路径参数
++
++
++
++ 包含要更新变量的对话ID。
++
++
++ 要更新的变量ID。
++
++
++
++ ### 请求体
++
++
++
++ 变量的新值。必须匹配变量的预期类型(字符串、数字、对象等)。
++
++
++ 用户标识符,由开发人员定义的规则,在应用程序内必须唯一。
++
++
++
++ ### 响应
++
++ 返回包含以下内容的更新变量对象:
++ - `id` (string) 变量ID
++ - `name` (string) 变量名称
++ - `value_type` (string) 变量类型(字符串、数字、对象等)
++ - `value` (any) 更新后的变量值
++ - `description` (string) 变量描述
++ - `created_at` (int) 创建时间戳
++ - `updated_at` (int) 最后更新时间戳
++
++ ### 错误
++ - 400, `Type mismatch: variable expects {expected_type}, but got {actual_type} type`, 值类型与变量的预期类型不匹配
++ - 404, `conversation_not_exists`, 对话不存在
++ - 404, `conversation_variable_not_exists`, 变量不存在
++
++
++
++
++
++
++ ```bash {{ title: 'cURL' }}
++ curl -X PUT '${props.appDetail.api_base_url}/conversations/{conversation_id}/variables/{variable_id}' \
++ --header 'Content-Type: application/json' \
++ --header 'Authorization: Bearer {api_key}' \
++ --data-raw '{
++ "value": "Updated Value",
++ "user": "abc-123"
++ }'
++ ```
++
++
++
++
++ ```bash {{ title: '字符串值' }}
++ curl -X PUT '${props.appDetail.api_base_url}/conversations/{conversation_id}/variables/{variable_id}' \
++ --header 'Content-Type: application/json' \
++ --header 'Authorization: Bearer {api_key}' \
++ --data-raw '{
++ "value": "新的字符串值",
++ "user": "abc-123"
++ }'
++ ```
++
++ ```bash {{ title: '数字值' }}
++ curl -X PUT '${props.appDetail.api_base_url}/conversations/{conversation_id}/variables/{variable_id}' \
++ --header 'Content-Type: application/json' \
++ --header 'Authorization: Bearer {api_key}' \
++ --data-raw '{
++ "value": 42,
++ "user": "abc-123"
++ }'
++ ```
++
++ ```bash {{ title: '对象值' }}
++ curl -X PUT '${props.appDetail.api_base_url}/conversations/{conversation_id}/variables/{variable_id}' \
++ --header 'Content-Type: application/json' \
++ --header 'Authorization: Bearer {api_key}' \
++ --data-raw '{
++ "value": {"product": "Widget", "quantity": 10, "price": 29.99},
++ "user": "abc-123"
++ }'
++ ```
++
++
++
++ ```json {{ title: 'Response' }}
++ {
++ "id": "variable-uuid-1",
++ "name": "customer_name",
++ "value_type": "string",
++ "value": "Updated Value",
++ "description": "客户名称(从对话中提取)",
++ "created_at": 1650000000000,
++ "updated_at": 1650000001000
++ }
++ ```
++
++
++
++
++---
++
+
+
+
+@@ -1112,7 +1313,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty } from '../md.tsx'
+ url='/text-to-audio'
+ method='POST'
+ title='文字转语音'
+- name='#audio'
++ name='#text-to-audio'
+ />
+
+
+diff --git a/web/app/components/develop/template/template_workflow.zh.mdx b/web/app/components/develop/template/template_workflow.zh.mdx
+index 236da62e88..5c00f03a70 100644
+--- a/web/app/components/develop/template/template_workflow.zh.mdx
++++ b/web/app/components/develop/template/template_workflow.zh.mdx
+@@ -328,6 +328,235 @@ Workflow 应用无会话支持,适合用于翻译/文章写作/总结 AI 等
+
+ ---
+
++
++
++
++ 执行指定版本的工作流,通过路径参数指定工作流ID。
++
++ ### Path
++ - `workflow_id` (string) Required 工作流ID,用于指定特定版本的工作流
++
++ 获取方式:可以在版本历史中查询特定版本的工作流ID。
++
++ ### Request Body
++ - `inputs` (object) Required
++ 允许传入 App 定义的各变量值。
++ inputs 参数包含了多组键值对(Key/Value pairs),每组的键对应一个特定变量,每组的值则是该变量的具体值。变量可以是文件列表类型。
++ 文件列表类型变量适用于传入文件结合文本理解并回答问题,仅当模型支持该类型文件解析能力时可用。如果该变量是文件列表类型,该变量对应的值应是列表格式,其中每个元素应包含以下内容:
++ - `type` (string) 支持类型:
++ - `document` 具体类型包含:'TXT', 'MD', 'MARKDOWN', 'PDF', 'HTML', 'XLSX', 'XLS', 'DOCX', 'CSV', 'EML', 'MSG', 'PPTX', 'PPT', 'XML', 'EPUB'
++ - `image` 具体类型包含:'JPG', 'JPEG', 'PNG', 'GIF', 'WEBP', 'SVG'
++ - `audio` 具体类型包含:'MP3', 'M4A', 'WAV', 'WEBM', 'AMR'
++ - `video` 具体类型包含:'MP4', 'MOV', 'MPEG', 'MPGA'
++ - `custom` 具体类型包含:其他文件类型
++ - `transfer_method` (string) 传递方式,`remote_url` 图片地址 / `local_file` 上传文件
++ - `url` (string) 图片地址(仅当传递方式为 `remote_url` 时)
++ - `upload_file_id` (string) 上传文件 ID(仅当传递方式为 `local_file` 时)
++ - `response_mode` (string) Required
++ 返回响应模式,支持:
++ - `streaming` 流式模式(推荐)。基于 SSE(**[Server-Sent Events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events)**)实现类似打字机输出方式的流式返回。
++ - `blocking` 阻塞模式,等待执行完毕后返回结果。(请求若流程较长可能会被中断)。
++ 由于 Cloudflare 限制,请求会在 100 秒超时无返回后中断。
++ - `user` (string) Required
++ 用户标识,用于定义终端用户的身份,方便检索、统计。
++ 由开发者定义规则,需保证用户标识在应用内唯一。API 无法访问 WebApp 创建的会话。
++ - `files` (array[object]) 可选
++ - `trace_id` (string) Optional
++ 链路追踪ID。适用于与业务系统已有的trace组件打通,实现端到端分布式追踪等场景。如果未指定,系统将自动生成 `trace_id`。支持以下三种方式传递,具体优先级依次为:
++ 1. Header:推荐通过 HTTP Header `X-Trace-Id` 传递,优先级最高。
++ 2. Query 参数:通过 URL 查询参数 `trace_id` 传递。
++ 3. Request Body:通过请求体字段 `trace_id` 传递(即本字段)。
++
++ ### Response
++ 当 `response_mode` 为 `blocking` 时,返回 CompletionResponse object。
++ 当 `response_mode` 为 `streaming`时,返回 ChunkCompletionResponse object 流式序列。
++
++ ### CompletionResponse
++ 返回完整的 App 结果,`Content-Type` 为 `application/json` 。
++ - `workflow_run_id` (string) workflow 执行 ID
++ - `task_id` (string) 任务 ID,用于请求跟踪和下方的停止响应接口
++ - `data` (object) 详细内容
++ - `id` (string) workflow 执行 ID
++ - `workflow_id` (string) 关联 Workflow ID
++ - `status` (string) 执行状态, `running` / `succeeded` / `failed` / `stopped`
++ - `outputs` (json) Optional 输出内容
++ - `error` (string) Optional 错误原因
++ - `elapsed_time` (float) Optional 耗时(s)
++ - `total_tokens` (int) Optional 总使用 tokens
++ - `total_steps` (int) 总步数(冗余),默认 0
++ - `created_at` (timestamp) 开始时间
++ - `finished_at` (timestamp) 结束时间
++
++ ### ChunkCompletionResponse
++ 返回 App 输出的流式块,`Content-Type` 为 `text/event-stream`。
++ 每个流式块均为 data: 开头,块之间以 `\n\n` 即两个换行符分隔,如下所示:
++
++ ```streaming {{ title: 'Response' }}
++ data: {"event": "text_chunk", "workflow_run_id": "b85e5fc5-751b-454d-b14e-dc5f240b0a31", "task_id": "bd029338-b068-4d34-a331-fc85478922c2", "data": {"text": "\u4e3a\u4e86", "from_variable_selector": ["1745912968134", "text"]}}\n\n
++ ```
++
++ 流式块中根据 `event` 不同,结构也不同,包含以下类型:
++ - `event: workflow_started` workflow 开始执行
++ - `task_id` (string) 任务 ID,用于请求跟踪和下方的停止响应接口
++ - `workflow_run_id` (string) workflow 执行 ID
++ - `event` (string) 固定为 `workflow_started`
++ - `data` (object) 详细内容
++ - `id` (string) workflow 执行 ID
++ - `workflow_id` (string) 关联 Workflow ID
++ - `created_at` (timestamp) 开始时间
++ - `event: node_started` node 开始执行
++ - `task_id` (string) 任务 ID,用于请求跟踪和下方的停止响应接口
++ - `workflow_run_id` (string) workflow 执行 ID
++ - `event` (string) 固定为 `node_started`
++ - `data` (object) 详细内容
++ - `id` (string) workflow 执行 ID
++ - `node_id` (string) 节点 ID
++ - `node_type` (string) 节点类型
++ - `title` (string) 节点名称
++ - `index` (int) 执行序号,用于展示 Tracing Node 顺序
++ - `predecessor_node_id` (string) 前置节点 ID,用于画布展示执行路径
++ - `inputs` (object) 节点中所有使用到的前置节点变量内容
++ - `created_at` (timestamp) 开始时间
++ - `event: text_chunk` 文本片段
++ - `task_id` (string) 任务 ID,用于请求跟踪和下方的停止响应接口
++ - `workflow_run_id` (string) workflow 执行 ID
++ - `event` (string) 固定为 `text_chunk`
++ - `data` (object) 详细内容
++ - `text` (string) 文本内容
++ - `from_variable_selector` (array) 文本来源路径,帮助开发者了解文本是由哪个节点的哪个变量生成的
++ - `event: node_finished` node 执行结束,成功失败同一事件中不同状态
++ - `task_id` (string) 任务 ID,用于请求跟踪和下方的停止响应接口
++ - `workflow_run_id` (string) workflow 执行 ID
++ - `event` (string) 固定为 `node_finished`
++ - `data` (object) 详细内容
++ - `id` (string) node 执行 ID
++ - `node_id` (string) 节点 ID
++ - `index` (int) 执行序号,用于展示 Tracing Node 顺序
++ - `predecessor_node_id` (string) optional 前置节点 ID,用于画布展示执行路径
++ - `inputs` (object) 节点中所有使用到的前置节点变量内容
++ - `process_data` (json) Optional 节点过程数据
++ - `outputs` (json) Optional 输出内容
++ - `status` (string) 执行状态 `running` / `succeeded` / `failed` / `stopped`
++ - `error` (string) Optional 错误原因
++ - `elapsed_time` (float) Optional 耗时(s)
++ - `execution_metadata` (json) 元数据
++ - `total_tokens` (int) optional 总使用 tokens
++ - `total_price` (decimal) optional 总费用
++ - `currency` (string) optional 货币,如 `USD` / `RMB`
++ - `created_at` (timestamp) 开始时间
++ - `event: workflow_finished` workflow 执行结束,成功失败同一事件中不同状态
++ - `task_id` (string) 任务 ID,用于请求跟踪和下方的停止响应接口
++ - `workflow_run_id` (string) workflow 执行 ID
++ - `event` (string) 固定为 `workflow_finished`
++ - `data` (object) 详细内容
++ - `id` (string) workflow 执行 ID
++ - `workflow_id` (string) 关联 Workflow ID
++ - `status` (string) 执行状态 `running` / `succeeded` / `failed` / `stopped`
++ - `outputs` (json) Optional 输出内容
++ - `error` (string) Optional 错误原因
++ - `elapsed_time` (float) Optional 耗时(s)
++ - `total_tokens` (int) Optional 总使用 tokens
++ - `total_steps` (int) 总步数(冗余),默认 0
++ - `created_at` (timestamp) 开始时间
++ - `finished_at` (timestamp) 结束时间
++ - `event: tts_message` TTS 音频流事件,即:语音合成输出。内容是Mp3格式的音频块,使用 base64 编码后的字符串,播放的时候直接解码即可。(开启自动播放才有此消息)
++ - `task_id` (string) 任务 ID,用于请求跟踪和下方的停止响应接口
++ - `message_id` (string) 消息唯一 ID
++ - `audio` (string) 语音合成之后的音频块使用 Base64 编码之后的文本内容,播放的时候直接 base64 解码送入播放器即可
++ - `created_at` (int) 创建时间戳,如:1705395332
++ - `event: tts_message_end` TTS 音频流结束事件,收到这个事件表示音频流返回结束。
++ - `task_id` (string) 任务 ID,用于请求跟踪和下方的停止响应接口
++ - `message_id` (string) 消息唯一 ID
++ - `audio` (string) 结束事件是没有音频的,所以这里是空字符串
++ - `created_at` (int) 创建时间戳,如:1705395332
++ - `event: ping` 每 10s 一次的 ping 事件,保持连接存活。
++
++ ### Errors
++ - 400,`invalid_param`,传入参数异常
++ - 400,`app_unavailable`,App 配置不可用
++ - 400,`provider_not_initialize`,无可用模型凭据配置
++ - 400,`provider_quota_exceeded`,模型调用额度不足
++ - 400,`model_currently_not_support`,当前模型不可用
++ - 400,`workflow_not_found`,指定的工作流版本未找到
++ - 400,`draft_workflow_error`,无法使用草稿工作流版本
++ - 400,`workflow_id_format_error`,工作流ID格式错误,需要UUID格式
++ - 400,`workflow_request_error`,workflow 执行失败
++ - 500,服务内部异常
++
++
++
++
++ ```bash {{ title: 'cURL' }}
++ curl -X POST '${props.appDetail.api_base_url}/workflows/{workflow_id}/run' \
++ --header 'Authorization: Bearer {api_key}' \
++ --header 'Content-Type: application/json' \
++ --data-raw '{
++ "inputs": {},
++ "response_mode": "streaming",
++ "user": "abc-123"
++ }'
++ ```
++
++
++ ```json {{ title: 'File variable example' }}
++ {
++ "inputs": {
++ "{variable_name}":
++ [
++ {
++ "transfer_method": "local_file",
++ "upload_file_id": "{upload_file_id}",
++ "type": "{document_type}"
++ }
++ ]
++ }
++ }
++ ```
++
++ ### Blocking Mode
++
++ ```json {{ title: 'Response' }}
++ {
++ "workflow_run_id": "djflajgkldjgd",
++ "task_id": "9da23599-e713-473b-982c-4328d4f5c78a",
++ "data": {
++ "id": "fdlsjfjejkghjda",
++ "workflow_id": "fldjaslkfjlsda",
++ "status": "succeeded",
++ "outputs": {
++ "text": "Nice to meet you."
++ },
++ "error": null,
++ "elapsed_time": 0.875,
++ "total_tokens": 3562,
++ "total_steps": 8,
++ "created_at": 1705407629,
++ "finished_at": 1727807631
++ }
++ }
++ ```
++
++ ### Streaming Mode
++
++ ```streaming {{ title: 'Response' }}
++ data: {"event": "workflow_started", "task_id": "5ad4cb98-f0c7-4085-b384-88c403be6290", "workflow_run_id": "5ad498-f0c7-4085-b384-88cbe6290", "data": {"id": "5ad498-f0c7-4085-b384-88cbe6290", "workflow_id": "dfjasklfjdslag", "created_at": 1679586595}}
++ data: {"event": "node_started", "task_id": "5ad4cb98-f0c7-4085-b384-88c403be6290", "workflow_run_id": "5ad498-f0c7-4085-b384-88cbe6290", "data": {"id": "5ad498-f0c7-4085-b384-88cbe6290", "node_id": "dfjasklfjdslag", "node_type": "start", "title": "Start", "index": 0, "predecessor_node_id": "fdljewklfklgejlglsd", "inputs": {}, "created_at": 1679586595}}
++ data: {"event": "node_finished", "task_id": "5ad4cb98-f0c7-4085-b384-88c403be6290", "workflow_run_id": "5ad498-f0c7-4085-b384-88cbe6290", "data": {"id": "5ad498-f0c7-4085-b384-88cbe6290", "node_id": "dfjasklfjdslag", "node_type": "start", "title": "Start", "index": 0, "predecessor_node_id": "fdljewklfklgejlglsd", "inputs": {}, "outputs": {}, "status": "succeeded", "elapsed_time": 0.324, "execution_metadata": {"total_tokens": 63127864, "total_price": 2.378, "currency": "USD"}, "created_at": 1679586595}}
++ data: {"event": "workflow_finished", "task_id": "5ad4cb98-f0c7-4085-b384-88c403be6290", "workflow_run_id": "5ad498-f0c7-4085-b384-88cbe6290", "data": {"id": "5ad498-f0c7-4085-b384-88cbe6290", "workflow_id": "dfjasklfjdslag", "outputs": {}, "status": "succeeded", "elapsed_time": 0.324, "total_tokens": 63127864, "total_steps": "1", "created_at": 1679586595, "finished_at": 1679976595}}
++ data: {"event": "tts_message", "conversation_id": "23dd85f3-1a41-4ea0-b7a9-062734ccfaf9", "message_id": "a8bdc41c-13b2-4c18-bfd9-054b9803038c", "created_at": 1721205487, "task_id": "3bf8a0bb-e73b-4690-9e66-4e429bad8ee7", "audio": "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq"}
++ data: {"event": "tts_message_end", "conversation_id": "23dd85f3-1a41-4ea0-b7a9-062734ccfaf9", "message_id": "a8bdc41c-13b2-4c18-bfd9-054b9803038c", "created_at": 1721205487, "task_id": "3bf8a0bb-e73b-4690-9e66-4e429bad8ee7", "audio": ""}
++ ```
++
++
++
++
++---
++
+
+ ---
+
++
++
++
++ 预览或下载已上传的文件。此端点允许您访问先前通过文件上传 API 上传的文件。
++
++ 文件只能在属于请求应用程序的消息范围内访问。
++
++ ### 路径参数
++ - `file_id` (string) 必需
++ 要预览的文件的唯一标识符,从文件上传 API 响应中获得。
++
++ ### 查询参数
++ - `as_attachment` (boolean) 可选
++ 是否强制将文件作为附件下载。默认为 `false`(在浏览器中预览)。
++
++ ### 响应
++ 返回带有适当浏览器显示或下载标头的文件内容。
++ - `Content-Type` 根据文件 MIME 类型设置
++ - `Content-Length` 文件大小(以字节为单位,如果可用)
++ - `Content-Disposition` 如果 `as_attachment=true` 则设置为 "attachment"
++ - `Cache-Control` 用于性能的缓存标头
++ - `Accept-Ranges` 对于音频/视频文件设置为 "bytes"
++
++ ### 错误
++ - 400, `invalid_param`, 参数输入异常
++ - 403, `file_access_denied`, 文件访问被拒绝或文件不属于当前应用程序
++ - 404, `file_not_found`, 文件未找到或已被删除
++ - 500, 服务内部错误
++
++
++
++ ### 请求示例
++
++
++ ```bash {{ title: 'cURL' }}
++ curl -X GET '${props.appDetail.api_base_url}/files/72fa9618-8f89-4a37-9b33-7e1178a24a67/preview' \
++ --header 'Authorization: Bearer {api_key}'
++ ```
++
++
++
++ ### 作为附件下载
++
++
++ ```bash {{ title: 'cURL' }}
++ curl -X GET '${props.appDetail.api_base_url}/files/72fa9618-8f89-4a37-9b33-7e1178a24a67/preview?as_attachment=true' \
++ --header 'Authorization: Bearer {api_key}' \
++ --output downloaded_file.png
++ ```
++
++
++
++ ### 响应标头示例
++
++ ```http {{ title: 'Headers - 图片预览' }}
++ Content-Type: image/png
++ Content-Length: 1024
++ Cache-Control: public, max-age=3600
++ ```
++
++
++ ### 文件下载响应标头
++
++ ```http {{ title: 'Headers - 文件下载' }}
++ Content-Type: image/png
++ Content-Length: 1024
++ Content-Disposition: attachment; filename*=UTF-8''example.png
++ Cache-Control: public, max-age=3600
++ ```
++
++
++
++---
++
+ typing.Iterator[ChunkChatCompletionResponse]:
@@ -108,6 +112,9 @@ def send_chat_message_by_app_advanced_chat(
auto_generate_name : typing.Optional[bool]
(Optional) Automatically generate title, default `true`. If set to `false`, you can call the conversation rename interface and set `auto_generate` to `true` to generate a title asynchronously.
+ workflow_id : typing.Optional[str]
+ (Optional) Workflow ID for specifying a specific version. If not provided, the default published version will be used.
+
trace_id : typing.Optional[str]
(Optional) Trace ID. Suitable for integrating with existing trace components in business systems to achieve end-to-end distributed tracing scenarios. If not specified, the system will automatically generate a trace_id. Three methods are supported with the following priority order: Header: Pass through HTTP Header X-Trace-Id, highest priority. Query parameter: Pass through URL query parameter trace_id. Request Body: Pass through request body field trace_id (this field).
@@ -135,6 +142,7 @@ def send_chat_message_by_app_advanced_chat(
conversation_id=conversation_id,
files=files,
auto_generate_name=auto_generate_name,
+ workflow_id=workflow_id,
trace_id=trace_id,
request_options=request_options,
) as r:
@@ -212,6 +220,38 @@ def upload_file_by_app_advanced_chat(
)
return _response.data
+ def preview_file_by_app_advanced_chat(
+ self,
+ file_id: str,
+ *,
+ as_attachment: typing.Optional[bool] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> typing.Iterator[bytes]:
+ """
+ Preview or download uploaded files. This endpoint allows you to access files previously uploaded through the file upload API.
+ Files can only be accessed within the message scope belonging to the requesting application.
+
+ Parameters
+ ----------
+ file_id : str
+ Unique identifier of the file to preview, obtained from the file upload API response.
+
+ as_attachment : typing.Optional[bool]
+ Whether to force download the file as an attachment. Default is false (preview in browser).
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration. You can pass in configuration such as `chunk_size`, and more to customize the request and response.
+
+ Returns
+ -------
+ typing.Iterator[bytes]
+ File content
+ """
+ with self._raw_client.preview_file_by_app_advanced_chat(
+ file_id, as_attachment=as_attachment, request_options=request_options
+ ) as r:
+ yield from r.data
+
def convert_audio_to_text_by_app_advanced_chat(
self,
*,
@@ -666,6 +706,51 @@ def get_conversation_variables_by_app_advanced_chat(
)
return _response.data
+ def update_conversation_variable_by_app_advanced_chat(
+ self,
+ conversation_id: str,
+ variable_id: str,
+ *,
+ user: str,
+ value: typing.Optional[typing.Any] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> UpdateConversationVariableByAppAdvancedChatResponse:
+ """
+ Update the value of a specific conversation variable. This endpoint allows you to modify variable values captured during conversations while preserving their name, type, and description.
+
+ Parameters
+ ----------
+ conversation_id : str
+ The conversation ID containing the variable to update.
+
+ variable_id : str
+ The ID of the variable to update.
+
+ user : str
+ User identifier, defined by developer rules, must be unique within the application.
+
+ value : typing.Optional[typing.Any]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ UpdateConversationVariableByAppAdvancedChatResponse
+ Successful response
+
+ Examples
+ --------
+ from dify import DifyApi
+ client = DifyApi(token="YOUR_TOKEN", )
+ client.advanced_chat.update_conversation_variable_by_app_advanced_chat(conversation_id='conversation_id', variable_id='variable_id', value={'key': 'value'}
+ , user='user', )
+ """
+ _response = self._raw_client.update_conversation_variable_by_app_advanced_chat(
+ conversation_id, variable_id, user=user, value=value, request_options=request_options
+ )
+ return _response.data
+
def get_app_meta_info_by_app_advanced_chat(
self, *, request_options: typing.Optional[RequestOptions] = None
) -> GetAppMetaInfoByAppAdvancedChatResponse:
@@ -963,6 +1048,7 @@ async def send_chat_message_by_app_advanced_chat(
conversation_id: typing.Optional[str] = OMIT,
files: typing.Optional[typing.Sequence[FileInput]] = OMIT,
auto_generate_name: typing.Optional[bool] = OMIT,
+ workflow_id: typing.Optional[str] = OMIT,
trace_id: typing.Optional[str] = OMIT,
request_options: typing.Optional[RequestOptions] = None,
) -> typing.AsyncIterator[ChunkChatCompletionResponse]:
@@ -994,6 +1080,9 @@ async def send_chat_message_by_app_advanced_chat(
auto_generate_name : typing.Optional[bool]
(Optional) Automatically generate title, default `true`. If set to `false`, you can call the conversation rename interface and set `auto_generate` to `true` to generate a title asynchronously.
+ workflow_id : typing.Optional[str]
+ (Optional) Workflow ID for specifying a specific version. If not provided, the default published version will be used.
+
trace_id : typing.Optional[str]
(Optional) Trace ID. Suitable for integrating with existing trace components in business systems to achieve end-to-end distributed tracing scenarios. If not specified, the system will automatically generate a trace_id. Three methods are supported with the following priority order: Header: Pass through HTTP Header X-Trace-Id, highest priority. Query parameter: Pass through URL query parameter trace_id. Request Body: Pass through request body field trace_id (this field).
@@ -1024,6 +1113,7 @@ async def main() -> None:
conversation_id=conversation_id,
files=files,
auto_generate_name=auto_generate_name,
+ workflow_id=workflow_id,
trace_id=trace_id,
request_options=request_options,
) as r:
@@ -1108,6 +1198,39 @@ async def main() -> None:
)
return _response.data
+ async def preview_file_by_app_advanced_chat(
+ self,
+ file_id: str,
+ *,
+ as_attachment: typing.Optional[bool] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> typing.AsyncIterator[bytes]:
+ """
+ Preview or download uploaded files. This endpoint allows you to access files previously uploaded through the file upload API.
+ Files can only be accessed within the message scope belonging to the requesting application.
+
+ Parameters
+ ----------
+ file_id : str
+ Unique identifier of the file to preview, obtained from the file upload API response.
+
+ as_attachment : typing.Optional[bool]
+ Whether to force download the file as an attachment. Default is false (preview in browser).
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration. You can pass in configuration such as `chunk_size`, and more to customize the request and response.
+
+ Returns
+ -------
+ typing.AsyncIterator[bytes]
+ File content
+ """
+ async with self._raw_client.preview_file_by_app_advanced_chat(
+ file_id, as_attachment=as_attachment, request_options=request_options
+ ) as r:
+ async for data in r.data:
+ yield data
+
async def convert_audio_to_text_by_app_advanced_chat(
self,
*,
@@ -1598,6 +1721,54 @@ async def main() -> None:
)
return _response.data
+ async def update_conversation_variable_by_app_advanced_chat(
+ self,
+ conversation_id: str,
+ variable_id: str,
+ *,
+ user: str,
+ value: typing.Optional[typing.Any] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> UpdateConversationVariableByAppAdvancedChatResponse:
+ """
+ Update the value of a specific conversation variable. This endpoint allows you to modify variable values captured during conversations while preserving their name, type, and description.
+
+ Parameters
+ ----------
+ conversation_id : str
+ The conversation ID containing the variable to update.
+
+ variable_id : str
+ The ID of the variable to update.
+
+ user : str
+ User identifier, defined by developer rules, must be unique within the application.
+
+ value : typing.Optional[typing.Any]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ UpdateConversationVariableByAppAdvancedChatResponse
+ Successful response
+
+ Examples
+ --------
+ from dify import AsyncDifyApi
+ import asyncio
+ client = AsyncDifyApi(token="YOUR_TOKEN", )
+ async def main() -> None:
+ await client.advanced_chat.update_conversation_variable_by_app_advanced_chat(conversation_id='conversation_id', variable_id='variable_id', value={'key': 'value'}
+ , user='user', )
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.update_conversation_variable_by_app_advanced_chat(
+ conversation_id, variable_id, user=user, value=value, request_options=request_options
+ )
+ return _response.data
+
async def get_app_meta_info_by_app_advanced_chat(
self, *, request_options: typing.Optional[RequestOptions] = None
) -> GetAppMetaInfoByAppAdvancedChatResponse:
diff --git a/src/dify_sdk/advanced_chat/errors/__init__.py b/src/dify_sdk/advanced_chat/errors/__init__.py
index 635aad6..37b13b9 100644
--- a/src/dify_sdk/advanced_chat/errors/__init__.py
+++ b/src/dify_sdk/advanced_chat/errors/__init__.py
@@ -4,6 +4,7 @@
from .bad_request_error import BadRequestError
from .content_too_large_error import ContentTooLargeError
+from .forbidden_error import ForbiddenError
from .internal_server_error import InternalServerError
from .not_found_error import NotFoundError
from .service_unavailable_error import ServiceUnavailableError
@@ -12,6 +13,7 @@
__all__ = [
"BadRequestError",
"ContentTooLargeError",
+ "ForbiddenError",
"InternalServerError",
"NotFoundError",
"ServiceUnavailableError",
diff --git a/src/dify_sdk/advanced_chat/errors/bad_request_error.py b/src/dify_sdk/advanced_chat/errors/bad_request_error.py
index 5ccb07c..c1e658e 100644
--- a/src/dify_sdk/advanced_chat/errors/bad_request_error.py
+++ b/src/dify_sdk/advanced_chat/errors/bad_request_error.py
@@ -1,9 +1,10 @@
# This file was auto-generated by Fern from our API Definition.
+import typing
+
from ...core.api_error import ApiError
-from ..types.error import Error
class BadRequestError(ApiError):
- def __init__(self, body: Error):
+ def __init__(self, body: typing.Optional[typing.Any]):
super().__init__(status_code=400, body=body)
diff --git a/src/dify_sdk/advanced_chat/errors/forbidden_error.py b/src/dify_sdk/advanced_chat/errors/forbidden_error.py
new file mode 100644
index 0000000..674d6b9
--- /dev/null
+++ b/src/dify_sdk/advanced_chat/errors/forbidden_error.py
@@ -0,0 +1,10 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from ...core.api_error import ApiError
+
+
+class ForbiddenError(ApiError):
+ def __init__(self, body: typing.Optional[typing.Any]):
+ super().__init__(status_code=403, body=body)
diff --git a/src/dify_sdk/advanced_chat/raw_client.py b/src/dify_sdk/advanced_chat/raw_client.py
index 58ee2a1..d98aadf 100644
--- a/src/dify_sdk/advanced_chat/raw_client.py
+++ b/src/dify_sdk/advanced_chat/raw_client.py
@@ -15,6 +15,7 @@
from ..core.serialization import convert_and_respect_annotation_metadata
from .errors.bad_request_error import BadRequestError
from .errors.content_too_large_error import ContentTooLargeError
+from .errors.forbidden_error import ForbiddenError
from .errors.internal_server_error import InternalServerError
from .errors.not_found_error import NotFoundError
from .errors.service_unavailable_error import ServiceUnavailableError
@@ -60,6 +61,9 @@
from .types.send_message_feedback_by_app_advanced_chat_response import SendMessageFeedbackByAppAdvancedChatResponse
from .types.stop_chat_response_by_app_advanced_chat_response import StopChatResponseByAppAdvancedChatResponse
from .types.update_annotation_by_app_advanced_chat_response import UpdateAnnotationByAppAdvancedChatResponse
+from .types.update_conversation_variable_by_app_advanced_chat_response import (
+ UpdateConversationVariableByAppAdvancedChatResponse,
+)
from .types.uploaded_file import UploadedFile
# this is used as the default value for optional parameters
@@ -81,6 +85,7 @@ def send_chat_message_by_app_advanced_chat(
conversation_id: typing.Optional[str] = OMIT,
files: typing.Optional[typing.Sequence[FileInput]] = OMIT,
auto_generate_name: typing.Optional[bool] = OMIT,
+ workflow_id: typing.Optional[str] = OMIT,
trace_id: typing.Optional[str] = OMIT,
request_options: typing.Optional[RequestOptions] = None,
) -> typing.Iterator[HttpResponse[typing.Iterator[ChunkChatCompletionResponse]]]:
@@ -112,6 +117,9 @@ def send_chat_message_by_app_advanced_chat(
auto_generate_name : typing.Optional[bool]
(Optional) Automatically generate title, default `true`. If set to `false`, you can call the conversation rename interface and set `auto_generate` to `true` to generate a title asynchronously.
+ workflow_id : typing.Optional[str]
+ (Optional) Workflow ID for specifying a specific version. If not provided, the default published version will be used.
+
trace_id : typing.Optional[str]
(Optional) Trace ID. Suitable for integrating with existing trace components in business systems to achieve end-to-end distributed tracing scenarios. If not specified, the system will automatically generate a trace_id. Three methods are supported with the following priority order: Header: Pass through HTTP Header X-Trace-Id, highest priority. Query parameter: Pass through URL query parameter trace_id. Request Body: Pass through request body field trace_id (this field).
@@ -136,6 +144,7 @@ def send_chat_message_by_app_advanced_chat(
object_=files, annotation=typing.Sequence[FileInput], direction="write"
),
"auto_generate_name": auto_generate_name,
+ "workflow_id": workflow_id,
"trace_id": trace_id,
},
headers={
@@ -165,9 +174,9 @@ def _iter():
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -306,9 +315,9 @@ def upload_file_by_app_advanced_chat(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -348,6 +357,100 @@ def upload_file_by_app_advanced_chat(
raise ApiError(headers=dict(_response.headers), status_code=_response.status_code, body=_response.text)
raise ApiError(headers=dict(_response.headers), status_code=_response.status_code, body=_response_json)
+ @contextlib.contextmanager
+ def preview_file_by_app_advanced_chat(
+ self,
+ file_id: str,
+ *,
+ as_attachment: typing.Optional[bool] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> typing.Iterator[HttpResponse[typing.Iterator[bytes]]]:
+ """
+ Preview or download uploaded files. This endpoint allows you to access files previously uploaded through the file upload API.
+ Files can only be accessed within the message scope belonging to the requesting application.
+
+ Parameters
+ ----------
+ file_id : str
+ Unique identifier of the file to preview, obtained from the file upload API response.
+
+ as_attachment : typing.Optional[bool]
+ Whether to force download the file as an attachment. Default is false (preview in browser).
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration. You can pass in configuration such as `chunk_size`, and more to customize the request and response.
+
+ Returns
+ -------
+ typing.Iterator[HttpResponse[typing.Iterator[bytes]]]
+ File content
+ """
+ with self._client_wrapper.httpx_client.stream(
+ f"files/{jsonable_encoder(file_id)}/preview",
+ method="GET",
+ params={
+ "as_attachment": as_attachment,
+ },
+ request_options=request_options,
+ ) as _response:
+
+ def stream() -> HttpResponse[typing.Iterator[bytes]]:
+ try:
+ if 200 <= _response.status_code < 300:
+ _chunk_size = request_options.get("chunk_size", None) if request_options is not None else None
+ return HttpResponse(
+ response=_response, data=(_chunk for _chunk in _response.iter_bytes(chunk_size=_chunk_size))
+ )
+ _response.read()
+ if _response.status_code == 400:
+ raise BadRequestError(
+ typing.cast(
+ typing.Optional[typing.Any],
+ parse_obj_as(
+ type_=typing.Optional[typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ if _response.status_code == 403:
+ raise ForbiddenError(
+ typing.cast(
+ typing.Optional[typing.Any],
+ parse_obj_as(
+ type_=typing.Optional[typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ if _response.status_code == 404:
+ raise NotFoundError(
+ typing.cast(
+ typing.Optional[typing.Any],
+ parse_obj_as(
+ type_=typing.Optional[typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ if _response.status_code == 500:
+ raise InternalServerError(
+ typing.cast(
+ Error,
+ parse_obj_as(
+ type_=Error, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(
+ headers=dict(_response.headers), status_code=_response.status_code, body=_response.text
+ )
+ raise ApiError(headers=dict(_response.headers), status_code=_response.status_code, body=_response_json)
+
+ yield stream()
+
def convert_audio_to_text_by_app_advanced_chat(
self,
*,
@@ -991,6 +1094,87 @@ def get_conversation_variables_by_app_advanced_chat(
raise ApiError(headers=dict(_response.headers), status_code=_response.status_code, body=_response.text)
raise ApiError(headers=dict(_response.headers), status_code=_response.status_code, body=_response_json)
+ def update_conversation_variable_by_app_advanced_chat(
+ self,
+ conversation_id: str,
+ variable_id: str,
+ *,
+ user: str,
+ value: typing.Optional[typing.Any] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[UpdateConversationVariableByAppAdvancedChatResponse]:
+ """
+ Update the value of a specific conversation variable. This endpoint allows you to modify variable values captured during conversations while preserving their name, type, and description.
+
+ Parameters
+ ----------
+ conversation_id : str
+ The conversation ID containing the variable to update.
+
+ variable_id : str
+ The ID of the variable to update.
+
+ user : str
+ User identifier, defined by developer rules, must be unique within the application.
+
+ value : typing.Optional[typing.Any]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[UpdateConversationVariableByAppAdvancedChatResponse]
+ Successful response
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"conversations/{jsonable_encoder(conversation_id)}/variables/{jsonable_encoder(variable_id)}",
+ method="PUT",
+ json={
+ "value": value,
+ "user": user,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ UpdateConversationVariableByAppAdvancedChatResponse,
+ parse_obj_as(
+ type_=UpdateConversationVariableByAppAdvancedChatResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 400:
+ raise BadRequestError(
+ typing.cast(
+ typing.Optional[typing.Any],
+ parse_obj_as(
+ type_=typing.Optional[typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ if _response.status_code == 404:
+ raise NotFoundError(
+ typing.cast(
+ typing.Optional[typing.Any],
+ parse_obj_as(
+ type_=typing.Optional[typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(headers=dict(_response.headers), status_code=_response.status_code, body=_response.text)
+ raise ApiError(headers=dict(_response.headers), status_code=_response.status_code, body=_response_json)
+
def get_app_meta_info_by_app_advanced_chat(
self, *, request_options: typing.Optional[RequestOptions] = None
) -> HttpResponse[GetAppMetaInfoByAppAdvancedChatResponse]:
@@ -1372,6 +1556,7 @@ async def send_chat_message_by_app_advanced_chat(
conversation_id: typing.Optional[str] = OMIT,
files: typing.Optional[typing.Sequence[FileInput]] = OMIT,
auto_generate_name: typing.Optional[bool] = OMIT,
+ workflow_id: typing.Optional[str] = OMIT,
trace_id: typing.Optional[str] = OMIT,
request_options: typing.Optional[RequestOptions] = None,
) -> typing.AsyncIterator[AsyncHttpResponse[typing.AsyncIterator[ChunkChatCompletionResponse]]]:
@@ -1403,6 +1588,9 @@ async def send_chat_message_by_app_advanced_chat(
auto_generate_name : typing.Optional[bool]
(Optional) Automatically generate title, default `true`. If set to `false`, you can call the conversation rename interface and set `auto_generate` to `true` to generate a title asynchronously.
+ workflow_id : typing.Optional[str]
+ (Optional) Workflow ID for specifying a specific version. If not provided, the default published version will be used.
+
trace_id : typing.Optional[str]
(Optional) Trace ID. Suitable for integrating with existing trace components in business systems to achieve end-to-end distributed tracing scenarios. If not specified, the system will automatically generate a trace_id. Three methods are supported with the following priority order: Header: Pass through HTTP Header X-Trace-Id, highest priority. Query parameter: Pass through URL query parameter trace_id. Request Body: Pass through request body field trace_id (this field).
@@ -1427,6 +1615,7 @@ async def send_chat_message_by_app_advanced_chat(
object_=files, annotation=typing.Sequence[FileInput], direction="write"
),
"auto_generate_name": auto_generate_name,
+ "workflow_id": workflow_id,
"trace_id": trace_id,
},
headers={
@@ -1456,9 +1645,9 @@ async def _iter():
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -1597,9 +1786,9 @@ async def upload_file_by_app_advanced_chat(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -1639,6 +1828,101 @@ async def upload_file_by_app_advanced_chat(
raise ApiError(headers=dict(_response.headers), status_code=_response.status_code, body=_response.text)
raise ApiError(headers=dict(_response.headers), status_code=_response.status_code, body=_response_json)
+ @contextlib.asynccontextmanager
+ async def preview_file_by_app_advanced_chat(
+ self,
+ file_id: str,
+ *,
+ as_attachment: typing.Optional[bool] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> typing.AsyncIterator[AsyncHttpResponse[typing.AsyncIterator[bytes]]]:
+ """
+ Preview or download uploaded files. This endpoint allows you to access files previously uploaded through the file upload API.
+ Files can only be accessed within the message scope belonging to the requesting application.
+
+ Parameters
+ ----------
+ file_id : str
+ Unique identifier of the file to preview, obtained from the file upload API response.
+
+ as_attachment : typing.Optional[bool]
+ Whether to force download the file as an attachment. Default is false (preview in browser).
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration. You can pass in configuration such as `chunk_size`, and more to customize the request and response.
+
+ Returns
+ -------
+ typing.AsyncIterator[AsyncHttpResponse[typing.AsyncIterator[bytes]]]
+ File content
+ """
+ async with self._client_wrapper.httpx_client.stream(
+ f"files/{jsonable_encoder(file_id)}/preview",
+ method="GET",
+ params={
+ "as_attachment": as_attachment,
+ },
+ request_options=request_options,
+ ) as _response:
+
+ async def stream() -> AsyncHttpResponse[typing.AsyncIterator[bytes]]:
+ try:
+ if 200 <= _response.status_code < 300:
+ _chunk_size = request_options.get("chunk_size", None) if request_options is not None else None
+ return AsyncHttpResponse(
+ response=_response,
+ data=(_chunk async for _chunk in _response.aiter_bytes(chunk_size=_chunk_size)),
+ )
+ await _response.aread()
+ if _response.status_code == 400:
+ raise BadRequestError(
+ typing.cast(
+ typing.Optional[typing.Any],
+ parse_obj_as(
+ type_=typing.Optional[typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ if _response.status_code == 403:
+ raise ForbiddenError(
+ typing.cast(
+ typing.Optional[typing.Any],
+ parse_obj_as(
+ type_=typing.Optional[typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ if _response.status_code == 404:
+ raise NotFoundError(
+ typing.cast(
+ typing.Optional[typing.Any],
+ parse_obj_as(
+ type_=typing.Optional[typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ if _response.status_code == 500:
+ raise InternalServerError(
+ typing.cast(
+ Error,
+ parse_obj_as(
+ type_=Error, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(
+ headers=dict(_response.headers), status_code=_response.status_code, body=_response.text
+ )
+ raise ApiError(headers=dict(_response.headers), status_code=_response.status_code, body=_response_json)
+
+ yield await stream()
+
async def convert_audio_to_text_by_app_advanced_chat(
self,
*,
@@ -2283,6 +2567,87 @@ async def get_conversation_variables_by_app_advanced_chat(
raise ApiError(headers=dict(_response.headers), status_code=_response.status_code, body=_response.text)
raise ApiError(headers=dict(_response.headers), status_code=_response.status_code, body=_response_json)
+ async def update_conversation_variable_by_app_advanced_chat(
+ self,
+ conversation_id: str,
+ variable_id: str,
+ *,
+ user: str,
+ value: typing.Optional[typing.Any] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[UpdateConversationVariableByAppAdvancedChatResponse]:
+ """
+ Update the value of a specific conversation variable. This endpoint allows you to modify variable values captured during conversations while preserving their name, type, and description.
+
+ Parameters
+ ----------
+ conversation_id : str
+ The conversation ID containing the variable to update.
+
+ variable_id : str
+ The ID of the variable to update.
+
+ user : str
+ User identifier, defined by developer rules, must be unique within the application.
+
+ value : typing.Optional[typing.Any]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[UpdateConversationVariableByAppAdvancedChatResponse]
+ Successful response
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"conversations/{jsonable_encoder(conversation_id)}/variables/{jsonable_encoder(variable_id)}",
+ method="PUT",
+ json={
+ "value": value,
+ "user": user,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ UpdateConversationVariableByAppAdvancedChatResponse,
+ parse_obj_as(
+ type_=UpdateConversationVariableByAppAdvancedChatResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 400:
+ raise BadRequestError(
+ typing.cast(
+ typing.Optional[typing.Any],
+ parse_obj_as(
+ type_=typing.Optional[typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ if _response.status_code == 404:
+ raise NotFoundError(
+ typing.cast(
+ typing.Optional[typing.Any],
+ parse_obj_as(
+ type_=typing.Optional[typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(headers=dict(_response.headers), status_code=_response.status_code, body=_response.text)
+ raise ApiError(headers=dict(_response.headers), status_code=_response.status_code, body=_response_json)
+
async def get_app_meta_info_by_app_advanced_chat(
self, *, request_options: typing.Optional[RequestOptions] = None
) -> AsyncHttpResponse[GetAppMetaInfoByAppAdvancedChatResponse]:
diff --git a/src/dify_sdk/advanced_chat/types/__init__.py b/src/dify_sdk/advanced_chat/types/__init__.py
index 67e5e40..37002f8 100644
--- a/src/dify_sdk/advanced_chat/types/__init__.py
+++ b/src/dify_sdk/advanced_chat/types/__init__.py
@@ -2,6 +2,7 @@
# isort: skip_file
+from .bad_request_error_body import BadRequestErrorBody
from .chat_completion_response import ChatCompletionResponse
from .chat_completion_response_metadata import ChatCompletionResponseMetadata
from .chunk_chat_completion_response import ChunkChatCompletionResponse
@@ -122,6 +123,7 @@
from .get_conversations_by_app_advanced_chat_response_data_item import GetConversationsByAppAdvancedChatResponseDataItem
from .get_suggested_questions_by_app_advanced_chat_response import GetSuggestedQuestionsByAppAdvancedChatResponse
from .not_found_error_body import NotFoundErrorBody
+from .not_found_error_body_code import NotFoundErrorBodyCode
from .rename_conversation_by_app_advanced_chat_response import RenameConversationByAppAdvancedChatResponse
from .retriever_resource import RetrieverResource
from .send_chat_message_by_app_advanced_chat_request_response_mode import (
@@ -130,10 +132,14 @@
from .send_message_feedback_by_app_advanced_chat_response import SendMessageFeedbackByAppAdvancedChatResponse
from .stop_chat_response_by_app_advanced_chat_response import StopChatResponseByAppAdvancedChatResponse
from .update_annotation_by_app_advanced_chat_response import UpdateAnnotationByAppAdvancedChatResponse
+from .update_conversation_variable_by_app_advanced_chat_response import (
+ UpdateConversationVariableByAppAdvancedChatResponse,
+)
from .uploaded_file import UploadedFile
from .usage import Usage
__all__ = [
+ "BadRequestErrorBody",
"ChatCompletionResponse",
"ChatCompletionResponseMetadata",
"ChunkChatCompletionResponse",
@@ -192,12 +198,14 @@
"GetConversationsByAppAdvancedChatResponseDataItem",
"GetSuggestedQuestionsByAppAdvancedChatResponse",
"NotFoundErrorBody",
+ "NotFoundErrorBodyCode",
"RenameConversationByAppAdvancedChatResponse",
"RetrieverResource",
"SendChatMessageByAppAdvancedChatRequestResponseMode",
"SendMessageFeedbackByAppAdvancedChatResponse",
"StopChatResponseByAppAdvancedChatResponse",
"UpdateAnnotationByAppAdvancedChatResponse",
+ "UpdateConversationVariableByAppAdvancedChatResponse",
"UploadedFile",
"Usage",
]
diff --git a/src/dify_sdk/advanced_chat/types/bad_request_error_body.py b/src/dify_sdk/advanced_chat/types/bad_request_error_body.py
new file mode 100644
index 0000000..5440d9b
--- /dev/null
+++ b/src/dify_sdk/advanced_chat/types/bad_request_error_body.py
@@ -0,0 +1,27 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ...core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class BadRequestErrorBody(UniversalBaseModel):
+ code: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Error code
+ """
+
+ message: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Error message
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/src/dify_sdk/advanced_chat/types/get_conversation_messages_by_app_advanced_chat_response_data_item_message_files_item.py b/src/dify_sdk/advanced_chat/types/get_conversation_messages_by_app_advanced_chat_response_data_item_message_files_item.py
index 8475cd9..73d2e73 100644
--- a/src/dify_sdk/advanced_chat/types/get_conversation_messages_by_app_advanced_chat_response_data_item_message_files_item.py
+++ b/src/dify_sdk/advanced_chat/types/get_conversation_messages_by_app_advanced_chat_response_data_item_message_files_item.py
@@ -22,7 +22,7 @@ class GetConversationMessagesByAppAdvancedChatResponseDataItemMessageFilesItem(U
url: typing.Optional[str] = pydantic.Field(default=None)
"""
- Preview image URL
+ File preview URL, access files using the file preview API (`/files/{file_id}/preview`)
"""
belongs_to: typing.Optional[GetConversationMessagesByAppAdvancedChatResponseDataItemMessageFilesItemBelongsTo] = (
diff --git a/src/dify_sdk/advanced_chat/types/not_found_error_body.py b/src/dify_sdk/advanced_chat/types/not_found_error_body.py
index b76f064..84e0522 100644
--- a/src/dify_sdk/advanced_chat/types/not_found_error_body.py
+++ b/src/dify_sdk/advanced_chat/types/not_found_error_body.py
@@ -4,10 +4,11 @@
import pydantic
from ...core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .not_found_error_body_code import NotFoundErrorBodyCode
class NotFoundErrorBody(UniversalBaseModel):
- code: typing.Optional[typing.Literal["conversation_not_exists"]] = pydantic.Field(default=None)
+ code: typing.Optional[NotFoundErrorBodyCode] = pydantic.Field(default=None)
"""
Error code
"""
diff --git a/src/dify_sdk/advanced_chat/types/not_found_error_body_code.py b/src/dify_sdk/advanced_chat/types/not_found_error_body_code.py
new file mode 100644
index 0000000..8161f38
--- /dev/null
+++ b/src/dify_sdk/advanced_chat/types/not_found_error_body_code.py
@@ -0,0 +1,7 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+NotFoundErrorBodyCode = typing.Union[
+ typing.Literal["conversation_not_exists", "conversation_variable_not_exists"], typing.Any
+]
diff --git a/src/dify_sdk/advanced_chat/types/update_conversation_variable_by_app_advanced_chat_response.py b/src/dify_sdk/advanced_chat/types/update_conversation_variable_by_app_advanced_chat_response.py
new file mode 100644
index 0000000..f12b8fa
--- /dev/null
+++ b/src/dify_sdk/advanced_chat/types/update_conversation_variable_by_app_advanced_chat_response.py
@@ -0,0 +1,48 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ...core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class UpdateConversationVariableByAppAdvancedChatResponse(UniversalBaseModel):
+ id: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Variable ID
+ """
+
+ name: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Variable name
+ """
+
+ value_type: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Variable type (string, number, object, etc.)
+ """
+
+ value: typing.Optional[typing.Optional[typing.Any]] = None
+ description: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Variable description
+ """
+
+ created_at: typing.Optional[int] = pydantic.Field(default=None)
+ """
+ Creation timestamp
+ """
+
+ updated_at: typing.Optional[int] = pydantic.Field(default=None)
+ """
+ Last update timestamp
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/src/dify_sdk/chat/__init__.py b/src/dify_sdk/chat/__init__.py
index 421b6a4..22b8a46 100644
--- a/src/dify_sdk/chat/__init__.py
+++ b/src/dify_sdk/chat/__init__.py
@@ -3,6 +3,8 @@
# isort: skip_file
from .types import (
+ BadRequestErrorBody,
+ BadRequestErrorBodyCode,
ChatCompletionResponse,
ChatCompletionResponseMetadata,
ChatHistoryMessage,
@@ -23,6 +25,7 @@
FileInput,
FileInputTransferMethod,
FileInputType,
+ ForbiddenErrorBody,
GetAnnotationReplyStatusByAppChatRequestAction,
GetAnnotationReplyStatusByAppChatResponse,
GetAnnotationsListByAppChatResponse,
@@ -60,6 +63,7 @@
GetConversationVariablesByAppChatResponseDataItem,
GetSuggestedQuestionsByAppChatResponse,
NotFoundErrorBody,
+ NotFoundErrorBodyCode,
RetrieverResource,
SendChatMessageByAppChatRequestFilesItem,
SendChatMessageByAppChatRequestFilesItemTransferMethod,
@@ -67,12 +71,14 @@
SendMessageFeedbackByAppChatResponse,
StopChatResponseByAppChatResponse,
UpdateAnnotationByAppChatResponse,
+ UpdateConversationVariableByAppChatResponse,
UploadedFile,
Usage,
)
from .errors import (
BadRequestError,
ContentTooLargeError,
+ ForbiddenError,
InternalServerError,
NotFoundError,
ServiceUnavailableError,
@@ -81,6 +87,8 @@
__all__ = [
"BadRequestError",
+ "BadRequestErrorBody",
+ "BadRequestErrorBodyCode",
"ChatCompletionResponse",
"ChatCompletionResponseMetadata",
"ChatHistoryMessage",
@@ -102,6 +110,8 @@
"FileInput",
"FileInputTransferMethod",
"FileInputType",
+ "ForbiddenError",
+ "ForbiddenErrorBody",
"GetAnnotationReplyStatusByAppChatRequestAction",
"GetAnnotationReplyStatusByAppChatResponse",
"GetAnnotationsListByAppChatResponse",
@@ -141,6 +151,7 @@
"InternalServerError",
"NotFoundError",
"NotFoundErrorBody",
+ "NotFoundErrorBodyCode",
"RetrieverResource",
"SendChatMessageByAppChatRequestFilesItem",
"SendChatMessageByAppChatRequestFilesItemTransferMethod",
@@ -150,6 +161,7 @@
"StopChatResponseByAppChatResponse",
"UnsupportedMediaTypeError",
"UpdateAnnotationByAppChatResponse",
+ "UpdateConversationVariableByAppChatResponse",
"UploadedFile",
"Usage",
]
diff --git a/src/dify_sdk/chat/client.py b/src/dify_sdk/chat/client.py
index 9d40c81..b75d022 100644
--- a/src/dify_sdk/chat/client.py
+++ b/src/dify_sdk/chat/client.py
@@ -31,6 +31,7 @@
from .types.send_message_feedback_by_app_chat_response import SendMessageFeedbackByAppChatResponse
from .types.stop_chat_response_by_app_chat_response import StopChatResponseByAppChatResponse
from .types.update_annotation_by_app_chat_response import UpdateAnnotationByAppChatResponse
+from .types.update_conversation_variable_by_app_chat_response import UpdateConversationVariableByAppChatResponse
from .types.uploaded_file import UploadedFile
# this is used as the default value for optional parameters
@@ -62,6 +63,7 @@ def send_chat_message_by_app_chat(
conversation_id: typing.Optional[str] = OMIT,
files: typing.Optional[typing.Sequence[SendChatMessageByAppChatRequestFilesItem]] = OMIT,
auto_generate_name: typing.Optional[bool] = OMIT,
+ workflow_id: typing.Optional[str] = OMIT,
trace_id: typing.Optional[str] = OMIT,
request_options: typing.Optional[RequestOptions] = None,
) -> typing.Iterator[ChunkChatCompletionResponse]:
@@ -94,6 +96,9 @@ def send_chat_message_by_app_chat(
auto_generate_name : typing.Optional[bool]
(Optional) Whether to automatically generate title, default is true. If set to false, you can call the conversation rename interface and set auto_generate to true to generate a title asynchronously.
+ workflow_id : typing.Optional[str]
+ (Optional) Workflow ID, used to specify a specific version. If not provided, the default published version will be used.
+
trace_id : typing.Optional[str]
(Optional) Trace ID for linking with existing trace components in business systems, enabling end-to-end distributed tracing scenarios. If not specified, the system will automatically generate a trace_id. Supports the following three transmission methods, in order of priority:
- Header: Passed through HTTP Header X-Trace-Id, highest priority.
@@ -124,11 +129,44 @@ def send_chat_message_by_app_chat(
conversation_id=conversation_id,
files=files,
auto_generate_name=auto_generate_name,
+ workflow_id=workflow_id,
trace_id=trace_id,
request_options=request_options,
) as r:
yield from r.data
+ def preview_file_by_app_chat(
+ self,
+ file_id: str,
+ *,
+ as_attachment: typing.Optional[bool] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> typing.Iterator[bytes]:
+ """
+ Preview or download uploaded files. This endpoint allows you to access files previously uploaded through the file upload API.
+ Files can only be accessed within the message scope belonging to the requesting application.
+
+ Parameters
+ ----------
+ file_id : str
+ Unique identifier of the file to preview, obtained from the file upload API response
+
+ as_attachment : typing.Optional[bool]
+ Whether to force the file to be downloaded as an attachment. Default is false (preview in browser)
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration. You can pass in configuration such as `chunk_size`, and more to customize the request and response.
+
+ Returns
+ -------
+ typing.Iterator[bytes]
+ File content
+ """
+ with self._raw_client.preview_file_by_app_chat(
+ file_id, as_attachment=as_attachment, request_options=request_options
+ ) as r:
+ yield from r.data
+
def get_conversation_list_by_app_chat(
self,
*,
@@ -291,6 +329,51 @@ def get_conversation_variables_by_app_chat(
)
return _response.data
+ def update_conversation_variable_by_app_chat(
+ self,
+ conversation_id: str,
+ variable_id: str,
+ *,
+ user: str,
+ value: typing.Optional[typing.Any] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> UpdateConversationVariableByAppChatResponse:
+ """
+ Update the value of a specific conversation variable. This endpoint allows you to modify variable values captured during conversations while preserving their names, types, and descriptions.
+
+ Parameters
+ ----------
+ conversation_id : str
+ ID of the conversation containing the variable to update
+
+ variable_id : str
+ ID of the variable to update
+
+ user : str
+ User identifier, defined by developer rules, must be unique within the application.
+
+ value : typing.Optional[typing.Any]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ UpdateConversationVariableByAppChatResponse
+ Successfully updated variable
+
+ Examples
+ --------
+ from dify import DifyApi
+ client = DifyApi(token="YOUR_TOKEN", )
+ client.chat.update_conversation_variable_by_app_chat(conversation_id='conversation_id', variable_id='variable_id', value={'key': 'value'}
+ , user='user', )
+ """
+ _response = self._raw_client.update_conversation_variable_by_app_chat(
+ conversation_id, variable_id, user=user, value=value, request_options=request_options
+ )
+ return _response.data
+
def get_conversation_messages_by_app_chat(
self,
*,
@@ -931,6 +1014,7 @@ async def send_chat_message_by_app_chat(
conversation_id: typing.Optional[str] = OMIT,
files: typing.Optional[typing.Sequence[SendChatMessageByAppChatRequestFilesItem]] = OMIT,
auto_generate_name: typing.Optional[bool] = OMIT,
+ workflow_id: typing.Optional[str] = OMIT,
trace_id: typing.Optional[str] = OMIT,
request_options: typing.Optional[RequestOptions] = None,
) -> typing.AsyncIterator[ChunkChatCompletionResponse]:
@@ -963,6 +1047,9 @@ async def send_chat_message_by_app_chat(
auto_generate_name : typing.Optional[bool]
(Optional) Whether to automatically generate title, default is true. If set to false, you can call the conversation rename interface and set auto_generate to true to generate a title asynchronously.
+ workflow_id : typing.Optional[str]
+ (Optional) Workflow ID, used to specify a specific version. If not provided, the default published version will be used.
+
trace_id : typing.Optional[str]
(Optional) Trace ID for linking with existing trace components in business systems, enabling end-to-end distributed tracing scenarios. If not specified, the system will automatically generate a trace_id. Supports the following three transmission methods, in order of priority:
- Header: Passed through HTTP Header X-Trace-Id, highest priority.
@@ -996,12 +1083,46 @@ async def main() -> None:
conversation_id=conversation_id,
files=files,
auto_generate_name=auto_generate_name,
+ workflow_id=workflow_id,
trace_id=trace_id,
request_options=request_options,
) as r:
async for data in r.data:
yield data
+ async def preview_file_by_app_chat(
+ self,
+ file_id: str,
+ *,
+ as_attachment: typing.Optional[bool] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> typing.AsyncIterator[bytes]:
+ """
+ Preview or download uploaded files. This endpoint allows you to access files previously uploaded through the file upload API.
+ Files can only be accessed within the message scope belonging to the requesting application.
+
+ Parameters
+ ----------
+ file_id : str
+ Unique identifier of the file to preview, obtained from the file upload API response
+
+ as_attachment : typing.Optional[bool]
+ Whether to force the file to be downloaded as an attachment. Default is false (preview in browser)
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration. You can pass in configuration such as `chunk_size`, and more to customize the request and response.
+
+ Returns
+ -------
+ typing.AsyncIterator[bytes]
+ File content
+ """
+ async with self._raw_client.preview_file_by_app_chat(
+ file_id, as_attachment=as_attachment, request_options=request_options
+ ) as r:
+ async for data in r.data:
+ yield data
+
async def get_conversation_list_by_app_chat(
self,
*,
@@ -1176,6 +1297,54 @@ async def main() -> None:
)
return _response.data
+ async def update_conversation_variable_by_app_chat(
+ self,
+ conversation_id: str,
+ variable_id: str,
+ *,
+ user: str,
+ value: typing.Optional[typing.Any] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> UpdateConversationVariableByAppChatResponse:
+ """
+ Update the value of a specific conversation variable. This endpoint allows you to modify variable values captured during conversations while preserving their names, types, and descriptions.
+
+ Parameters
+ ----------
+ conversation_id : str
+ ID of the conversation containing the variable to update
+
+ variable_id : str
+ ID of the variable to update
+
+ user : str
+ User identifier, defined by developer rules, must be unique within the application.
+
+ value : typing.Optional[typing.Any]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ UpdateConversationVariableByAppChatResponse
+ Successfully updated variable
+
+ Examples
+ --------
+ from dify import AsyncDifyApi
+ import asyncio
+ client = AsyncDifyApi(token="YOUR_TOKEN", )
+ async def main() -> None:
+ await client.chat.update_conversation_variable_by_app_chat(conversation_id='conversation_id', variable_id='variable_id', value={'key': 'value'}
+ , user='user', )
+ asyncio.run(main())
+ """
+ _response = await self._raw_client.update_conversation_variable_by_app_chat(
+ conversation_id, variable_id, user=user, value=value, request_options=request_options
+ )
+ return _response.data
+
async def get_conversation_messages_by_app_chat(
self,
*,
diff --git a/src/dify_sdk/chat/errors/__init__.py b/src/dify_sdk/chat/errors/__init__.py
index 635aad6..37b13b9 100644
--- a/src/dify_sdk/chat/errors/__init__.py
+++ b/src/dify_sdk/chat/errors/__init__.py
@@ -4,6 +4,7 @@
from .bad_request_error import BadRequestError
from .content_too_large_error import ContentTooLargeError
+from .forbidden_error import ForbiddenError
from .internal_server_error import InternalServerError
from .not_found_error import NotFoundError
from .service_unavailable_error import ServiceUnavailableError
@@ -12,6 +13,7 @@
__all__ = [
"BadRequestError",
"ContentTooLargeError",
+ "ForbiddenError",
"InternalServerError",
"NotFoundError",
"ServiceUnavailableError",
diff --git a/src/dify_sdk/chat/errors/bad_request_error.py b/src/dify_sdk/chat/errors/bad_request_error.py
index 5ccb07c..c1e658e 100644
--- a/src/dify_sdk/chat/errors/bad_request_error.py
+++ b/src/dify_sdk/chat/errors/bad_request_error.py
@@ -1,9 +1,10 @@
# This file was auto-generated by Fern from our API Definition.
+import typing
+
from ...core.api_error import ApiError
-from ..types.error import Error
class BadRequestError(ApiError):
- def __init__(self, body: Error):
+ def __init__(self, body: typing.Optional[typing.Any]):
super().__init__(status_code=400, body=body)
diff --git a/src/dify_sdk/chat/errors/forbidden_error.py b/src/dify_sdk/chat/errors/forbidden_error.py
new file mode 100644
index 0000000..674d6b9
--- /dev/null
+++ b/src/dify_sdk/chat/errors/forbidden_error.py
@@ -0,0 +1,10 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from ...core.api_error import ApiError
+
+
+class ForbiddenError(ApiError):
+ def __init__(self, body: typing.Optional[typing.Any]):
+ super().__init__(status_code=403, body=body)
diff --git a/src/dify_sdk/chat/raw_client.py b/src/dify_sdk/chat/raw_client.py
index 3d82e46..bdc5eff 100644
--- a/src/dify_sdk/chat/raw_client.py
+++ b/src/dify_sdk/chat/raw_client.py
@@ -15,6 +15,7 @@
from ..core.serialization import convert_and_respect_annotation_metadata
from .errors.bad_request_error import BadRequestError
from .errors.content_too_large_error import ContentTooLargeError
+from .errors.forbidden_error import ForbiddenError
from .errors.internal_server_error import InternalServerError
from .errors.not_found_error import NotFoundError
from .errors.service_unavailable_error import ServiceUnavailableError
@@ -45,6 +46,7 @@
from .types.send_message_feedback_by_app_chat_response import SendMessageFeedbackByAppChatResponse
from .types.stop_chat_response_by_app_chat_response import StopChatResponseByAppChatResponse
from .types.update_annotation_by_app_chat_response import UpdateAnnotationByAppChatResponse
+from .types.update_conversation_variable_by_app_chat_response import UpdateConversationVariableByAppChatResponse
from .types.uploaded_file import UploadedFile
# this is used as the default value for optional parameters
@@ -66,6 +68,7 @@ def send_chat_message_by_app_chat(
conversation_id: typing.Optional[str] = OMIT,
files: typing.Optional[typing.Sequence[SendChatMessageByAppChatRequestFilesItem]] = OMIT,
auto_generate_name: typing.Optional[bool] = OMIT,
+ workflow_id: typing.Optional[str] = OMIT,
trace_id: typing.Optional[str] = OMIT,
request_options: typing.Optional[RequestOptions] = None,
) -> typing.Iterator[HttpResponse[typing.Iterator[ChunkChatCompletionResponse]]]:
@@ -98,6 +101,9 @@ def send_chat_message_by_app_chat(
auto_generate_name : typing.Optional[bool]
(Optional) Whether to automatically generate title, default is true. If set to false, you can call the conversation rename interface and set auto_generate to true to generate a title asynchronously.
+ workflow_id : typing.Optional[str]
+ (Optional) Workflow ID, used to specify a specific version. If not provided, the default published version will be used.
+
trace_id : typing.Optional[str]
(Optional) Trace ID for linking with existing trace components in business systems, enabling end-to-end distributed tracing scenarios. If not specified, the system will automatically generate a trace_id. Supports the following three transmission methods, in order of priority:
- Header: Passed through HTTP Header X-Trace-Id, highest priority.
@@ -127,6 +133,7 @@ def send_chat_message_by_app_chat(
direction="write",
),
"auto_generate_name": auto_generate_name,
+ "workflow_id": workflow_id,
"trace_id": trace_id,
},
headers={
@@ -155,6 +162,26 @@ def _iter():
_response.read()
if _response.status_code == 400:
raise BadRequestError(
+ typing.cast(
+ typing.Optional[typing.Any],
+ parse_obj_as(
+ type_=typing.Optional[typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ if _response.status_code == 404:
+ raise NotFoundError(
+ typing.cast(
+ typing.Optional[typing.Any],
+ parse_obj_as(
+ type_=typing.Optional[typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ if _response.status_code == 500:
+ raise InternalServerError(
typing.cast(
Error,
parse_obj_as(
@@ -163,6 +190,80 @@ def _iter():
),
)
)
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(
+ headers=dict(_response.headers), status_code=_response.status_code, body=_response.text
+ )
+ raise ApiError(headers=dict(_response.headers), status_code=_response.status_code, body=_response_json)
+
+ yield stream()
+
+ @contextlib.contextmanager
+ def preview_file_by_app_chat(
+ self,
+ file_id: str,
+ *,
+ as_attachment: typing.Optional[bool] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> typing.Iterator[HttpResponse[typing.Iterator[bytes]]]:
+ """
+ Preview or download uploaded files. This endpoint allows you to access files previously uploaded through the file upload API.
+ Files can only be accessed within the message scope belonging to the requesting application.
+
+ Parameters
+ ----------
+ file_id : str
+ Unique identifier of the file to preview, obtained from the file upload API response
+
+ as_attachment : typing.Optional[bool]
+ Whether to force the file to be downloaded as an attachment. Default is false (preview in browser)
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration. You can pass in configuration such as `chunk_size`, and more to customize the request and response.
+
+ Returns
+ -------
+ typing.Iterator[HttpResponse[typing.Iterator[bytes]]]
+ File content
+ """
+ with self._client_wrapper.httpx_client.stream(
+ f"files/{jsonable_encoder(file_id)}/preview",
+ method="GET",
+ params={
+ "as_attachment": as_attachment,
+ },
+ request_options=request_options,
+ ) as _response:
+
+ def stream() -> HttpResponse[typing.Iterator[bytes]]:
+ try:
+ if 200 <= _response.status_code < 300:
+ _chunk_size = request_options.get("chunk_size", None) if request_options is not None else None
+ return HttpResponse(
+ response=_response, data=(_chunk for _chunk in _response.iter_bytes(chunk_size=_chunk_size))
+ )
+ _response.read()
+ if _response.status_code == 400:
+ raise BadRequestError(
+ typing.cast(
+ typing.Optional[typing.Any],
+ parse_obj_as(
+ type_=typing.Optional[typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ if _response.status_code == 403:
+ raise ForbiddenError(
+ typing.cast(
+ typing.Optional[typing.Any],
+ parse_obj_as(
+ type_=typing.Optional[typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
if _response.status_code == 404:
raise NotFoundError(
typing.cast(
@@ -420,6 +521,87 @@ def get_conversation_variables_by_app_chat(
raise ApiError(headers=dict(_response.headers), status_code=_response.status_code, body=_response.text)
raise ApiError(headers=dict(_response.headers), status_code=_response.status_code, body=_response_json)
+ def update_conversation_variable_by_app_chat(
+ self,
+ conversation_id: str,
+ variable_id: str,
+ *,
+ user: str,
+ value: typing.Optional[typing.Any] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> HttpResponse[UpdateConversationVariableByAppChatResponse]:
+ """
+ Update the value of a specific conversation variable. This endpoint allows you to modify variable values captured during conversations while preserving their names, types, and descriptions.
+
+ Parameters
+ ----------
+ conversation_id : str
+ ID of the conversation containing the variable to update
+
+ variable_id : str
+ ID of the variable to update
+
+ user : str
+ User identifier, defined by developer rules, must be unique within the application.
+
+ value : typing.Optional[typing.Any]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ HttpResponse[UpdateConversationVariableByAppChatResponse]
+ Successfully updated variable
+ """
+ _response = self._client_wrapper.httpx_client.request(
+ f"conversations/{jsonable_encoder(conversation_id)}/variables/{jsonable_encoder(variable_id)}",
+ method="PUT",
+ json={
+ "value": value,
+ "user": user,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ UpdateConversationVariableByAppChatResponse,
+ parse_obj_as(
+ type_=UpdateConversationVariableByAppChatResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return HttpResponse(response=_response, data=_data)
+ if _response.status_code == 400:
+ raise BadRequestError(
+ typing.cast(
+ typing.Optional[typing.Any],
+ parse_obj_as(
+ type_=typing.Optional[typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ if _response.status_code == 404:
+ raise NotFoundError(
+ typing.cast(
+ typing.Optional[typing.Any],
+ parse_obj_as(
+ type_=typing.Optional[typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(headers=dict(_response.headers), status_code=_response.status_code, body=_response.text)
+ raise ApiError(headers=dict(_response.headers), status_code=_response.status_code, body=_response_json)
+
def get_conversation_messages_by_app_chat(
self,
*,
@@ -692,9 +874,9 @@ def upload_file_by_app_chat(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -1359,6 +1541,7 @@ async def send_chat_message_by_app_chat(
conversation_id: typing.Optional[str] = OMIT,
files: typing.Optional[typing.Sequence[SendChatMessageByAppChatRequestFilesItem]] = OMIT,
auto_generate_name: typing.Optional[bool] = OMIT,
+ workflow_id: typing.Optional[str] = OMIT,
trace_id: typing.Optional[str] = OMIT,
request_options: typing.Optional[RequestOptions] = None,
) -> typing.AsyncIterator[AsyncHttpResponse[typing.AsyncIterator[ChunkChatCompletionResponse]]]:
@@ -1391,6 +1574,9 @@ async def send_chat_message_by_app_chat(
auto_generate_name : typing.Optional[bool]
(Optional) Whether to automatically generate title, default is true. If set to false, you can call the conversation rename interface and set auto_generate to true to generate a title asynchronously.
+ workflow_id : typing.Optional[str]
+ (Optional) Workflow ID, used to specify a specific version. If not provided, the default published version will be used.
+
trace_id : typing.Optional[str]
(Optional) Trace ID for linking with existing trace components in business systems, enabling end-to-end distributed tracing scenarios. If not specified, the system will automatically generate a trace_id. Supports the following three transmission methods, in order of priority:
- Header: Passed through HTTP Header X-Trace-Id, highest priority.
@@ -1420,6 +1606,7 @@ async def send_chat_message_by_app_chat(
direction="write",
),
"auto_generate_name": auto_generate_name,
+ "workflow_id": workflow_id,
"trace_id": trace_id,
},
headers={
@@ -1448,6 +1635,26 @@ async def _iter():
await _response.aread()
if _response.status_code == 400:
raise BadRequestError(
+ typing.cast(
+ typing.Optional[typing.Any],
+ parse_obj_as(
+ type_=typing.Optional[typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ if _response.status_code == 404:
+ raise NotFoundError(
+ typing.cast(
+ typing.Optional[typing.Any],
+ parse_obj_as(
+ type_=typing.Optional[typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ if _response.status_code == 500:
+ raise InternalServerError(
typing.cast(
Error,
parse_obj_as(
@@ -1456,6 +1663,81 @@ async def _iter():
),
)
)
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(
+ headers=dict(_response.headers), status_code=_response.status_code, body=_response.text
+ )
+ raise ApiError(headers=dict(_response.headers), status_code=_response.status_code, body=_response_json)
+
+ yield await stream()
+
+ @contextlib.asynccontextmanager
+ async def preview_file_by_app_chat(
+ self,
+ file_id: str,
+ *,
+ as_attachment: typing.Optional[bool] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> typing.AsyncIterator[AsyncHttpResponse[typing.AsyncIterator[bytes]]]:
+ """
+ Preview or download uploaded files. This endpoint allows you to access files previously uploaded through the file upload API.
+ Files can only be accessed within the message scope belonging to the requesting application.
+
+ Parameters
+ ----------
+ file_id : str
+ Unique identifier of the file to preview, obtained from the file upload API response
+
+ as_attachment : typing.Optional[bool]
+ Whether to force the file to be downloaded as an attachment. Default is false (preview in browser)
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration. You can pass in configuration such as `chunk_size`, and more to customize the request and response.
+
+ Returns
+ -------
+ typing.AsyncIterator[AsyncHttpResponse[typing.AsyncIterator[bytes]]]
+ File content
+ """
+ async with self._client_wrapper.httpx_client.stream(
+ f"files/{jsonable_encoder(file_id)}/preview",
+ method="GET",
+ params={
+ "as_attachment": as_attachment,
+ },
+ request_options=request_options,
+ ) as _response:
+
+ async def stream() -> AsyncHttpResponse[typing.AsyncIterator[bytes]]:
+ try:
+ if 200 <= _response.status_code < 300:
+ _chunk_size = request_options.get("chunk_size", None) if request_options is not None else None
+ return AsyncHttpResponse(
+ response=_response,
+ data=(_chunk async for _chunk in _response.aiter_bytes(chunk_size=_chunk_size)),
+ )
+ await _response.aread()
+ if _response.status_code == 400:
+ raise BadRequestError(
+ typing.cast(
+ typing.Optional[typing.Any],
+ parse_obj_as(
+ type_=typing.Optional[typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ if _response.status_code == 403:
+ raise ForbiddenError(
+ typing.cast(
+ typing.Optional[typing.Any],
+ parse_obj_as(
+ type_=typing.Optional[typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
if _response.status_code == 404:
raise NotFoundError(
typing.cast(
@@ -1713,6 +1995,87 @@ async def get_conversation_variables_by_app_chat(
raise ApiError(headers=dict(_response.headers), status_code=_response.status_code, body=_response.text)
raise ApiError(headers=dict(_response.headers), status_code=_response.status_code, body=_response_json)
+ async def update_conversation_variable_by_app_chat(
+ self,
+ conversation_id: str,
+ variable_id: str,
+ *,
+ user: str,
+ value: typing.Optional[typing.Any] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> AsyncHttpResponse[UpdateConversationVariableByAppChatResponse]:
+ """
+ Update the value of a specific conversation variable. This endpoint allows you to modify variable values captured during conversations while preserving their names, types, and descriptions.
+
+ Parameters
+ ----------
+ conversation_id : str
+ ID of the conversation containing the variable to update
+
+ variable_id : str
+ ID of the variable to update
+
+ user : str
+ User identifier, defined by developer rules, must be unique within the application.
+
+ value : typing.Optional[typing.Any]
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Returns
+ -------
+ AsyncHttpResponse[UpdateConversationVariableByAppChatResponse]
+ Successfully updated variable
+ """
+ _response = await self._client_wrapper.httpx_client.request(
+ f"conversations/{jsonable_encoder(conversation_id)}/variables/{jsonable_encoder(variable_id)}",
+ method="PUT",
+ json={
+ "value": value,
+ "user": user,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ )
+ try:
+ if 200 <= _response.status_code < 300:
+ _data = typing.cast(
+ UpdateConversationVariableByAppChatResponse,
+ parse_obj_as(
+ type_=UpdateConversationVariableByAppChatResponse, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ return AsyncHttpResponse(response=_response, data=_data)
+ if _response.status_code == 400:
+ raise BadRequestError(
+ typing.cast(
+ typing.Optional[typing.Any],
+ parse_obj_as(
+ type_=typing.Optional[typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ if _response.status_code == 404:
+ raise NotFoundError(
+ typing.cast(
+ typing.Optional[typing.Any],
+ parse_obj_as(
+ type_=typing.Optional[typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(headers=dict(_response.headers), status_code=_response.status_code, body=_response.text)
+ raise ApiError(headers=dict(_response.headers), status_code=_response.status_code, body=_response_json)
+
async def get_conversation_messages_by_app_chat(
self,
*,
@@ -1985,9 +2348,9 @@ async def upload_file_by_app_chat(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
diff --git a/src/dify_sdk/chat/types/__init__.py b/src/dify_sdk/chat/types/__init__.py
index b4683ee..bec40bb 100644
--- a/src/dify_sdk/chat/types/__init__.py
+++ b/src/dify_sdk/chat/types/__init__.py
@@ -2,6 +2,8 @@
# isort: skip_file
+from .bad_request_error_body import BadRequestErrorBody
+from .bad_request_error_body_code import BadRequestErrorBodyCode
from .chat_completion_response import ChatCompletionResponse
from .chat_completion_response_metadata import ChatCompletionResponseMetadata
from .chat_history_message import ChatHistoryMessage
@@ -22,6 +24,7 @@
from .file_input import FileInput
from .file_input_transfer_method import FileInputTransferMethod
from .file_input_type import FileInputType
+from .forbidden_error_body import ForbiddenErrorBody
from .get_annotation_reply_status_by_app_chat_request_action import GetAnnotationReplyStatusByAppChatRequestAction
from .get_annotation_reply_status_by_app_chat_response import GetAnnotationReplyStatusByAppChatResponse
from .get_annotations_list_by_app_chat_response import GetAnnotationsListByAppChatResponse
@@ -97,6 +100,7 @@
from .get_conversation_variables_by_app_chat_response_data_item import GetConversationVariablesByAppChatResponseDataItem
from .get_suggested_questions_by_app_chat_response import GetSuggestedQuestionsByAppChatResponse
from .not_found_error_body import NotFoundErrorBody
+from .not_found_error_body_code import NotFoundErrorBodyCode
from .retriever_resource import RetrieverResource
from .send_chat_message_by_app_chat_request_files_item import SendChatMessageByAppChatRequestFilesItem
from .send_chat_message_by_app_chat_request_files_item_transfer_method import (
@@ -106,10 +110,13 @@
from .send_message_feedback_by_app_chat_response import SendMessageFeedbackByAppChatResponse
from .stop_chat_response_by_app_chat_response import StopChatResponseByAppChatResponse
from .update_annotation_by_app_chat_response import UpdateAnnotationByAppChatResponse
+from .update_conversation_variable_by_app_chat_response import UpdateConversationVariableByAppChatResponse
from .uploaded_file import UploadedFile
from .usage import Usage
__all__ = [
+ "BadRequestErrorBody",
+ "BadRequestErrorBodyCode",
"ChatCompletionResponse",
"ChatCompletionResponseMetadata",
"ChatHistoryMessage",
@@ -130,6 +137,7 @@
"FileInput",
"FileInputTransferMethod",
"FileInputType",
+ "ForbiddenErrorBody",
"GetAnnotationReplyStatusByAppChatRequestAction",
"GetAnnotationReplyStatusByAppChatResponse",
"GetAnnotationsListByAppChatResponse",
@@ -167,6 +175,7 @@
"GetConversationVariablesByAppChatResponseDataItem",
"GetSuggestedQuestionsByAppChatResponse",
"NotFoundErrorBody",
+ "NotFoundErrorBodyCode",
"RetrieverResource",
"SendChatMessageByAppChatRequestFilesItem",
"SendChatMessageByAppChatRequestFilesItemTransferMethod",
@@ -174,6 +183,7 @@
"SendMessageFeedbackByAppChatResponse",
"StopChatResponseByAppChatResponse",
"UpdateAnnotationByAppChatResponse",
+ "UpdateConversationVariableByAppChatResponse",
"UploadedFile",
"Usage",
]
diff --git a/src/dify_sdk/chat/types/bad_request_error_body.py b/src/dify_sdk/chat/types/bad_request_error_body.py
new file mode 100644
index 0000000..77c3061
--- /dev/null
+++ b/src/dify_sdk/chat/types/bad_request_error_body.py
@@ -0,0 +1,28 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ...core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class BadRequestErrorBody(UniversalBaseModel):
+ message: typing.Optional[typing.Optional[typing.Any]] = None
+ code: str = pydantic.Field()
+ """
+ Error code
+ """
+
+ status: int = pydantic.Field()
+ """
+ HTTP status code
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/src/dify_sdk/chat/types/bad_request_error_body_code.py b/src/dify_sdk/chat/types/bad_request_error_body_code.py
new file mode 100644
index 0000000..e4453c2
--- /dev/null
+++ b/src/dify_sdk/chat/types/bad_request_error_body_code.py
@@ -0,0 +1,18 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+BadRequestErrorBodyCode = typing.Union[
+ typing.Literal[
+ "invalid_param",
+ "app_unavailable",
+ "provider_not_initialize",
+ "provider_quota_exceeded",
+ "model_currently_not_support",
+ "workflow_not_found",
+ "draft_workflow_error",
+ "workflow_id_format_error",
+ "completion_request_error",
+ ],
+ typing.Any,
+]
diff --git a/src/dify_sdk/chat/types/forbidden_error_body.py b/src/dify_sdk/chat/types/forbidden_error_body.py
new file mode 100644
index 0000000..7e13c13
--- /dev/null
+++ b/src/dify_sdk/chat/types/forbidden_error_body.py
@@ -0,0 +1,28 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ...core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class ForbiddenErrorBody(UniversalBaseModel):
+ code: typing.Optional[typing.Literal["file_access_denied"]] = None
+ status: int = pydantic.Field()
+ """
+ HTTP status code
+ """
+
+ message: str = pydantic.Field()
+ """
+ Error message description
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/src/dify_sdk/chat/types/not_found_error_body.py b/src/dify_sdk/chat/types/not_found_error_body.py
index b76f064..44e14ee 100644
--- a/src/dify_sdk/chat/types/not_found_error_body.py
+++ b/src/dify_sdk/chat/types/not_found_error_body.py
@@ -4,17 +4,19 @@
import pydantic
from ...core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+from .not_found_error_body_code import NotFoundErrorBodyCode
class NotFoundErrorBody(UniversalBaseModel):
- code: typing.Optional[typing.Literal["conversation_not_exists"]] = pydantic.Field(default=None)
+ code: typing.Optional[NotFoundErrorBodyCode] = None
+ status: int = pydantic.Field()
"""
- Error code
+ HTTP status code
"""
- message: typing.Optional[str] = pydantic.Field(default=None)
+ message: str = pydantic.Field()
"""
- Error message
+ Error message description
"""
if IS_PYDANTIC_V2:
diff --git a/src/dify_sdk/chat/types/not_found_error_body_code.py b/src/dify_sdk/chat/types/not_found_error_body_code.py
new file mode 100644
index 0000000..8161f38
--- /dev/null
+++ b/src/dify_sdk/chat/types/not_found_error_body_code.py
@@ -0,0 +1,7 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+NotFoundErrorBodyCode = typing.Union[
+ typing.Literal["conversation_not_exists", "conversation_variable_not_exists"], typing.Any
+]
diff --git a/src/dify_sdk/chat/types/update_conversation_variable_by_app_chat_response.py b/src/dify_sdk/chat/types/update_conversation_variable_by_app_chat_response.py
new file mode 100644
index 0000000..f4f3141
--- /dev/null
+++ b/src/dify_sdk/chat/types/update_conversation_variable_by_app_chat_response.py
@@ -0,0 +1,48 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+import pydantic
+from ...core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
+
+
+class UpdateConversationVariableByAppChatResponse(UniversalBaseModel):
+ id: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Variable ID
+ """
+
+ name: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Variable name
+ """
+
+ value_type: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Variable type (string, number, object, etc.)
+ """
+
+ value: typing.Optional[typing.Optional[typing.Any]] = None
+ description: typing.Optional[str] = pydantic.Field(default=None)
+ """
+ Variable description
+ """
+
+ created_at: typing.Optional[int] = pydantic.Field(default=None)
+ """
+ Creation timestamp
+ """
+
+ updated_at: typing.Optional[int] = pydantic.Field(default=None)
+ """
+ Last update timestamp
+ """
+
+ if IS_PYDANTIC_V2:
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
+ else:
+
+ class Config:
+ frozen = True
+ smart_union = True
+ extra = pydantic.Extra.allow
diff --git a/src/dify_sdk/generation/__init__.py b/src/dify_sdk/generation/__init__.py
index 9b8e1c6..165cbaa 100644
--- a/src/dify_sdk/generation/__init__.py
+++ b/src/dify_sdk/generation/__init__.py
@@ -63,6 +63,7 @@
from .errors import (
BadRequestError,
ContentTooLargeError,
+ ForbiddenError,
InternalServerError,
NotFoundError,
ServiceUnavailableError,
@@ -84,6 +85,7 @@
"FileInput",
"FileInputTransferMethod",
"FileInputType",
+ "ForbiddenError",
"GetAnnotationReplyStatusByAppGenerationRequestAction",
"GetAnnotationReplyStatusByAppGenerationResponse",
"GetAnnotationsListByAppGenerationResponse",
diff --git a/src/dify_sdk/generation/client.py b/src/dify_sdk/generation/client.py
index 2c3efc0..eaf620a 100644
--- a/src/dify_sdk/generation/client.py
+++ b/src/dify_sdk/generation/client.py
@@ -154,6 +154,38 @@ def upload_file_by_app_generation(
)
return _response.data
+ def preview_file_by_app_generation(
+ self,
+ file_id: str,
+ *,
+ as_attachment: typing.Optional[bool] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> typing.Iterator[bytes]:
+ """
+ Preview or download uploaded files. This endpoint allows you to access files previously uploaded through the file upload API.
+ Files can only be accessed within the message scope belonging to the requesting application.
+
+ Parameters
+ ----------
+ file_id : str
+ Unique identifier of the file to preview, obtained from the file upload API response
+
+ as_attachment : typing.Optional[bool]
+ Whether to force file download as attachment. Defaults to false (preview in browser)
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration. You can pass in configuration such as `chunk_size`, and more to customize the request and response.
+
+ Returns
+ -------
+ typing.Iterator[bytes]
+ Successful response
+ """
+ with self._raw_client.preview_file_by_app_generation(
+ file_id, as_attachment=as_attachment, request_options=request_options
+ ) as r:
+ yield from r.data
+
def get_application_info_by_app_generation(
self, *, request_options: typing.Optional[RequestOptions] = None
) -> GetApplicationInfoByAppGenerationResponse:
@@ -744,6 +776,39 @@ async def main() -> None:
)
return _response.data
+ async def preview_file_by_app_generation(
+ self,
+ file_id: str,
+ *,
+ as_attachment: typing.Optional[bool] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> typing.AsyncIterator[bytes]:
+ """
+ Preview or download uploaded files. This endpoint allows you to access files previously uploaded through the file upload API.
+ Files can only be accessed within the message scope belonging to the requesting application.
+
+ Parameters
+ ----------
+ file_id : str
+ Unique identifier of the file to preview, obtained from the file upload API response
+
+ as_attachment : typing.Optional[bool]
+ Whether to force file download as attachment. Defaults to false (preview in browser)
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration. You can pass in configuration such as `chunk_size`, and more to customize the request and response.
+
+ Returns
+ -------
+ typing.AsyncIterator[bytes]
+ Successful response
+ """
+ async with self._raw_client.preview_file_by_app_generation(
+ file_id, as_attachment=as_attachment, request_options=request_options
+ ) as r:
+ async for data in r.data:
+ yield data
+
async def get_application_info_by_app_generation(
self, *, request_options: typing.Optional[RequestOptions] = None
) -> GetApplicationInfoByAppGenerationResponse:
diff --git a/src/dify_sdk/generation/errors/__init__.py b/src/dify_sdk/generation/errors/__init__.py
index 635aad6..37b13b9 100644
--- a/src/dify_sdk/generation/errors/__init__.py
+++ b/src/dify_sdk/generation/errors/__init__.py
@@ -4,6 +4,7 @@
from .bad_request_error import BadRequestError
from .content_too_large_error import ContentTooLargeError
+from .forbidden_error import ForbiddenError
from .internal_server_error import InternalServerError
from .not_found_error import NotFoundError
from .service_unavailable_error import ServiceUnavailableError
@@ -12,6 +13,7 @@
__all__ = [
"BadRequestError",
"ContentTooLargeError",
+ "ForbiddenError",
"InternalServerError",
"NotFoundError",
"ServiceUnavailableError",
diff --git a/src/dify_sdk/generation/errors/bad_request_error.py b/src/dify_sdk/generation/errors/bad_request_error.py
index 5ccb07c..c1e658e 100644
--- a/src/dify_sdk/generation/errors/bad_request_error.py
+++ b/src/dify_sdk/generation/errors/bad_request_error.py
@@ -1,9 +1,10 @@
# This file was auto-generated by Fern from our API Definition.
+import typing
+
from ...core.api_error import ApiError
-from ..types.error import Error
class BadRequestError(ApiError):
- def __init__(self, body: Error):
+ def __init__(self, body: typing.Optional[typing.Any]):
super().__init__(status_code=400, body=body)
diff --git a/src/dify_sdk/generation/errors/forbidden_error.py b/src/dify_sdk/generation/errors/forbidden_error.py
new file mode 100644
index 0000000..674d6b9
--- /dev/null
+++ b/src/dify_sdk/generation/errors/forbidden_error.py
@@ -0,0 +1,10 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from ...core.api_error import ApiError
+
+
+class ForbiddenError(ApiError):
+ def __init__(self, body: typing.Optional[typing.Any]):
+ super().__init__(status_code=403, body=body)
diff --git a/src/dify_sdk/generation/raw_client.py b/src/dify_sdk/generation/raw_client.py
index 14c4263..459f10d 100644
--- a/src/dify_sdk/generation/raw_client.py
+++ b/src/dify_sdk/generation/raw_client.py
@@ -15,6 +15,7 @@
from ..core.serialization import convert_and_respect_annotation_metadata
from .errors.bad_request_error import BadRequestError
from .errors.content_too_large_error import ContentTooLargeError
+from .errors.forbidden_error import ForbiddenError
from .errors.internal_server_error import InternalServerError
from .errors.not_found_error import NotFoundError
from .errors.service_unavailable_error import ServiceUnavailableError
@@ -145,9 +146,9 @@ def _iter():
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -233,9 +234,9 @@ def upload_file_by_app_generation(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -275,6 +276,100 @@ def upload_file_by_app_generation(
raise ApiError(headers=dict(_response.headers), status_code=_response.status_code, body=_response.text)
raise ApiError(headers=dict(_response.headers), status_code=_response.status_code, body=_response_json)
+ @contextlib.contextmanager
+ def preview_file_by_app_generation(
+ self,
+ file_id: str,
+ *,
+ as_attachment: typing.Optional[bool] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> typing.Iterator[HttpResponse[typing.Iterator[bytes]]]:
+ """
+ Preview or download uploaded files. This endpoint allows you to access files previously uploaded through the file upload API.
+ Files can only be accessed within the message scope belonging to the requesting application.
+
+ Parameters
+ ----------
+ file_id : str
+ Unique identifier of the file to preview, obtained from the file upload API response
+
+ as_attachment : typing.Optional[bool]
+ Whether to force file download as attachment. Defaults to false (preview in browser)
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration. You can pass in configuration such as `chunk_size`, and more to customize the request and response.
+
+ Returns
+ -------
+ typing.Iterator[HttpResponse[typing.Iterator[bytes]]]
+ Successful response
+ """
+ with self._client_wrapper.httpx_client.stream(
+ f"files/{jsonable_encoder(file_id)}/preview",
+ method="GET",
+ params={
+ "as_attachment": as_attachment,
+ },
+ request_options=request_options,
+ ) as _response:
+
+ def stream() -> HttpResponse[typing.Iterator[bytes]]:
+ try:
+ if 200 <= _response.status_code < 300:
+ _chunk_size = request_options.get("chunk_size", None) if request_options is not None else None
+ return HttpResponse(
+ response=_response, data=(_chunk for _chunk in _response.iter_bytes(chunk_size=_chunk_size))
+ )
+ _response.read()
+ if _response.status_code == 400:
+ raise BadRequestError(
+ typing.cast(
+ typing.Optional[typing.Any],
+ parse_obj_as(
+ type_=typing.Optional[typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ if _response.status_code == 403:
+ raise ForbiddenError(
+ typing.cast(
+ typing.Optional[typing.Any],
+ parse_obj_as(
+ type_=typing.Optional[typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ if _response.status_code == 404:
+ raise NotFoundError(
+ typing.cast(
+ typing.Optional[typing.Any],
+ parse_obj_as(
+ type_=typing.Optional[typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ if _response.status_code == 500:
+ raise InternalServerError(
+ typing.cast(
+ Error,
+ parse_obj_as(
+ type_=Error, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(
+ headers=dict(_response.headers), status_code=_response.status_code, body=_response.text
+ )
+ raise ApiError(headers=dict(_response.headers), status_code=_response.status_code, body=_response_json)
+
+ yield stream()
+
def get_application_info_by_app_generation(
self, *, request_options: typing.Optional[RequestOptions] = None
) -> HttpResponse[GetApplicationInfoByAppGenerationResponse]:
@@ -1029,9 +1124,9 @@ async def _iter():
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -1117,9 +1212,9 @@ async def upload_file_by_app_generation(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -1159,6 +1254,101 @@ async def upload_file_by_app_generation(
raise ApiError(headers=dict(_response.headers), status_code=_response.status_code, body=_response.text)
raise ApiError(headers=dict(_response.headers), status_code=_response.status_code, body=_response_json)
+ @contextlib.asynccontextmanager
+ async def preview_file_by_app_generation(
+ self,
+ file_id: str,
+ *,
+ as_attachment: typing.Optional[bool] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> typing.AsyncIterator[AsyncHttpResponse[typing.AsyncIterator[bytes]]]:
+ """
+ Preview or download uploaded files. This endpoint allows you to access files previously uploaded through the file upload API.
+ Files can only be accessed within the message scope belonging to the requesting application.
+
+ Parameters
+ ----------
+ file_id : str
+ Unique identifier of the file to preview, obtained from the file upload API response
+
+ as_attachment : typing.Optional[bool]
+ Whether to force file download as attachment. Defaults to false (preview in browser)
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration. You can pass in configuration such as `chunk_size`, and more to customize the request and response.
+
+ Returns
+ -------
+ typing.AsyncIterator[AsyncHttpResponse[typing.AsyncIterator[bytes]]]
+ Successful response
+ """
+ async with self._client_wrapper.httpx_client.stream(
+ f"files/{jsonable_encoder(file_id)}/preview",
+ method="GET",
+ params={
+ "as_attachment": as_attachment,
+ },
+ request_options=request_options,
+ ) as _response:
+
+ async def stream() -> AsyncHttpResponse[typing.AsyncIterator[bytes]]:
+ try:
+ if 200 <= _response.status_code < 300:
+ _chunk_size = request_options.get("chunk_size", None) if request_options is not None else None
+ return AsyncHttpResponse(
+ response=_response,
+ data=(_chunk async for _chunk in _response.aiter_bytes(chunk_size=_chunk_size)),
+ )
+ await _response.aread()
+ if _response.status_code == 400:
+ raise BadRequestError(
+ typing.cast(
+ typing.Optional[typing.Any],
+ parse_obj_as(
+ type_=typing.Optional[typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ if _response.status_code == 403:
+ raise ForbiddenError(
+ typing.cast(
+ typing.Optional[typing.Any],
+ parse_obj_as(
+ type_=typing.Optional[typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ if _response.status_code == 404:
+ raise NotFoundError(
+ typing.cast(
+ typing.Optional[typing.Any],
+ parse_obj_as(
+ type_=typing.Optional[typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ if _response.status_code == 500:
+ raise InternalServerError(
+ typing.cast(
+ Error,
+ parse_obj_as(
+ type_=Error, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(
+ headers=dict(_response.headers), status_code=_response.status_code, body=_response.text
+ )
+ raise ApiError(headers=dict(_response.headers), status_code=_response.status_code, body=_response_json)
+
+ yield await stream()
+
async def get_application_info_by_app_generation(
self, *, request_options: typing.Optional[RequestOptions] = None
) -> AsyncHttpResponse[GetApplicationInfoByAppGenerationResponse]:
diff --git a/src/dify_sdk/knowledge_base/datasets/raw_client.py b/src/dify_sdk/knowledge_base/datasets/raw_client.py
index 38479f8..6245f65 100644
--- a/src/dify_sdk/knowledge_base/datasets/raw_client.py
+++ b/src/dify_sdk/knowledge_base/datasets/raw_client.py
@@ -80,9 +80,9 @@ def get_dataset_list(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -193,9 +193,9 @@ def create_empty_dataset(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -252,9 +252,9 @@ def view_knowledge_base_details(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -262,9 +262,9 @@ def view_knowledge_base_details(
if _response.status_code == 403:
raise ForbiddenError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -303,9 +303,9 @@ def delete_dataset(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -313,9 +313,9 @@ def delete_dataset(
if _response.status_code == 403:
raise ForbiddenError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -412,9 +412,9 @@ def update_knowledge_base_details(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -422,9 +422,9 @@ def update_knowledge_base_details(
if _response.status_code == 403:
raise ForbiddenError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -497,9 +497,9 @@ def retrieve_dataset(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -507,9 +507,9 @@ def retrieve_dataset(
if _response.status_code == 403:
raise ForbiddenError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -572,9 +572,9 @@ async def get_dataset_list(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -685,9 +685,9 @@ async def create_empty_dataset(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -744,9 +744,9 @@ async def view_knowledge_base_details(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -754,9 +754,9 @@ async def view_knowledge_base_details(
if _response.status_code == 403:
raise ForbiddenError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -795,9 +795,9 @@ async def delete_dataset(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -805,9 +805,9 @@ async def delete_dataset(
if _response.status_code == 403:
raise ForbiddenError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -904,9 +904,9 @@ async def update_knowledge_base_details(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -914,9 +914,9 @@ async def update_knowledge_base_details(
if _response.status_code == 403:
raise ForbiddenError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -989,9 +989,9 @@ async def retrieve_dataset(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -999,9 +999,9 @@ async def retrieve_dataset(
if _response.status_code == 403:
raise ForbiddenError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
diff --git a/src/dify_sdk/knowledge_base/documents/raw_client.py b/src/dify_sdk/knowledge_base/documents/raw_client.py
index f3f11b7..ecedd98 100644
--- a/src/dify_sdk/knowledge_base/documents/raw_client.py
+++ b/src/dify_sdk/knowledge_base/documents/raw_client.py
@@ -119,9 +119,9 @@ def create_document_by_text(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -209,9 +209,9 @@ def create_document_by_file(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -323,9 +323,9 @@ def update_document_by_text(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -333,9 +333,9 @@ def update_document_by_text(
if _response.status_code == 403:
raise ForbiddenError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -411,9 +411,9 @@ def update_document_by_file(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -421,9 +421,9 @@ def update_document_by_file(
if _response.status_code == 403:
raise ForbiddenError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -493,9 +493,9 @@ def get_document_indexing_status(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -503,9 +503,9 @@ def get_document_indexing_status(
if _response.status_code == 403:
raise ForbiddenError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -572,9 +572,9 @@ def get_document_list(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -635,9 +635,9 @@ def get_document_detail(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -645,9 +645,9 @@ def get_document_detail(
if _response.status_code == 403:
raise ForbiddenError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -699,9 +699,9 @@ def delete_document(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -709,9 +709,9 @@ def delete_document(
if _response.status_code == 403:
raise ForbiddenError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -776,9 +776,9 @@ def batch_update_document_status(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -786,9 +786,9 @@ def batch_update_document_status(
if _response.status_code == 403:
raise ForbiddenError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -838,9 +838,9 @@ def get_upload_file(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -848,9 +848,9 @@ def get_upload_file(
if _response.status_code == 403:
raise ForbiddenError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -942,9 +942,9 @@ async def create_document_by_text(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -1032,9 +1032,9 @@ async def create_document_by_file(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -1146,9 +1146,9 @@ async def update_document_by_text(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -1156,9 +1156,9 @@ async def update_document_by_text(
if _response.status_code == 403:
raise ForbiddenError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -1234,9 +1234,9 @@ async def update_document_by_file(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -1244,9 +1244,9 @@ async def update_document_by_file(
if _response.status_code == 403:
raise ForbiddenError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -1316,9 +1316,9 @@ async def get_document_indexing_status(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -1326,9 +1326,9 @@ async def get_document_indexing_status(
if _response.status_code == 403:
raise ForbiddenError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -1395,9 +1395,9 @@ async def get_document_list(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -1458,9 +1458,9 @@ async def get_document_detail(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -1468,9 +1468,9 @@ async def get_document_detail(
if _response.status_code == 403:
raise ForbiddenError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -1522,9 +1522,9 @@ async def delete_document(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -1532,9 +1532,9 @@ async def delete_document(
if _response.status_code == 403:
raise ForbiddenError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -1599,9 +1599,9 @@ async def batch_update_document_status(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -1609,9 +1609,9 @@ async def batch_update_document_status(
if _response.status_code == 403:
raise ForbiddenError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -1661,9 +1661,9 @@ async def get_upload_file(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -1671,9 +1671,9 @@ async def get_upload_file(
if _response.status_code == 403:
raise ForbiddenError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
diff --git a/src/dify_sdk/knowledge_base/errors/bad_request_error.py b/src/dify_sdk/knowledge_base/errors/bad_request_error.py
index 5ccb07c..c1e658e 100644
--- a/src/dify_sdk/knowledge_base/errors/bad_request_error.py
+++ b/src/dify_sdk/knowledge_base/errors/bad_request_error.py
@@ -1,9 +1,10 @@
# This file was auto-generated by Fern from our API Definition.
+import typing
+
from ...core.api_error import ApiError
-from ..types.error import Error
class BadRequestError(ApiError):
- def __init__(self, body: Error):
+ def __init__(self, body: typing.Optional[typing.Any]):
super().__init__(status_code=400, body=body)
diff --git a/src/dify_sdk/knowledge_base/errors/forbidden_error.py b/src/dify_sdk/knowledge_base/errors/forbidden_error.py
index 4569e4f..674d6b9 100644
--- a/src/dify_sdk/knowledge_base/errors/forbidden_error.py
+++ b/src/dify_sdk/knowledge_base/errors/forbidden_error.py
@@ -1,9 +1,10 @@
# This file was auto-generated by Fern from our API Definition.
+import typing
+
from ...core.api_error import ApiError
-from ..types.error import Error
class ForbiddenError(ApiError):
- def __init__(self, body: Error):
+ def __init__(self, body: typing.Optional[typing.Any]):
super().__init__(status_code=403, body=body)
diff --git a/src/dify_sdk/knowledge_base/metadata/raw_client.py b/src/dify_sdk/knowledge_base/metadata/raw_client.py
index 91dfa15..c7b4371 100644
--- a/src/dify_sdk/knowledge_base/metadata/raw_client.py
+++ b/src/dify_sdk/knowledge_base/metadata/raw_client.py
@@ -11,7 +11,6 @@
from ...core.request_options import RequestOptions
from ...core.serialization import convert_and_respect_annotation_metadata
from ..errors.bad_request_error import BadRequestError
-from ..types.error import Error
from .types.create_metadata_response import CreateMetadataResponse
from .types.list_dataset_metadata_response import ListDatasetMetadataResponse
from .types.toggle_built_in_metadata_request_action import ToggleBuiltInMetadataRequestAction
@@ -63,9 +62,9 @@ def list_dataset_metadata(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -126,9 +125,9 @@ def create_metadata(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -170,9 +169,9 @@ def delete_metadata(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -232,9 +231,9 @@ def update_metadata(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -280,9 +279,9 @@ def toggle_built_in_metadata(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -339,9 +338,9 @@ def update_documents_metadata(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -393,9 +392,9 @@ async def list_dataset_metadata(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -456,9 +455,9 @@ async def create_metadata(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -500,9 +499,9 @@ async def delete_metadata(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -562,9 +561,9 @@ async def update_metadata(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -610,9 +609,9 @@ async def toggle_built_in_metadata(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -669,9 +668,9 @@ async def update_documents_metadata(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
diff --git a/src/dify_sdk/knowledge_base/models/raw_client.py b/src/dify_sdk/knowledge_base/models/raw_client.py
index 5cc2485..e9b6364 100644
--- a/src/dify_sdk/knowledge_base/models/raw_client.py
+++ b/src/dify_sdk/knowledge_base/models/raw_client.py
@@ -9,7 +9,6 @@
from ...core.pydantic_utilities import parse_obj_as
from ...core.request_options import RequestOptions
from ..errors.bad_request_error import BadRequestError
-from ..types.error import Error
from .types.get_embedding_models_response import GetEmbeddingModelsResponse
@@ -51,9 +50,9 @@ def get_embedding_models(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -102,9 +101,9 @@ async def get_embedding_models(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
diff --git a/src/dify_sdk/knowledge_base/segments/raw_client.py b/src/dify_sdk/knowledge_base/segments/raw_client.py
index 679a284..831ab18 100644
--- a/src/dify_sdk/knowledge_base/segments/raw_client.py
+++ b/src/dify_sdk/knowledge_base/segments/raw_client.py
@@ -12,7 +12,6 @@
from ...core.serialization import convert_and_respect_annotation_metadata
from ..errors.bad_request_error import BadRequestError
from ..errors.forbidden_error import ForbiddenError
-from ..types.error import Error
from .types.create_segments_request_segments_item import CreateSegmentsRequestSegmentsItem
from .types.create_segments_response import CreateSegmentsResponse
from .types.get_datasets_dataset_id_documents_document_id_segments_segment_id_child_chunks_response import (
@@ -103,9 +102,9 @@ def get_segments(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -171,9 +170,9 @@ def create_segments(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -181,9 +180,9 @@ def create_segments(
if _response.status_code == 403:
raise ForbiddenError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -258,9 +257,9 @@ def query_document_child_segments(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -329,9 +328,9 @@ def create_document_child_segment(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -339,9 +338,9 @@ def create_document_child_segment(
if _response.status_code == 403:
raise ForbiddenError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -395,9 +394,9 @@ def delete_document_child_segment(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -405,9 +404,9 @@ def delete_document_child_segment(
if _response.status_code == 403:
raise ForbiddenError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -480,9 +479,9 @@ def update_document_child_segment(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -490,9 +489,9 @@ def update_document_child_segment(
if _response.status_code == 403:
raise ForbiddenError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -550,9 +549,9 @@ def get_segment_detail(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -560,9 +559,9 @@ def get_segment_detail(
if _response.status_code == 403:
raise ForbiddenError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -632,9 +631,9 @@ def update_segment(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -642,9 +641,9 @@ def update_segment(
if _response.status_code == 403:
raise ForbiddenError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -694,9 +693,9 @@ def delete_segment(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -704,9 +703,9 @@ def delete_segment(
if _response.status_code == 403:
raise ForbiddenError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -787,9 +786,9 @@ async def get_segments(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -855,9 +854,9 @@ async def create_segments(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -865,9 +864,9 @@ async def create_segments(
if _response.status_code == 403:
raise ForbiddenError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -942,9 +941,9 @@ async def query_document_child_segments(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -1013,9 +1012,9 @@ async def create_document_child_segment(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -1023,9 +1022,9 @@ async def create_document_child_segment(
if _response.status_code == 403:
raise ForbiddenError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -1079,9 +1078,9 @@ async def delete_document_child_segment(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -1089,9 +1088,9 @@ async def delete_document_child_segment(
if _response.status_code == 403:
raise ForbiddenError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -1164,9 +1163,9 @@ async def update_document_child_segment(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -1174,9 +1173,9 @@ async def update_document_child_segment(
if _response.status_code == 403:
raise ForbiddenError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -1234,9 +1233,9 @@ async def get_segment_detail(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -1244,9 +1243,9 @@ async def get_segment_detail(
if _response.status_code == 403:
raise ForbiddenError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -1316,9 +1315,9 @@ async def update_segment(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -1326,9 +1325,9 @@ async def update_segment(
if _response.status_code == 403:
raise ForbiddenError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -1378,9 +1377,9 @@ async def delete_segment(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -1388,9 +1387,9 @@ async def delete_segment(
if _response.status_code == 403:
raise ForbiddenError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
diff --git a/src/dify_sdk/knowledge_base/tags/raw_client.py b/src/dify_sdk/knowledge_base/tags/raw_client.py
index 6fff10d..34d2c54 100644
--- a/src/dify_sdk/knowledge_base/tags/raw_client.py
+++ b/src/dify_sdk/knowledge_base/tags/raw_client.py
@@ -10,7 +10,6 @@
from ...core.pydantic_utilities import parse_obj_as
from ...core.request_options import RequestOptions
from ..errors.bad_request_error import BadRequestError
-from ..types.error import Error
from ..types.knowledge_tag import KnowledgeTag
from .types.get_dataset_tags_response import GetDatasetTagsResponse
@@ -56,9 +55,9 @@ def get_knowledge_tags(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -112,9 +111,9 @@ def create_knowledge_tag(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -160,9 +159,9 @@ def delete_knowledge_tag(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -220,9 +219,9 @@ def update_knowledge_tag(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -272,9 +271,9 @@ def bind_dataset_to_tag(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -324,9 +323,9 @@ def unbind_dataset_from_tag(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -373,9 +372,9 @@ def get_dataset_tags(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -424,9 +423,9 @@ async def get_knowledge_tags(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -480,9 +479,9 @@ async def create_knowledge_tag(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -528,9 +527,9 @@ async def delete_knowledge_tag(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -588,9 +587,9 @@ async def update_knowledge_tag(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -640,9 +639,9 @@ async def bind_dataset_to_tag(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -692,9 +691,9 @@ async def unbind_dataset_from_tag(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -741,9 +740,9 @@ async def get_dataset_tags(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
diff --git a/src/dify_sdk/workflow/__init__.py b/src/dify_sdk/workflow/__init__.py
index de3f5a5..9e9f9c0 100644
--- a/src/dify_sdk/workflow/__init__.py
+++ b/src/dify_sdk/workflow/__init__.py
@@ -41,6 +41,7 @@
GetWorkflowLogsResponseDataItemWorkflowRun,
GetWorkflowLogsResponseDataItemWorkflowRunStatus,
RetrieverResource,
+ RunSpecificWorkflowRequestResponseMode,
RunWorkflowRequestResponseMode,
StopWorkflowResponse,
UploadFileResponse,
@@ -52,6 +53,7 @@
from .errors import (
BadRequestError,
ContentTooLargeError,
+ ForbiddenError,
InternalServerError,
NotFoundError,
ServiceUnavailableError,
@@ -72,6 +74,7 @@
"FileInput",
"FileInputTransferMethod",
"FileInputType",
+ "ForbiddenError",
"GetAppInfoResponse",
"GetAppParametersResponse",
"GetAppParametersResponseFileUpload",
@@ -102,6 +105,7 @@
"InternalServerError",
"NotFoundError",
"RetrieverResource",
+ "RunSpecificWorkflowRequestResponseMode",
"RunWorkflowRequestResponseMode",
"ServiceUnavailableError",
"StopWorkflowResponse",
diff --git a/src/dify_sdk/workflow/client.py b/src/dify_sdk/workflow/client.py
index d81da41..be83cb7 100644
--- a/src/dify_sdk/workflow/client.py
+++ b/src/dify_sdk/workflow/client.py
@@ -13,6 +13,7 @@
from .types.get_workflow_execution_status_response import GetWorkflowExecutionStatusResponse
from .types.get_workflow_logs_request_status import GetWorkflowLogsRequestStatus
from .types.get_workflow_logs_response import GetWorkflowLogsResponse
+from .types.run_specific_workflow_request_response_mode import RunSpecificWorkflowRequestResponseMode
from .types.run_workflow_request_response_mode import RunWorkflowRequestResponseMode
from .types.stop_workflow_response import StopWorkflowResponse
from .types.upload_file_response import UploadFileResponse
@@ -111,6 +112,86 @@ def run_workflow(
) as r:
yield from r.data
+ def run_specific_workflow(
+ self,
+ workflow_id: str,
+ *,
+ inputs: typing.Dict[str, typing.Optional[typing.Any]],
+ response_mode: RunSpecificWorkflowRequestResponseMode,
+ user: str,
+ files: typing.Optional[typing.Sequence[typing.Dict[str, typing.Optional[typing.Any]]]] = OMIT,
+ trace_id: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> typing.Iterator[ChunkWorkflowMessage]:
+ """
+ Execute a specific version of the workflow, specifying the workflow ID through the path parameter
+
+ Parameters
+ ----------
+ workflow_id : str
+ Workflow ID, used to specify a specific version of the workflow. How to obtain: You can query the specific version workflow ID in the version history.
+
+ inputs : typing.Dict[str, typing.Optional[typing.Any]]
+ Allows passing values for variables defined in the App.
+ The inputs parameter contains multiple key/value pairs, where each key corresponds to a specific variable and each value is the specific value for that variable. Variables can be of file list type.
+ File list type variables are suitable for passing files combined with text understanding to answer questions, only available when the model supports parsing capabilities for that type of file. If the variable is a file list type, the value corresponding to the variable should be in list format, where each element should include the following:
+ - `type` (string) Supported types:
+ - `document` Specific types include: 'TXT', 'MD', 'MARKDOWN', 'PDF', 'HTML', 'XLSX', 'XLS', 'DOCX', 'CSV', 'EML', 'MSG', 'PPTX', 'PPT', 'XML', 'EPUB'
+ - `image` Specific types include: 'JPG', 'JPEG', 'PNG', 'GIF', 'WEBP', 'SVG'
+ - `audio` Specific types include: 'MP3', 'M4A', 'WAV', 'WEBM', 'AMR'
+ - `video` Specific types include: 'MP4', 'MOV', 'MPEG', 'MPGA'
+ - `custom` Specific types include: other file types
+ - `transfer_method` (string) Transfer method, `remote_url` image address / `local_file` uploaded file
+ - `url` (string) Image address (only when the transfer method is `remote_url`)
+ - `upload_file_id` (string) Upload file ID (only when the transfer method is `local_file`)
+
+ response_mode : RunSpecificWorkflowRequestResponseMode
+ Response mode, supports:
+ - `streaming` Streaming mode (recommended). Implements streaming return similar to typewriter output based on SSE (Server-Sent Events).
+ - `blocking` Blocking mode, waits for execution to complete before returning results. (Requests may be interrupted if the process is lengthy).
+ Due to Cloudflare limitations, requests will be interrupted after 100 seconds of timeout with no response.
+
+ user : str
+ User identifier, used to define the identity of the end user, for easy retrieval and statistics.
+ Rules defined by the developer, the user identifier must be unique within the application. API cannot access sessions created by WebApp.
+
+ files : typing.Optional[typing.Sequence[typing.Dict[str, typing.Optional[typing.Any]]]]
+ Optional file list
+
+ trace_id : typing.Optional[str]
+ Tracing ID. Suitable for integrating with existing trace components in business systems to achieve end-to-end distributed tracing. If not specified, the system will automatically generate a `trace_id`. Supports the following three transmission methods, with priorities as follows:
+ 1. Header: Recommended to pass through HTTP Header `X-Trace-Id`, highest priority.
+ 2. Query parameter: Pass through URL query parameter `trace_id`.
+ 3. Request Body: Pass through request body field `trace_id` (this field).
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Yields
+ ------
+ typing.Iterator[ChunkWorkflowMessage]
+ Successful response
+
+ Examples
+ --------
+ from dify import DifyApi
+ client = DifyApi(token="YOUR_TOKEN", )
+ response = client.workflow.run_specific_workflow(workflow_id='workflow_id', inputs={'key': 'value'
+ }, response_mode="streaming", user='user', )
+ for chunk in response:
+ yield chunk
+ """
+ with self._raw_client.run_specific_workflow(
+ workflow_id,
+ inputs=inputs,
+ response_mode=response_mode,
+ user=user,
+ files=files,
+ trace_id=trace_id,
+ request_options=request_options,
+ ) as r:
+ yield from r.data
+
def get_workflow_execution_status(
self, workflow_run_id: str, *, request_options: typing.Optional[RequestOptions] = None
) -> GetWorkflowExecutionStatusResponse:
@@ -260,6 +341,35 @@ def upload_file(
_response = self._raw_client.upload_file(file=file, user=user, request_options=request_options)
return _response.data
+ def preview_file(
+ self,
+ file_id: str,
+ *,
+ as_attachment: typing.Optional[bool] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> typing.Iterator[bytes]:
+ """
+ Preview or download uploaded files. This endpoint allows you to access files previously uploaded through the file upload API. Files can only be accessed within the message scope belonging to the requesting application.
+
+ Parameters
+ ----------
+ file_id : str
+ Unique identifier of the file to preview, obtained from the file upload API response
+
+ as_attachment : typing.Optional[bool]
+ Whether to force the file to be downloaded as an attachment. Defaults to `false` (preview in browser)
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration. You can pass in configuration such as `chunk_size`, and more to customize the request and response.
+
+ Returns
+ -------
+ typing.Iterator[bytes]
+ Successfully retrieved file content
+ """
+ with self._raw_client.preview_file(file_id, as_attachment=as_attachment, request_options=request_options) as r:
+ yield from r.data
+
def get_app_info(self, *, request_options: typing.Optional[RequestOptions] = None) -> GetAppInfoResponse:
"""
Used to get basic information about the application
@@ -426,6 +536,90 @@ async def main() -> None:
async for data in r.data:
yield data
+ async def run_specific_workflow(
+ self,
+ workflow_id: str,
+ *,
+ inputs: typing.Dict[str, typing.Optional[typing.Any]],
+ response_mode: RunSpecificWorkflowRequestResponseMode,
+ user: str,
+ files: typing.Optional[typing.Sequence[typing.Dict[str, typing.Optional[typing.Any]]]] = OMIT,
+ trace_id: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> typing.AsyncIterator[ChunkWorkflowMessage]:
+ """
+ Execute a specific version of the workflow, specifying the workflow ID through the path parameter
+
+ Parameters
+ ----------
+ workflow_id : str
+ Workflow ID, used to specify a specific version of the workflow. How to obtain: You can query the specific version workflow ID in the version history.
+
+ inputs : typing.Dict[str, typing.Optional[typing.Any]]
+ Allows passing values for variables defined in the App.
+ The inputs parameter contains multiple key/value pairs, where each key corresponds to a specific variable and each value is the specific value for that variable. Variables can be of file list type.
+ File list type variables are suitable for passing files combined with text understanding to answer questions, only available when the model supports parsing capabilities for that type of file. If the variable is a file list type, the value corresponding to the variable should be in list format, where each element should include the following:
+ - `type` (string) Supported types:
+ - `document` Specific types include: 'TXT', 'MD', 'MARKDOWN', 'PDF', 'HTML', 'XLSX', 'XLS', 'DOCX', 'CSV', 'EML', 'MSG', 'PPTX', 'PPT', 'XML', 'EPUB'
+ - `image` Specific types include: 'JPG', 'JPEG', 'PNG', 'GIF', 'WEBP', 'SVG'
+ - `audio` Specific types include: 'MP3', 'M4A', 'WAV', 'WEBM', 'AMR'
+ - `video` Specific types include: 'MP4', 'MOV', 'MPEG', 'MPGA'
+ - `custom` Specific types include: other file types
+ - `transfer_method` (string) Transfer method, `remote_url` image address / `local_file` uploaded file
+ - `url` (string) Image address (only when the transfer method is `remote_url`)
+ - `upload_file_id` (string) Upload file ID (only when the transfer method is `local_file`)
+
+ response_mode : RunSpecificWorkflowRequestResponseMode
+ Response mode, supports:
+ - `streaming` Streaming mode (recommended). Implements streaming return similar to typewriter output based on SSE (Server-Sent Events).
+ - `blocking` Blocking mode, waits for execution to complete before returning results. (Requests may be interrupted if the process is lengthy).
+ Due to Cloudflare limitations, requests will be interrupted after 100 seconds of timeout with no response.
+
+ user : str
+ User identifier, used to define the identity of the end user, for easy retrieval and statistics.
+ Rules defined by the developer, the user identifier must be unique within the application. API cannot access sessions created by WebApp.
+
+ files : typing.Optional[typing.Sequence[typing.Dict[str, typing.Optional[typing.Any]]]]
+ Optional file list
+
+ trace_id : typing.Optional[str]
+ Tracing ID. Suitable for integrating with existing trace components in business systems to achieve end-to-end distributed tracing. If not specified, the system will automatically generate a `trace_id`. Supports the following three transmission methods, with priorities as follows:
+ 1. Header: Recommended to pass through HTTP Header `X-Trace-Id`, highest priority.
+ 2. Query parameter: Pass through URL query parameter `trace_id`.
+ 3. Request Body: Pass through request body field `trace_id` (this field).
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Yields
+ ------
+ typing.AsyncIterator[ChunkWorkflowMessage]
+ Successful response
+
+ Examples
+ --------
+ from dify import AsyncDifyApi
+ import asyncio
+ client = AsyncDifyApi(token="YOUR_TOKEN", )
+ async def main() -> None:
+ response = await client.workflow.run_specific_workflow(workflow_id='workflow_id', inputs={'key': 'value'
+ }, response_mode="streaming", user='user', )
+ async for chunk in response:
+ yield chunk
+ asyncio.run(main())
+ """
+ async with self._raw_client.run_specific_workflow(
+ workflow_id,
+ inputs=inputs,
+ response_mode=response_mode,
+ user=user,
+ files=files,
+ trace_id=trace_id,
+ request_options=request_options,
+ ) as r:
+ async for data in r.data:
+ yield data
+
async def get_workflow_execution_status(
self, workflow_run_id: str, *, request_options: typing.Optional[RequestOptions] = None
) -> GetWorkflowExecutionStatusResponse:
@@ -589,6 +783,38 @@ async def main() -> None:
_response = await self._raw_client.upload_file(file=file, user=user, request_options=request_options)
return _response.data
+ async def preview_file(
+ self,
+ file_id: str,
+ *,
+ as_attachment: typing.Optional[bool] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> typing.AsyncIterator[bytes]:
+ """
+ Preview or download uploaded files. This endpoint allows you to access files previously uploaded through the file upload API. Files can only be accessed within the message scope belonging to the requesting application.
+
+ Parameters
+ ----------
+ file_id : str
+ Unique identifier of the file to preview, obtained from the file upload API response
+
+ as_attachment : typing.Optional[bool]
+ Whether to force the file to be downloaded as an attachment. Defaults to `false` (preview in browser)
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration. You can pass in configuration such as `chunk_size`, and more to customize the request and response.
+
+ Returns
+ -------
+ typing.AsyncIterator[bytes]
+ Successfully retrieved file content
+ """
+ async with self._raw_client.preview_file(
+ file_id, as_attachment=as_attachment, request_options=request_options
+ ) as r:
+ async for data in r.data:
+ yield data
+
async def get_app_info(self, *, request_options: typing.Optional[RequestOptions] = None) -> GetAppInfoResponse:
"""
Used to get basic information about the application
diff --git a/src/dify_sdk/workflow/errors/__init__.py b/src/dify_sdk/workflow/errors/__init__.py
index ccae61f..4b2a0bb 100644
--- a/src/dify_sdk/workflow/errors/__init__.py
+++ b/src/dify_sdk/workflow/errors/__init__.py
@@ -4,6 +4,7 @@
from .bad_request_error import BadRequestError
from .content_too_large_error import ContentTooLargeError
+from .forbidden_error import ForbiddenError
from .internal_server_error import InternalServerError
from .not_found_error import NotFoundError
from .service_unavailable_error import ServiceUnavailableError
@@ -13,6 +14,7 @@
__all__ = [
"BadRequestError",
"ContentTooLargeError",
+ "ForbiddenError",
"InternalServerError",
"NotFoundError",
"ServiceUnavailableError",
diff --git a/src/dify_sdk/workflow/errors/bad_request_error.py b/src/dify_sdk/workflow/errors/bad_request_error.py
index 5ccb07c..c1e658e 100644
--- a/src/dify_sdk/workflow/errors/bad_request_error.py
+++ b/src/dify_sdk/workflow/errors/bad_request_error.py
@@ -1,9 +1,10 @@
# This file was auto-generated by Fern from our API Definition.
+import typing
+
from ...core.api_error import ApiError
-from ..types.error import Error
class BadRequestError(ApiError):
- def __init__(self, body: Error):
+ def __init__(self, body: typing.Optional[typing.Any]):
super().__init__(status_code=400, body=body)
diff --git a/src/dify_sdk/workflow/errors/forbidden_error.py b/src/dify_sdk/workflow/errors/forbidden_error.py
new file mode 100644
index 0000000..674d6b9
--- /dev/null
+++ b/src/dify_sdk/workflow/errors/forbidden_error.py
@@ -0,0 +1,10 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+from ...core.api_error import ApiError
+
+
+class ForbiddenError(ApiError):
+ def __init__(self, body: typing.Optional[typing.Any]):
+ super().__init__(status_code=403, body=body)
diff --git a/src/dify_sdk/workflow/raw_client.py b/src/dify_sdk/workflow/raw_client.py
index 718c3f2..1c28fae 100644
--- a/src/dify_sdk/workflow/raw_client.py
+++ b/src/dify_sdk/workflow/raw_client.py
@@ -5,6 +5,7 @@
import typing
from json.decoder import JSONDecodeError
+import httpx_sse
from .. import core
from ..core.api_error import ApiError
from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
@@ -14,6 +15,7 @@
from ..core.request_options import RequestOptions
from .errors.bad_request_error import BadRequestError
from .errors.content_too_large_error import ContentTooLargeError
+from .errors.forbidden_error import ForbiddenError
from .errors.internal_server_error import InternalServerError
from .errors.not_found_error import NotFoundError
from .errors.service_unavailable_error import ServiceUnavailableError
@@ -27,6 +29,7 @@
from .types.get_workflow_execution_status_response import GetWorkflowExecutionStatusResponse
from .types.get_workflow_logs_request_status import GetWorkflowLogsRequestStatus
from .types.get_workflow_logs_response import GetWorkflowLogsResponse
+from .types.run_specific_workflow_request_response_mode import RunSpecificWorkflowRequestResponseMode
from .types.run_workflow_request_response_mode import RunWorkflowRequestResponseMode
from .types.stop_workflow_response import StopWorkflowResponse
from .types.upload_file_response import UploadFileResponse
@@ -139,6 +142,26 @@ def _iter():
_response.read()
if _response.status_code == 400:
raise BadRequestError(
+ typing.cast(
+ typing.Optional[typing.Any],
+ parse_obj_as(
+ type_=typing.Optional[typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ if _response.status_code == 404:
+ raise NotFoundError(
+ typing.cast(
+ typing.Optional[typing.Any],
+ parse_obj_as(
+ type_=typing.Optional[typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ if _response.status_code == 500:
+ raise InternalServerError(
typing.cast(
Error,
parse_obj_as(
@@ -147,6 +170,120 @@ def _iter():
),
)
)
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(
+ headers=dict(_response.headers), status_code=_response.status_code, body=_response.text
+ )
+ raise ApiError(headers=dict(_response.headers), status_code=_response.status_code, body=_response_json)
+
+ yield stream()
+
+ @contextlib.contextmanager
+ def run_specific_workflow(
+ self,
+ workflow_id: str,
+ *,
+ inputs: typing.Dict[str, typing.Optional[typing.Any]],
+ response_mode: RunSpecificWorkflowRequestResponseMode,
+ user: str,
+ files: typing.Optional[typing.Sequence[typing.Dict[str, typing.Optional[typing.Any]]]] = OMIT,
+ trace_id: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> typing.Iterator[HttpResponse[typing.Iterator[ChunkWorkflowMessage]]]:
+ """
+ Execute a specific version of the workflow, specifying the workflow ID through the path parameter
+
+ Parameters
+ ----------
+ workflow_id : str
+ Workflow ID, used to specify a specific version of the workflow. How to obtain: You can query the specific version workflow ID in the version history.
+
+ inputs : typing.Dict[str, typing.Optional[typing.Any]]
+ Allows passing values for variables defined in the App.
+ The inputs parameter contains multiple key/value pairs, where each key corresponds to a specific variable and each value is the specific value for that variable. Variables can be of file list type.
+ File list type variables are suitable for passing files combined with text understanding to answer questions, only available when the model supports parsing capabilities for that type of file. If the variable is a file list type, the value corresponding to the variable should be in list format, where each element should include the following:
+ - `type` (string) Supported types:
+ - `document` Specific types include: 'TXT', 'MD', 'MARKDOWN', 'PDF', 'HTML', 'XLSX', 'XLS', 'DOCX', 'CSV', 'EML', 'MSG', 'PPTX', 'PPT', 'XML', 'EPUB'
+ - `image` Specific types include: 'JPG', 'JPEG', 'PNG', 'GIF', 'WEBP', 'SVG'
+ - `audio` Specific types include: 'MP3', 'M4A', 'WAV', 'WEBM', 'AMR'
+ - `video` Specific types include: 'MP4', 'MOV', 'MPEG', 'MPGA'
+ - `custom` Specific types include: other file types
+ - `transfer_method` (string) Transfer method, `remote_url` image address / `local_file` uploaded file
+ - `url` (string) Image address (only when the transfer method is `remote_url`)
+ - `upload_file_id` (string) Upload file ID (only when the transfer method is `local_file`)
+
+ response_mode : RunSpecificWorkflowRequestResponseMode
+ Response mode, supports:
+ - `streaming` Streaming mode (recommended). Implements streaming return similar to typewriter output based on SSE (Server-Sent Events).
+ - `blocking` Blocking mode, waits for execution to complete before returning results. (Requests may be interrupted if the process is lengthy).
+ Due to Cloudflare limitations, requests will be interrupted after 100 seconds of timeout with no response.
+
+ user : str
+ User identifier, used to define the identity of the end user, for easy retrieval and statistics.
+ Rules defined by the developer, the user identifier must be unique within the application. API cannot access sessions created by WebApp.
+
+ files : typing.Optional[typing.Sequence[typing.Dict[str, typing.Optional[typing.Any]]]]
+ Optional file list
+
+ trace_id : typing.Optional[str]
+ Tracing ID. Suitable for integrating with existing trace components in business systems to achieve end-to-end distributed tracing. If not specified, the system will automatically generate a `trace_id`. Supports the following three transmission methods, with priorities as follows:
+ 1. Header: Recommended to pass through HTTP Header `X-Trace-Id`, highest priority.
+ 2. Query parameter: Pass through URL query parameter `trace_id`.
+ 3. Request Body: Pass through request body field `trace_id` (this field).
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Yields
+ ------
+ typing.Iterator[HttpResponse[typing.Iterator[ChunkWorkflowMessage]]]
+ Successful response
+ """
+ with self._client_wrapper.httpx_client.stream(
+ f"workflows/{jsonable_encoder(workflow_id)}/run",
+ method="POST",
+ json={
+ "inputs": inputs,
+ "response_mode": response_mode,
+ "user": user,
+ "files": files,
+ "trace_id": trace_id,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ ) as _response:
+
+ def stream() -> HttpResponse[typing.Iterator[ChunkWorkflowMessage]]:
+ try:
+ if 200 <= _response.status_code < 300:
+
+ def _iter():
+ _event_source = httpx_sse.EventSource(_response)
+ for _sse in _event_source.iter_sse():
+ if _sse.data == None:
+ return
+ try:
+ yield _sse.data
+ except Exception:
+ pass
+ return
+
+ return HttpResponse(response=_response, data=_iter())
+ _response.read()
+ if _response.status_code == 400:
+ raise BadRequestError(
+ typing.cast(
+ typing.Optional[typing.Any],
+ parse_obj_as(
+ type_=typing.Optional[typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
if _response.status_code == 404:
raise NotFoundError(
typing.cast(
@@ -213,9 +350,9 @@ def get_workflow_execution_status(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -302,9 +439,9 @@ def stop_workflow(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -412,9 +549,9 @@ def get_workflow_logs(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -504,9 +641,9 @@ def upload_file(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -566,6 +703,99 @@ def upload_file(
raise ApiError(headers=dict(_response.headers), status_code=_response.status_code, body=_response.text)
raise ApiError(headers=dict(_response.headers), status_code=_response.status_code, body=_response_json)
+ @contextlib.contextmanager
+ def preview_file(
+ self,
+ file_id: str,
+ *,
+ as_attachment: typing.Optional[bool] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> typing.Iterator[HttpResponse[typing.Iterator[bytes]]]:
+ """
+ Preview or download uploaded files. This endpoint allows you to access files previously uploaded through the file upload API. Files can only be accessed within the message scope belonging to the requesting application.
+
+ Parameters
+ ----------
+ file_id : str
+ Unique identifier of the file to preview, obtained from the file upload API response
+
+ as_attachment : typing.Optional[bool]
+ Whether to force the file to be downloaded as an attachment. Defaults to `false` (preview in browser)
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration. You can pass in configuration such as `chunk_size`, and more to customize the request and response.
+
+ Returns
+ -------
+ typing.Iterator[HttpResponse[typing.Iterator[bytes]]]
+ Successfully retrieved file content
+ """
+ with self._client_wrapper.httpx_client.stream(
+ f"files/{jsonable_encoder(file_id)}/preview",
+ method="GET",
+ params={
+ "as_attachment": as_attachment,
+ },
+ request_options=request_options,
+ ) as _response:
+
+ def stream() -> HttpResponse[typing.Iterator[bytes]]:
+ try:
+ if 200 <= _response.status_code < 300:
+ _chunk_size = request_options.get("chunk_size", None) if request_options is not None else None
+ return HttpResponse(
+ response=_response, data=(_chunk for _chunk in _response.iter_bytes(chunk_size=_chunk_size))
+ )
+ _response.read()
+ if _response.status_code == 400:
+ raise BadRequestError(
+ typing.cast(
+ typing.Optional[typing.Any],
+ parse_obj_as(
+ type_=typing.Optional[typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ if _response.status_code == 403:
+ raise ForbiddenError(
+ typing.cast(
+ typing.Optional[typing.Any],
+ parse_obj_as(
+ type_=typing.Optional[typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ if _response.status_code == 404:
+ raise NotFoundError(
+ typing.cast(
+ typing.Optional[typing.Any],
+ parse_obj_as(
+ type_=typing.Optional[typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ if _response.status_code == 500:
+ raise InternalServerError(
+ typing.cast(
+ Error,
+ parse_obj_as(
+ type_=Error, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(
+ headers=dict(_response.headers), status_code=_response.status_code, body=_response.text
+ )
+ raise ApiError(headers=dict(_response.headers), status_code=_response.status_code, body=_response_json)
+
+ yield stream()
+
def get_app_info(
self, *, request_options: typing.Optional[RequestOptions] = None
) -> HttpResponse[GetAppInfoResponse]:
@@ -600,9 +830,9 @@ def get_app_info(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -676,9 +906,9 @@ def get_app_parameters(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -752,9 +982,9 @@ def get_app_site(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -899,6 +1129,26 @@ async def _iter():
await _response.aread()
if _response.status_code == 400:
raise BadRequestError(
+ typing.cast(
+ typing.Optional[typing.Any],
+ parse_obj_as(
+ type_=typing.Optional[typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ if _response.status_code == 404:
+ raise NotFoundError(
+ typing.cast(
+ typing.Optional[typing.Any],
+ parse_obj_as(
+ type_=typing.Optional[typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ if _response.status_code == 500:
+ raise InternalServerError(
typing.cast(
Error,
parse_obj_as(
@@ -907,6 +1157,120 @@ async def _iter():
),
)
)
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(
+ headers=dict(_response.headers), status_code=_response.status_code, body=_response.text
+ )
+ raise ApiError(headers=dict(_response.headers), status_code=_response.status_code, body=_response_json)
+
+ yield await stream()
+
+ @contextlib.asynccontextmanager
+ async def run_specific_workflow(
+ self,
+ workflow_id: str,
+ *,
+ inputs: typing.Dict[str, typing.Optional[typing.Any]],
+ response_mode: RunSpecificWorkflowRequestResponseMode,
+ user: str,
+ files: typing.Optional[typing.Sequence[typing.Dict[str, typing.Optional[typing.Any]]]] = OMIT,
+ trace_id: typing.Optional[str] = OMIT,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> typing.AsyncIterator[AsyncHttpResponse[typing.AsyncIterator[ChunkWorkflowMessage]]]:
+ """
+ Execute a specific version of the workflow, specifying the workflow ID through the path parameter
+
+ Parameters
+ ----------
+ workflow_id : str
+ Workflow ID, used to specify a specific version of the workflow. How to obtain: You can query the specific version workflow ID in the version history.
+
+ inputs : typing.Dict[str, typing.Optional[typing.Any]]
+ Allows passing values for variables defined in the App.
+ The inputs parameter contains multiple key/value pairs, where each key corresponds to a specific variable and each value is the specific value for that variable. Variables can be of file list type.
+ File list type variables are suitable for passing files combined with text understanding to answer questions, only available when the model supports parsing capabilities for that type of file. If the variable is a file list type, the value corresponding to the variable should be in list format, where each element should include the following:
+ - `type` (string) Supported types:
+ - `document` Specific types include: 'TXT', 'MD', 'MARKDOWN', 'PDF', 'HTML', 'XLSX', 'XLS', 'DOCX', 'CSV', 'EML', 'MSG', 'PPTX', 'PPT', 'XML', 'EPUB'
+ - `image` Specific types include: 'JPG', 'JPEG', 'PNG', 'GIF', 'WEBP', 'SVG'
+ - `audio` Specific types include: 'MP3', 'M4A', 'WAV', 'WEBM', 'AMR'
+ - `video` Specific types include: 'MP4', 'MOV', 'MPEG', 'MPGA'
+ - `custom` Specific types include: other file types
+ - `transfer_method` (string) Transfer method, `remote_url` image address / `local_file` uploaded file
+ - `url` (string) Image address (only when the transfer method is `remote_url`)
+ - `upload_file_id` (string) Upload file ID (only when the transfer method is `local_file`)
+
+ response_mode : RunSpecificWorkflowRequestResponseMode
+ Response mode, supports:
+ - `streaming` Streaming mode (recommended). Implements streaming return similar to typewriter output based on SSE (Server-Sent Events).
+ - `blocking` Blocking mode, waits for execution to complete before returning results. (Requests may be interrupted if the process is lengthy).
+ Due to Cloudflare limitations, requests will be interrupted after 100 seconds of timeout with no response.
+
+ user : str
+ User identifier, used to define the identity of the end user, for easy retrieval and statistics.
+ Rules defined by the developer, the user identifier must be unique within the application. API cannot access sessions created by WebApp.
+
+ files : typing.Optional[typing.Sequence[typing.Dict[str, typing.Optional[typing.Any]]]]
+ Optional file list
+
+ trace_id : typing.Optional[str]
+ Tracing ID. Suitable for integrating with existing trace components in business systems to achieve end-to-end distributed tracing. If not specified, the system will automatically generate a `trace_id`. Supports the following three transmission methods, with priorities as follows:
+ 1. Header: Recommended to pass through HTTP Header `X-Trace-Id`, highest priority.
+ 2. Query parameter: Pass through URL query parameter `trace_id`.
+ 3. Request Body: Pass through request body field `trace_id` (this field).
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration.
+
+ Yields
+ ------
+ typing.AsyncIterator[AsyncHttpResponse[typing.AsyncIterator[ChunkWorkflowMessage]]]
+ Successful response
+ """
+ async with self._client_wrapper.httpx_client.stream(
+ f"workflows/{jsonable_encoder(workflow_id)}/run",
+ method="POST",
+ json={
+ "inputs": inputs,
+ "response_mode": response_mode,
+ "user": user,
+ "files": files,
+ "trace_id": trace_id,
+ },
+ headers={
+ "content-type": "application/json",
+ },
+ request_options=request_options,
+ omit=OMIT,
+ ) as _response:
+
+ async def stream() -> AsyncHttpResponse[typing.AsyncIterator[ChunkWorkflowMessage]]:
+ try:
+ if 200 <= _response.status_code < 300:
+
+ async def _iter():
+ _event_source = httpx_sse.EventSource(_response)
+ async for _sse in _event_source.aiter_sse():
+ if _sse.data == None:
+ return
+ try:
+ yield _sse.data
+ except Exception:
+ pass
+ return
+
+ return AsyncHttpResponse(response=_response, data=_iter())
+ await _response.aread()
+ if _response.status_code == 400:
+ raise BadRequestError(
+ typing.cast(
+ typing.Optional[typing.Any],
+ parse_obj_as(
+ type_=typing.Optional[typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
if _response.status_code == 404:
raise NotFoundError(
typing.cast(
@@ -973,9 +1337,9 @@ async def get_workflow_execution_status(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -1062,9 +1426,9 @@ async def stop_workflow(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -1172,9 +1536,9 @@ async def get_workflow_logs(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -1264,9 +1628,9 @@ async def upload_file(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -1326,6 +1690,100 @@ async def upload_file(
raise ApiError(headers=dict(_response.headers), status_code=_response.status_code, body=_response.text)
raise ApiError(headers=dict(_response.headers), status_code=_response.status_code, body=_response_json)
+ @contextlib.asynccontextmanager
+ async def preview_file(
+ self,
+ file_id: str,
+ *,
+ as_attachment: typing.Optional[bool] = None,
+ request_options: typing.Optional[RequestOptions] = None,
+ ) -> typing.AsyncIterator[AsyncHttpResponse[typing.AsyncIterator[bytes]]]:
+ """
+ Preview or download uploaded files. This endpoint allows you to access files previously uploaded through the file upload API. Files can only be accessed within the message scope belonging to the requesting application.
+
+ Parameters
+ ----------
+ file_id : str
+ Unique identifier of the file to preview, obtained from the file upload API response
+
+ as_attachment : typing.Optional[bool]
+ Whether to force the file to be downloaded as an attachment. Defaults to `false` (preview in browser)
+
+ request_options : typing.Optional[RequestOptions]
+ Request-specific configuration. You can pass in configuration such as `chunk_size`, and more to customize the request and response.
+
+ Returns
+ -------
+ typing.AsyncIterator[AsyncHttpResponse[typing.AsyncIterator[bytes]]]
+ Successfully retrieved file content
+ """
+ async with self._client_wrapper.httpx_client.stream(
+ f"files/{jsonable_encoder(file_id)}/preview",
+ method="GET",
+ params={
+ "as_attachment": as_attachment,
+ },
+ request_options=request_options,
+ ) as _response:
+
+ async def stream() -> AsyncHttpResponse[typing.AsyncIterator[bytes]]:
+ try:
+ if 200 <= _response.status_code < 300:
+ _chunk_size = request_options.get("chunk_size", None) if request_options is not None else None
+ return AsyncHttpResponse(
+ response=_response,
+ data=(_chunk async for _chunk in _response.aiter_bytes(chunk_size=_chunk_size)),
+ )
+ await _response.aread()
+ if _response.status_code == 400:
+ raise BadRequestError(
+ typing.cast(
+ typing.Optional[typing.Any],
+ parse_obj_as(
+ type_=typing.Optional[typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ if _response.status_code == 403:
+ raise ForbiddenError(
+ typing.cast(
+ typing.Optional[typing.Any],
+ parse_obj_as(
+ type_=typing.Optional[typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ if _response.status_code == 404:
+ raise NotFoundError(
+ typing.cast(
+ typing.Optional[typing.Any],
+ parse_obj_as(
+ type_=typing.Optional[typing.Any], # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ if _response.status_code == 500:
+ raise InternalServerError(
+ typing.cast(
+ Error,
+ parse_obj_as(
+ type_=Error, # type: ignore
+ object_=_response.json(),
+ ),
+ )
+ )
+ _response_json = _response.json()
+ except JSONDecodeError:
+ raise ApiError(
+ headers=dict(_response.headers), status_code=_response.status_code, body=_response.text
+ )
+ raise ApiError(headers=dict(_response.headers), status_code=_response.status_code, body=_response_json)
+
+ yield await stream()
+
async def get_app_info(
self, *, request_options: typing.Optional[RequestOptions] = None
) -> AsyncHttpResponse[GetAppInfoResponse]:
@@ -1360,9 +1818,9 @@ async def get_app_info(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -1436,9 +1894,9 @@ async def get_app_parameters(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
@@ -1512,9 +1970,9 @@ async def get_app_site(
if _response.status_code == 400:
raise BadRequestError(
typing.cast(
- Error,
+ typing.Optional[typing.Any],
parse_obj_as(
- type_=Error, # type: ignore
+ type_=typing.Optional[typing.Any], # type: ignore
object_=_response.json(),
),
)
diff --git a/src/dify_sdk/workflow/types/__init__.py b/src/dify_sdk/workflow/types/__init__.py
index ce5ac8c..6efb149 100644
--- a/src/dify_sdk/workflow/types/__init__.py
+++ b/src/dify_sdk/workflow/types/__init__.py
@@ -54,6 +54,7 @@
from .get_workflow_logs_response_data_item_workflow_run import GetWorkflowLogsResponseDataItemWorkflowRun
from .get_workflow_logs_response_data_item_workflow_run_status import GetWorkflowLogsResponseDataItemWorkflowRunStatus
from .retriever_resource import RetrieverResource
+from .run_specific_workflow_request_response_mode import RunSpecificWorkflowRequestResponseMode
from .run_workflow_request_response_mode import RunWorkflowRequestResponseMode
from .stop_workflow_response import StopWorkflowResponse
from .upload_file_response import UploadFileResponse
@@ -101,6 +102,7 @@
"GetWorkflowLogsResponseDataItemWorkflowRun",
"GetWorkflowLogsResponseDataItemWorkflowRunStatus",
"RetrieverResource",
+ "RunSpecificWorkflowRequestResponseMode",
"RunWorkflowRequestResponseMode",
"StopWorkflowResponse",
"UploadFileResponse",
diff --git a/src/dify_sdk/workflow/types/run_specific_workflow_request_response_mode.py b/src/dify_sdk/workflow/types/run_specific_workflow_request_response_mode.py
new file mode 100644
index 0000000..e1f5f39
--- /dev/null
+++ b/src/dify_sdk/workflow/types/run_specific_workflow_request_response_mode.py
@@ -0,0 +1,5 @@
+# This file was auto-generated by Fern from our API Definition.
+
+import typing
+
+RunSpecificWorkflowRequestResponseMode = typing.Union[typing.Literal["streaming", "blocking"], typing.Any]
diff --git a/uv.lock b/uv.lock
index f434d81..0ce68f2 100644
--- a/uv.lock
+++ b/uv.lock
@@ -1,5 +1,5 @@
version = 1
-revision = 2
+revision = 3
requires-python = ">=3.9"
resolution-markers = [
"python_full_version >= '3.13'",
@@ -158,7 +158,7 @@ wheels = [
[[package]]
name = "dify-openapi"
-version = "1.7.1"
+version = "1.7.2"
source = { editable = "." }
dependencies = [
{ name = "httpx" },