About server_document

I Embedded bokeh in Django, and the code is as follows

Pass the variable wriid through the Ajax request in HTML file of another server. At present, the first request is normal, but when I change the passed variable wirid, the graph is not rendered. What should I do with this one? Can’t the third party respond in HTML?

        from os.path import join
        from pathlib import Path
        import bokeh.plotting as bp
        from bokeh.embed import server_document
        from bokeh.layouts import column
        from bokeh.models import HoverTool, CustomJS, ColumnDataSource, Button, TextInput
        from bokeh.themes import Theme
        from bokeh.document import Document
        from django.http import HttpRequest, HttpResponse
        import datashader as ds
        import pandas as pd
        import numpy as np
        import datashader.transfer_functions as tf
        from django.shortcuts import render
        from datashader.bokeh_ext import InteractiveImage
        from utils import matUtil, jsonUtil
        from web.CustomModelBackends import token_required_url, token_required
        from ykkj_ai import settings


        def signal_chart_handler(doc: Document) -> None:
            # 通过请求参数查找信号存储文件
            args = doc.session_context.request.arguments
            theme = Theme(filename=join(settings.THEMES_DIR, "theme.yaml"))
            data = matUtil.loadmat(Path(join(settings.BASE_DIR, "featrue_bokeh", args.get("wriId") + ".mat")))["data"]
            # 悬停工具
            hover = HoverTool(
                tooltips=[
                    ("(x值,y值)", "($x, $y)"),
                ]
            )
            # 处理信号数据并封装
            p = bp.figure(x_axis_type="datetime", x_range=(0, 5), title=args.get("wriId")+"信号数据",
                          tools=[hover, 'pan', 'wheel_zoom', 'box_zoom', 'save', 'reset'],
                          y_range=(np.min(data), np.max(data)))
            dists = {cat: pd.DataFrame(dict(x=np.arange(0, len(data), 1) / float(44100),
                                            y=data,
                                            val=val, cat=cat))
                     for x, y, s, val, cat in
                     [(2, 2, 0.01, 10, "d1")]}
            df = pd.concat(dists, ignore_index=True)
            df["cat"] = df["cat"].astype("category")
            width, height = p.plot_width, p.plot_height
            xmin, xmax = p.x_range.start, p.x_range.end
            ymin, ymax = p.y_range.start, p.y_range.end
            x_range = (xmin, xmax)
            y_range = (ymin, ymax)
            dw, dh = xmax - xmin, ymax - ymin
            cvs = ds.Canvas(plot_width=width, plot_height=height, x_range=x_range, y_range=y_range)
            agg = cvs.line(df, 'x', 'y')  # , ds.count())
            img_agg = tf.shade(agg, min_alpha=255)
            image = tf.dynspread(img_agg, threshold=0.25, max_px=1)
            source = ColumnDataSource(data=dict(image=[image.data], x=[xmin],
                                                y=[ymin], dw=[dw], dh=[dh]))
            p.image_rgba(source=source, image='image', x='x', y='y',
                         dw='dw', dh='dh', dilate=False)
            # 处理各种回调
            p.x_range.callback = CustomJS(code="""
            debugger;
            """)
            # 准备推送到客户端
            doc.theme = theme
            doc.add_root(column(p, sizing_mode='stretch_both'))
            doc.title = args.get("wriId")+"信号数据"
        #请求参数wriId:采集信号时的主键
        @token_required('ROLE_ADMIN')
        def signal_chart_main(request: HttpRequest) -> HttpResponse:
            script = server_document(
                url=request._current_scheme_host + '/bokeh_apps/signal_chart',  # 此处配置与bokeh_apps.autoload中请求地址保持一致
                arguments=dict(request.GET.dict(), **request.POST.dict())  # bokeh只接受不带参数的url因此处理django参数,处理django参数数据
            )
            # 前后端分离,前端执行返回的script即可实现数据渲染
            return jsonUtil.http_response_success(script)

django urls setting

urlpatterns = [
url(r'^bokeh_apps/signal_chart', signal_chart_main),# 验证登录失败
]
#配置bokeh_apps路由
bokeh_apps = [
autoload("bokeh_apps/signal_chart", signal_chart_handler),
]

Access the bokeh ’ app/signal_chart’ interface with parameters every time

Are there any server console errors? Are there any errors in the browser JS console? What is the value of arguments when things are failing?

Browser console results after two requests:


python console results

I execute the script returned by server_document in a separate HTML file

Where/how is the second request generated? Why is it a POST?

In another web service,it‘s from bokeh_apps/signal_chart/ twice

If you put a print debug statement in signal_chart_main do you see the expected script generated both times? If so, the question is why the script is not being executed the second time

Both requests received the expected script.

<script src="http://localhost:8000/bokeh_apps/signal_chart_handler/autoload.js?bokeh-autoload-element=1263&bokeh-app-path=/bokeh_apps/signal_chart_handler&bokeh-absolute-url=http://localhost:8000/bokeh_apps/signal_chart_handler&wriId=6624173862424674304" id="1263"></script>
<script src="http://localhost:8000/bokeh_apps/signal_chart_handler/autoload.js?bokeh-autoload-element=1391&bokeh-app-path=/bokeh_apps/signal_chart_handler&bokeh-absolute-url=http://localhost:8000/bokeh_apps/signal_chart_handler&wriId=6624174114078720000" id="1391"></script>

Do I need to refresh the current page before the second request, or do I guess to close the first websocket?Because I found that the python console only printed the websocket connection of the first request, but the second request did not print the websocket connection

@416970882 That means your page is not executing the script in the second case. You can see in the browser log that there is no follow-on load of autoload.js at all. But I don’t have any idea why that might be, or have any advice to offer, unfortunately. That’s not really a Bokeh question, per se, as far as I know. You need to make sure your page actually executes the scripts.

It seems to be a bug. Script returned by server_document cannot be inserted twice in the same page

It seems that a websocket connection will be created every time the script returned from the request server _document is executed. Is there any way to keep websocket for the first time,

Generally every connection generates a new session, for a new Document, serviced by a new websocket. I don’t really understand what you are trying to actually accomplish enough to advise you on any different courses of action.

If I request the server_document twice, the script returned by the execution uses the same websocket

That’s not possible.