Open RyanRio opened 4 years ago
@mattpap @philippjfr I asked for the issue to be made because I'm not sure it points to a need for docs/examples, or if there is some useful feature work that could be prompted
I'm actively using these feature(s) so I figure I will update this comment as I go with things I notice / functionality improvements.
function.py
and then application.py
in bokeh.application
, eventually bubbling all the way out bokeh.server.contexts
create_session_if_needed
. Errors do not appear in the browser either. For context I did set both log_levels to trace
on the bokeh.settings
instanceWhen you request the app interface, you can carry the data and modify your code
def app(request: HttpRequest) -> HttpResponse:
script = server_document(request.build_absolute_uri("/home/x"), arguments=dict(request.GET.dict(), **request.POST.dict())
return render(request, "embed.html", dict(script=script))
and in app app_handler func
args = doc.session_context.request.arguments
print(args.get("wriId"))
But I had other problems https://discourse.bokeh.org/t/about-server-document/4783
In the HTML file of another server, AJAX carries the parameter request interface to get the returned script and execute it..There is no problem with the first access, but there is no response after the second access only modifies the parameters
Hey @yanwencheng , you'll have to be a little more descriptive - does "wriId" exist in **request.POST.dict() (or GET), otherwise I don't see how you are fetching a valid value, which would cause it to silently fail on the KeyError as I mentioned. Otherwise it looks fine and if you are saying the graph appears on the first request then I think you should definitely investigate what the value of wriID is when the graph doesn't render.
嘿@yanwencheng,您必须要更具描述性-** request.POST.dict()(或GET)中是否存在“ wriId”,否则我看不到您如何获取有效值,会导致它在我提到的KeyError上无提示地失败。否则,它看起来还不错,并且如果您说图表出现在第一个请求上,那么我认为您应该研究当图表未呈现时wriID的值是什么。
Hey @yanwencheng , you'll have to be a little more descriptive - does "wriId" exist in **request.POST.dict() (or GET), otherwise I don't see how you are fetching a valid value, which would cause it to silently fail on the KeyError as I mentioned. Otherwise it looks fine and if you are saying the graph appears on the first request then I think you should definitely investigate what the value of wriID is when the graph doesn't render.
Combined POST and GET request parameters,Use args = doc.session_context.request.arguments when generating bokeh documents
@bryevdv Am I correct in that bokeh/bokeh#9536 would allow me to access other arguments on the request object and enable me to do (I'll try to keep it as purely-bokeh-related as possible, treat request.session
as just a django session that should persist across a single user instance):
doc.session_context.request.session["bokeh-id"] = doc.session_context.id
and then later on (for instance a user does something on the page and I handle the POST request by modifying the plot a little bit) I could access that with `request.session["bokeh-id"]?
From what I can tell, and this includes separate from django, an autoloadjsConsumer (or document - though I'm not all that sure what this does) that extends SessionConsumer
makes the call to create_session_if_needed
. After the bokeh document is created a request to the ws url is created which has reference to the application context and attempts to send the message to the client. Currently, I am attempting to use a workaround and in the connect
method of the WSConsumer I have put:
self.request['session']['bokeh-id'] = self.get_argument("bokeh-session-id")
However, as you can imagine, this request does not exactly persist throughout, the multiple states of the session
variable are
<django.contrib.sessions.backends.db.SessionStore object at 0x1AC62BE0> autoload <django.contrib.sessions.backends.db.SessionStore object at 0x1ABDED60> ws <django.contrib.sessions.backends.db.SessionStore object at 0x1ABD9CE8> ajax request
So, my data is lost (whether this is due to django user authentication being out of sync or due to the issues resolved by 9536, I don't know)
In any case, this prompts a possible feature - user synchronization between django and bokeh. It would be nice, if bokeh is living in a django environment, to optionally take advantage of the powerful django session, auth (might solve some problems mentioned in bokeh/bokeh#9536?), and user modules, it's already confusing enough that session
can refer to both! Feel free to lay on any server architecture knowledge you feel is relevant/interesting, or just point to src code, I'll happily do the digging and experimenting myself too!
I took a stab at implementing something like this before finding this issue - see bokeh/bokeh#9946 & bokeh/bokeh#9947
@RyanRio
Take a look at PR #6 and let me know if you have any feedback.
Here are the key points from the expanded examples in the PR:
urls.py
urlpatterns = [
path("shapes/<str:arg1>/<str:arg2>", views.shapes_with_args),
]
bokeh_apps = [
autoload("shapes/(?P<arg1>[\w_\-]+)/(?P<arg2>[\w_\-]+)", views.shape_viewer_handler_with_args),
]
Note that autoload
takes a re_path
pattern.
views.py
from bokeh_django import with_url_args
@with_url_args
def shape_viewer_handler_with_args(doc, arg1, arg2):
viewer = shape_viewer()
pn.Column(
viewer,
pn.pane.Markdown(f'## This app has URL Args: {arg1} and {arg2}')
).server_doc(doc)
def shapes_with_args(request: HttpRequest, arg1: str, arg2: str) -> HttpResponse:
script = server_document(request.get_full_path())
return render(request, "embed.html", dict(script=script))
Note that server_document
should be called with request.get_full_path()
.
Created from discussion around this discourse topic.
The main feature I am interested in is properly using
autoload
frombokeh.server.django
to access a bokeh app without mangling the url in the request function. To demonstrate this, consider the django project namedproject
and just using views/urls within said project directory (this could easily be extended to be contained within an app). Currently the following has to be done in order to support the generic 'title':Ideally, you could indicate to autoload that it will take a parameter and it would make that parameter available to that handler. Note that it is already technically available to the handler under doc.session_context.arguments, however I still had to explicitly put "/home/x"
A few issues from this example:
def init(self, scope: Dict[str, Any]): super().init(scope)
async def connect(self): await super().connect() print("connecting") # add your own code wherever you want here, and just forward along bokeh information
async def disconnect(self, close_code): await super().disconnect(close_code)
async def receive(self, text_data): await super().receive(text_data)