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

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

相关推荐
小小小小宇4 小时前
前端 Service Worker
前端
只喜欢赚钱的棉花没有糖5 小时前
http的缓存问题
前端·javascript·http
小小小小宇5 小时前
请求竞态问题统一封装
前端
loriloy5 小时前
前端资源帖
前端
源码超级联盟5 小时前
display的block和inline-block有什么区别
前端
GISer_Jing5 小时前
前端构建工具(Webpack\Vite\esbuild\Rspack)拆包能力深度解析
前端·webpack·node.js
让梦想疯狂5 小时前
开源、免费、美观的 Vue 后台管理系统模板
前端·javascript·vue.js
海云前端6 小时前
前端写简历有个很大的误区,就是夸张自己做过的东西。
前端
葡萄糖o_o6 小时前
ResizeObserver的错误
前端·javascript·html
AntBlack6 小时前
Python : AI 太牛了 ,撸了两个 Markdown 阅读器 ,谈谈使用感受
前端·人工智能·后端