使用Bokeh 0.12.14与Flask时,AjaxDataSource POST请求报404错误求助
Hey there, let's work through that 404 error you're hitting with AjaxDataSource. Looking at your code snippets, there are a couple of common missteps that are likely causing this issue. Let's break them down and fix things up.
1. 路由路径不匹配
Your Flask data endpoint is defined as @app.route('/data/', methods=['POST']) (note the trailing slash), but if your AjaxDataSource is configured to hit /data (no trailing slash), Flask will send a redirect response—and Ajax requests typically don't follow redirects automatically, leading to a 404.
The fix here is to align your paths perfectly: either remove the trailing slash from the Flask route, or ensure your AjaxDataSource uses the full path with the trailing slash. I'd recommend simplifying to a consistent path without the trailing slash for cleaner behavior.
2. 数据格式不符合Bokeh要求
Right now, your endpoint returns a single x and y value with jsonify(x=x, y=y), but Bokeh's AjaxDataSource expects array-based data (even if you're appending new points). Returning individual values will cause issues with how Bokeh parses the response, and might indirectly contribute to unexpected errors.
修正后的完整代码示例
Here's a polished version of your code that fixes both issues, plus adds proper initial data setup:
from flask import Flask, render_template, jsonify from bokeh.embed import components from bokeh.plotting import figure from bokeh.models.sources import AjaxDataSource app = Flask(__name__) # Initialize data lists to track historical points x_data = [0] y_data = [1] # 2^0 = 1, starting point @app.route('/data', methods=['POST']) def data(): global x_data, y_data new_x = x_data[-1] + 1 new_y = 2 ** new_x x_data.append(new_x) y_data.append(new_y) # Return array-formatted data that Bokeh expects return jsonify(x=x_data, y=y_data) @app.route("/dash") def show_dashboard(): # Configure AjaxDataSource with matching path and polling interval source = AjaxDataSource( data_url='/data', # Exact match to Flask route polling_interval=2000, # 2 seconds between updates mode='replace' # Replace full dataset; use 'append' to add only new points ) # Set initial data for the plot source.data = {'x': x_data, 'y': y_data} # Create the plot p = figure(title="Exponential Growth", x_axis_label='X', y_axis_label='Y') p.line('x', 'y', source=source, line_width=2) # Generate Bokeh components for embedding script, div = components(p) return render_template('dashboard.html', script=script, div=div) if __name__ == '__main__': app.run(debug=True)
配套前端模板(dashboard.html)
Make sure your HTML template correctly renders the Bokeh components:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Updating Bokeh Chart</title> {{ script|safe }} </head> <body> <div style="width: 80%; margin: 2rem auto;"> {{ div|safe }} </div> </body> </html>
额外排查要点
- Check Flask debug logs: With
debug=True, Flask will log every incoming request. You can verify exactly which URL is being hit—this is the fastest way to confirm path mismatches. - HTTP method alignment: AjaxDataSource uses POST by default, which matches your route's
methods=['POST']—if you ever switch to GET, make sure to update both the route and themethodparameter in AjaxDataSource. - CORS (if applicable): If your frontend is served from a different port/domain, you'll need to add CORS support to Flask, but 404 errors are almost always path-related first.
Give these changes a shot, and your chart should start updating without the 404. If you still run into trouble, the Flask debug logs will tell you exactly where the request is going wrong.
内容的提问来源于stack exchange,提问作者Anupam Trivedy

