Dify创建 echarts图表 (二)dify+python后端flask实现

通过python flask创建了一个接口,用来生成echarts能够适应更多场景应用

本次遇到的主要就是docker环境下,要访问本地接口需要转换一下接口ip,当然通过docker访问外部接口同样也有类似问题,也需要中间代理转换一下。当然最麻烦的就是dify传值这一步,简单做个记录

场景1:测试流程是否可用

这里传的是一个空值

复制代码
from urllib  import request
import urllib.request
import json

def main(str) -> dict:
    data = {"str": str}
    url = 'http://host.docker.internal:5000/fixed_string'
    json_data = json.dumps(data)
    byte_data = json_data.encode('utf-8')
    req = urllib.request.Request(url, data=byte_data, headers={'Content-Type': 'application/json'})
    response = urllib.request.urlopen(req)
    response_data = response.read().decode('utf-8')
      
    return {
        "result": response_data,
    }

后端接到请求直接返回字符串就好了,不得不感叹AI真的太强大了,后端代码几乎全是AI写的十来分钟搞定

复制代码
@app.route('/dynamic-string', methods=['POST'])
def dynamic_string():
    print("dynamic-string接口")
    print(request)
    if not request.json:
        return jsonify({"error": "请求必须包含JSON数据"}), 400
    return get_dynamic_string(json.dumps(request.json))


def get_fixed_string():
    option = {
        "xAxis": {
            "type": "category",
            "data": ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
        },
        "yAxis": {
            "type": "value"
        },
        "series": [
            {
                "data": [120, 200, 150, 80, 70, 110, 130],
                "type": "line"
            }
        ]
	}
 
    # 将字典转换为格式化的 JSON 字符串
    option_json = json.dumps(option, indent=2)
    
    # 构建正确的 Markdown 代码块
    output = "```echarts\n" + option_json + "\n```"
    
    return output

场景2:Dify传值到后端,再通过后端拼接好图表字符串后返给Dify端

目前做图的思路比较简单,Dify这边根据需求提问自动生成SQL并查询返回结果,然后在后端完成做图,再返给dify端,这个场景遇到稍微麻烦的地方就在于如何拿到制作图表需要的关键参数,如名称、类型、基础的X轴、Y轴数据,虽然可以通过大模型提取,试吧,一试一个不吱声,各种报错

最后实现方式是用的参数提取器做,模型选的阿里千问的

大致流程如下:

简单记录一下,数据库查结果还是用的插件,中间有个过滤代码,需要处理一下异常问题,巨烦

复制代码
import re
def main(arg1: str) -> dict:
    result = re.sub(r'"', '', arg1)
    result = re.sub(r'\n', ' ', result)
    result = result.replace("date('now')","CURRENT_DATE")
    result = result.replace("DATE('now')","CURRENT_DATE")
    return {
        "result": result,
    }

结果查出来了需要对数据再做一下处理

复制代码
import json
def main(arg1: str) -> dict:
 return {
    "result": json.dumps(arg1,ensure_ascii=False)
 }

最关键的就是下面的这个参数提取器,目前只是跑通了的版本,还有优化的空间

接下来就是往本地接口传值了,获取到参数提取器输出的四个数组,然后开始往接口丢

复制代码
from urllib import request
import urllib.request
import json

def main(title, chart_category, xdata, ydata) -> dict:
    url = 'http://host.docker.internal:5000/custom-chart'
    
    # 将4个数组封装成字典(可自定义字段名)
    payload = {
        "title": title,
        "chart_category": chart_category,
        "xdata": xdata,
        "ydata": ydata
    }
    
    # 构造请求
    json_data = json.dumps(payload)  # 序列化为JSON字符串
    byte_data = json_data.encode('utf-8')
    req = urllib.request.Request(
        url, 
        data=byte_data, 
        headers={'Content-Type': 'application/json'}
    )
    
    # 发送请求并解析响应
    response = urllib.request.urlopen(req)
    response_data = response.read().decode('utf-8')
    return {"result": response_data}  # 返回接口响应

后端代码如下,稍微改良了一下,由固定字符串变成了自动传参,但由于不同图表的特性不同,这里不能通用,接下来改造的方向,通过Dify传回来的图表类型,输出适配不同图表的参数

复制代码
@app.route('/custom-chart', methods=['POST'])
def custom_chart():
    """接收前端参数生成自定义图表"""
    print("custom-chart接口")
    print(request)

    if not request.json:
        return jsonify({"error": "请求必须包含JSON数据"}), 400
    
    data = request.json
    title = data.get('title', '自定义图表')
    chart_category = data.get('chart_category', 'line')
    ydata = data.get('ydata', [])
    xdata = data.get('xdata', [])
    
    return generate_chart_from_params(title, chart_category, ydata, xdata)

def generate_chart_from_params(title, chart_category, ydata, xdata):
    """根据参数生成ECharts配置"""
    # 处理xdata格式
    if isinstance(xdata, str):
        # 去除首尾引号,按分号分割,去除每个元素的首尾引号
        xdata = [item.strip().strip("'") for item in xdata.strip("'").split(';')]
    
    # 处理ydata格式
    if isinstance(ydata, str):
        # 去除首尾引号,按逗号分割,去除每个元素的首尾引号和空格,转换为数字
        ydata = [int(item.strip().strip("'")) for item in ydata.strip("'").split(',')]
    
    option = {
        "title": {
            "text": title
        },
        "tooltip": {},
        "xAxis": {
            "type": "category",
            "data": xdata
        },
        "yAxis": {
            "type": "value"
        },
        "series": [{
            "data": ydata,
            "type": chart_category
        }]
    }
    
    # 将字典转换为格式化的JSON字符串
    option_json = json.dumps(option, indent=2, ensure_ascii=False)
    # 构建正确的Markdown代码块
    output = "```echarts\n" + option_json + "\n```"
    print(output)   
    return output

好了,基本上流程就是这样了

相关推荐
GreenTea3 小时前
GrokBot 核心成员 Lauren Tan:每月交付 2000 个 PR 的人,是怎么用 AI 的
前端·后端·架构
mCell4 小时前
用 Knip 清理 AI Coding 留下的冗余代码
前端·ai编程·前端工程化
笃行3505 小时前
使用Rokid AIUI做了一个童年推箱子游戏
前端
excel6 小时前
前端加密的作用与使用场景
前端
计算机魔术师7 小时前
纽约时报版权诉讼披露:微软高管内部称训练 AI 是人类历史上最大规模劳动窃取
前端
去伪存真7 小时前
大模型的参数量为什么那么大?
前端·人工智能
IT_陈寒8 小时前
Java空指针这次真把我坑惨了
前端·人工智能·后端
八荒启·交互动画9 小时前
# Web特效020—让 Web 特效真正动起来:时间循环应该怎么接
前端·webgl·网页特效·八荒启-交互动画·八荒启
动恰客流统计9 小时前
线下零售数字化浪潮下,客流统计的3个核心发展趋势
大数据·前端·人工智能
用户938515635079 小时前
从小米前端面试题,彻底搞懂闭包、作用域链与 useState 惰性初始化
前端·面试