Files
AI_meeting_assistant---V2.1/services/dify_client.py
beabigegg 0fee703b84 back
2025-08-17 15:26:44 +08:00

93 lines
3.1 KiB
Python

# services/dify_client.py
import os, json, re, requests
from dotenv import load_dotenv
load_dotenv()
DIFY_BASE = os.getenv("DIFY_API_BASE_URL", "https://api.dify.ai/v1")
TIMEOUT = 60
def _post_request(endpoint: str, api_key: str, payload: dict):
"""Generic function to post a request to a Dify endpoint."""
if not api_key:
raise RuntimeError("Dify API key is not set")
url = f"{DIFY_BASE}{endpoint}"
headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json",
}
# For debugging the exact payload sent to the API
print(f"Sending Dify request to {url}: {json.dumps(payload, indent=2, ensure_ascii=False)}")
resp = requests.post(url, headers=headers, json=payload, timeout=TIMEOUT)
if resp.status_code != 200:
print(f"Dify API Error Response: {resp.text}")
resp.raise_for_status()
data = resp.json()
return data.get("answer") or data
def translate_text(text: str, target_lang: str, user_id: str = "system") -> str:
"""
Calls the Dify CHAT API for translation, mimicking a user query.
"""
api_key = os.getenv("DIFY_TRANSLATOR_API_KEY")
# Combine all information into a single query string, as expected by the prompt
query = f"目標語言:{target_lang}\n需翻譯內容:\n{text}"
payload = {
"inputs": {}, # Chatbot apps generally don't use inputs here
"response_mode": "blocking",
"user": user_id,
"query": query,
# conversation_id is optional for single-turn interactions
}
return _post_request("/chat-messages", api_key, payload)
def summarize_text(text: str, user_id: str = "system") -> str:
api_key = os.getenv("DIFY_SUMMARIZER_API_KEY")
payload = {
"inputs": {},
"response_mode": "blocking",
"user": user_id,
"query": text,
}
return _post_request("/chat-messages", api_key, payload)
def extract_action_items(text: str, user_id: str = "system") -> list[dict]:
api_key = os.getenv("DIFY_ACTION_EXTRACTOR_API_KEY")
payload = {
"inputs": {},
"response_mode": "blocking",
"user": user_id,
"query": text,
}
raw = _post_request("/chat-messages", api_key, payload)
# Fault tolerance for JSON parsing
s = str(raw).strip()
s = re.sub(r"^```(?:json)?|```$", "", s, flags=re.IGNORECASE|re.MULTILINE).strip()
if not (s.startswith("[") and s.endswith("]")):
m = re.search(r"[\s\S]*\[[\s\S]*\][\s\S]*", s)
if m: s = m.group(0)
items = json.loads(s)
if not isinstance(items, list):
raise ValueError("Extractor did not return a list")
# Normalize keys for database storage
normalized = []
for i in items:
for k in ("item", "action", "owner", "duedate"):
if k not in i:
raise ValueError(f"Extractor item is missing required key: {k}")
normalized.append({
"item": i["item"],
"action": i["action"],
"owner": i["owner"],
"due_date": i["duedate"],
})
return normalized