mirror of
https://github.com/langgenius/dify-docs.git
synced 2026-03-27 13:28:32 +07:00
refine docs
This commit is contained in:
@@ -7,63 +7,148 @@ dimensions:
|
||||
standard_title: Persistent Storage KV
|
||||
language: en
|
||||
title: Persistent Storage
|
||||
description: This document introduces the persistent storage functionality in Dify
|
||||
plugins, detailing how to use the KV database in plugins to store, retrieve, and
|
||||
delete data. This feature enables plugins to persistently store data within the
|
||||
same Workspace, meeting the needs for data preservation across sessions.
|
||||
description: Learn how to implement persistent storage in your Dify plugins using the built-in key-value database to maintain state across interactions.
|
||||
---
|
||||
|
||||
When examining Tools and Endpoints in plugins individually, it's not difficult to see that in most cases, they can only complete single-round interactions: request, return data, and the task ends.
|
||||
## Overview
|
||||
|
||||
If there is data that needs to be stored long-term, such as implementing persistent memory, the plugin needs to have persistent storage capabilities. **The persistent storage mechanism allows plugins to have the ability to persistently store data within the same Workspace**. Currently, a KV database is provided to meet storage needs, and more flexible and powerful storage interfaces may be introduced in the future based on actual usage.
|
||||
Most plugin tools and endpoints operate in a stateless, single-round interaction model:
|
||||
1. Receive a request
|
||||
2. Process data
|
||||
3. Return a response
|
||||
4. End the interaction
|
||||
|
||||
### Storing Keys
|
||||
However, many real-world applications require maintaining state across multiple interactions. This is where **persistent storage** becomes essential.
|
||||
|
||||
#### **Entry Point**
|
||||
<Info>
|
||||
The persistent storage mechanism allows plugins to store data persistently within the same workspace, enabling stateful applications and memory features.
|
||||
</Info>
|
||||
|
||||
Dify currently provides a key-value (KV) storage system for plugins, with plans to introduce more flexible and powerful storage interfaces in the future based on developer needs.
|
||||
|
||||
## Accessing Storage
|
||||
|
||||
All storage operations are performed through the `storage` object available in your plugin's session:
|
||||
|
||||
```python
|
||||
self.session.storage
|
||||
# Access the storage interface
|
||||
storage = self.session.storage
|
||||
```
|
||||
|
||||
#### **Interface**
|
||||
## Storage Operations
|
||||
|
||||
### Storing Data
|
||||
|
||||
Store data with the `set` method:
|
||||
|
||||
```python
|
||||
def set(self, key: str, val: bytes) -> None:
|
||||
pass
|
||||
def set(self, key: str, val: bytes) -> None:
|
||||
"""
|
||||
Store data in persistent storage
|
||||
|
||||
Parameters:
|
||||
key: Unique identifier for your data
|
||||
val: Binary data to store (bytes)
|
||||
"""
|
||||
pass
|
||||
```
|
||||
|
||||
Note that what is passed in is bytes, so you can actually store files in it.
|
||||
<Warning>
|
||||
The value must be in `bytes` format. This provides flexibility to store various types of data, including files.
|
||||
</Warning>
|
||||
|
||||
### Getting Keys
|
||||
|
||||
#### **Entry Point**
|
||||
#### Example: Storing Different Data Types
|
||||
|
||||
```python
|
||||
self.session.storage
|
||||
# String data (must convert to bytes)
|
||||
storage.set("user_name", "John Doe".encode('utf-8'))
|
||||
|
||||
# JSON data
|
||||
import json
|
||||
user_data = {"name": "John", "age": 30, "preferences": ["AI", "NLP"]}
|
||||
storage.set("user_data", json.dumps(user_data).encode('utf-8'))
|
||||
|
||||
# File data
|
||||
with open("image.jpg", "rb") as f:
|
||||
image_data = f.read()
|
||||
storage.set("profile_image", image_data)
|
||||
```
|
||||
|
||||
#### **Interface**
|
||||
### Retrieving Data
|
||||
|
||||
Retrieve stored data with the `get` method:
|
||||
|
||||
```python
|
||||
def get(self, key: str) -> bytes:
|
||||
pass
|
||||
def get(self, key: str) -> bytes:
|
||||
"""
|
||||
Retrieve data from persistent storage
|
||||
|
||||
Parameters:
|
||||
key: Unique identifier for your data
|
||||
|
||||
Returns:
|
||||
The stored data as bytes, or None if key doesn't exist
|
||||
"""
|
||||
pass
|
||||
```
|
||||
|
||||
### Deleting Keys
|
||||
|
||||
#### **Entry Point**
|
||||
#### Example: Retrieving and Converting Data
|
||||
|
||||
```python
|
||||
self.session.storage
|
||||
# Retrieving string data
|
||||
name_bytes = storage.get("user_name")
|
||||
if name_bytes:
|
||||
name = name_bytes.decode('utf-8')
|
||||
print(f"Retrieved name: {name}")
|
||||
|
||||
# Retrieving JSON data
|
||||
import json
|
||||
user_data_bytes = storage.get("user_data")
|
||||
if user_data_bytes:
|
||||
user_data = json.loads(user_data_bytes.decode('utf-8'))
|
||||
print(f"User preferences: {user_data['preferences']}")
|
||||
```
|
||||
|
||||
#### **Interface**
|
||||
### Deleting Data
|
||||
|
||||
Delete stored data with the `delete` method:
|
||||
|
||||
```python
|
||||
def delete(self, key: str) -> None:
|
||||
pass
|
||||
def delete(self, key: str) -> None:
|
||||
"""
|
||||
Delete data from persistent storage
|
||||
|
||||
Parameters:
|
||||
key: Unique identifier for the data to delete
|
||||
"""
|
||||
pass
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Use Descriptive Keys" icon="key">
|
||||
Create a consistent naming scheme for your keys to avoid conflicts and make your code more maintainable.
|
||||
</Card>
|
||||
<Card title="Handle Missing Keys" icon="triangle-exclamation">
|
||||
Always check if data exists before processing it, as the key might not be found.
|
||||
</Card>
|
||||
<Card title="Serialize Complex Data" icon="code">
|
||||
Convert complex objects to JSON or other serialized formats before storing.
|
||||
</Card>
|
||||
<Card title="Implement Error Handling" icon="shield">
|
||||
Wrap storage operations in try/except blocks to handle potential errors gracefully.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Common Use Cases
|
||||
|
||||
- **User Preferences**: Store user settings and preferences between sessions
|
||||
- **Conversation History**: Maintain context from previous conversations
|
||||
- **API Tokens**: Store authentication tokens securely
|
||||
- **Cached Data**: Store frequently accessed data to reduce API calls
|
||||
- **File Storage**: Store user-uploaded files or generated content
|
||||
|
||||
{/*
|
||||
Contributing Section
|
||||
DO NOT edit this section!
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user