Reloading plot data via Ajax

Hello!

My use case is fairly simply and common: I want have a bokeh plot (on client browser) be refreshed with data from the server every 1 sec, using an ajax request.

For testing this, I simply draw a circle at 0,0 initially, which shall then be updated to 10,10. The code is as follows.

Python:
from django.shortcuts import render
from django.http import JsonResponse
from bokeh.models import AjaxDataSource
from bokeh.plotting import figure
from bokeh.embed import components
from bokeh.resources import INLINE

def index(request):
plot = figure()

source = AjaxDataSource(data_url='http://localhost:8000/view2d/data/',
                    polling_interval=1000)

source.data = dict(x=[0], y=[0]) # workaround
plot.circle(source=source, x='x', y='y')

script, div = components(plot, INLINE)
js_resources = INLINE.render_js()
css_resources = INLINE.render_css()
context = {
    'bokeh_script' : script,
    'bokeh_div' : div,
    'js_resources' : js_resources,
    'css_resources' : css_resources
    }

return render(request, 'view2d/index.html', context)

def data(request):
response = JsonResponse(dict(x=[10],y=[10]))
response[“Access-Control-Allow-Origin”] = “"
response[“Access-Control-Allow-Methods”] = “GET, POST, OPTIONS”
response[“Access-Control-Max-Age”] = “1000”
response[“Access-Control-Allow-Headers”] = "

return response

``

Html:
{% block content %}

{{bokeh_div|safe}}

{% endblock %}

{% block scripts %}

{{ js_resources|safe }}
{{ css_resources|safe }}
{{ bokeh_script|safe }}

{% endblock %}

``

Unfortunately I do not get an update of the plot (circle stays at 0,0) but I can see the request being issued every second. This is the output:

[19/Jul/2016 16:19:25] “OPTIONS /view2d/data/ HTTP/1.1” 200 22
[19/Jul/2016 16:19:26] “OPTIONS /view2d/data/ HTTP/1.1” 200 22
[19/Jul/2016 16:19:27] “OPTIONS /view2d/data/ HTTP/1.1” 200 22
[19/Jul/2016 16:19:28] “OPTIONS /view2d/data/ HTTP/1.1” 200 22
[19/Jul/2016 16:19:29] “OPTIONS /view2d/data/ HTTP/1.1” 200 22
[19/Jul/2016 16:19:30] “OPTIONS /view2d/data/ HTTP/1.1” 200 22
[19/Jul/2016 16:19:31] “OPTIONS /view2d/data/ HTTP/1.1” 200 22

``

I am quite sure this problem has to do with cross-domain request restriction. Does anyone has a simply solution to this? I saw examples for flask (e.g. here: http://flask.pocoo.org/snippets/56/) but want to avoid decorators or middleware solutions.

As further info: I am using Django as framework.

Hello to my yesterday’s self! To answer my question, the following two things must be changed to make the script working (edits are underlined):

from django.shortcuts import render
from django.http import JsonResponse
from bokeh.models import AjaxDataSource
from bokeh.plotting import figure
from bokeh.embed import components
from bokeh.resources import INLINE

def index(request):
plot = figure()

source = AjaxDataSource(method='GET',data_url='http://localhost:8000/view2d/data/',
                    polling_interval=1000)

source.data = dict(x=[0], y=[0]) # workaround
plot.circle(source=source, x='x', y='y')

script, div = components(plot, INLINE)
js_resources = INLINE.render_js()
css_resources = INLINE.render_css()
context = {
    'bokeh_script' : script,
    'bokeh_div' : div,
    'js_resources' : js_resources,
    'css_resources' : css_resources
    }

return render(request, 'view2d/index.html', context)

def data(request):
response = JsonResponse(dict(x=[10],y=[10]))
response[“Access-Control-Allow-Origin”] = “*”
response[“Access-Control-Allow-Methods”] = “GET, POST, OPTIONS”
response[“Access-Control-Max-Age”] = “1000”
response[“Access-Control-Allow-Headers”] = “Content-Type”
return response

``

The reason:

  • “Access-Control-Allow-Headers” cannot use wildcard and must be set specifically;
  • Only ‘GET’ method is working, the default ‘POST’ would be blocked as a not allowed “Cross Origin Request”.

Hi Arthur,

I bet this information would be useful to other users, would you be interested in contributing a small PR to add this information to the documentation?

Thanks,

Bryan

···

On Jul 21, 2016, at 3:00 PM, Artur Scholz <[email protected]> wrote:

Hello to my yesterday's self! To answer my question, the following two things must be changed to make the script working (edits are underlined):

from django.shortcuts import render
from django.http import JsonResponse
from bokeh.models import AjaxDataSource
from bokeh.plotting import figure
from bokeh.embed import components
from bokeh.resources import INLINE

def index(request):
    plot = figure()

    source = AjaxDataSource(method='GET',data_url='http://localhost:8000/view2d/data/',
                        polling_interval=1000)
    
    source.data = dict(x=[0], y=[0]) # workaround
    plot.circle(source=source, x='x', y='y')

    script, div = components(plot, INLINE)
    js_resources = INLINE.render_js()
    css_resources = INLINE.render_css()
    context = {
        'bokeh_script' : script,
        'bokeh_div' : div,
        'js_resources' : js_resources,
        'css_resources' : css_resources
        }
    
    return render(request, 'view2d/index.html', context)

def data(request):
    response = JsonResponse(dict(x=[10],y=[10]))
    response["Access-Control-Allow-Origin"] = "*"
    response["Access-Control-Allow-Methods"] = "GET, POST, OPTIONS"
    response["Access-Control-Max-Age"] = "1000"
    response["Access-Control-Allow-Headers"] = "Content-Type"
    return response

The reason:
- "Access-Control-Allow-Headers" cannot use wildcard and must be set specifically;
- Only 'GET' method is working, the default 'POST' would be blocked as a not allowed "Cross Origin Request".

--
You received this message because you are subscribed to the Google Groups "Bokeh Discussion - Public" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/1c6c4270-a741-40d5-bd4e-eed12334b47d%40continuum.io.
For more options, visit https://groups.google.com/a/continuum.io/d/optout.

Dear Bryan,

I made an example application that plots the track of the intl. space station, using bokeh plot and ajax requests.

Its implemented in flask and django:

https://github.com/artur-scholz/view2d-flask
https://github.com/artur-scholz/view2d-django

Hope this can be useful to others, dealing with periodic updates of a plot and fighting with crossdomain restrictions.

Regards

Artur

···

On Thu, Jul 21, 2016 at 10:27 PM, Bryan Van de Ven [email protected] wrote:

Hi Arthur,

I bet this information would be useful to other users, would you be interested in contributing a small PR to add this information to the documentation?

Thanks,

Bryan

On Jul 21, 2016, at 3:00 PM, Artur Scholz [email protected] wrote:

Hello to my yesterday’s self! To answer my question, the following two things must be changed to make the script working (edits are underlined):

from django.shortcuts import render

from django.http import JsonResponse

from bokeh.models import AjaxDataSource

from bokeh.plotting import figure

from bokeh.embed import components

from bokeh.resources import INLINE

def index(request):

plot = figure()
source = AjaxDataSource(method='GET',data_url='[http://localhost:8000/view2d/data/](http://localhost:8000/view2d/data/)',
                    polling_interval=1000)
source.data = dict(x=[0], y=[0]) # workaround
plot.circle(source=source, x='x', y='y')
script, div = components(plot, INLINE)
js_resources = INLINE.render_js()
css_resources = INLINE.render_css()
context = {
    'bokeh_script' : script,
    'bokeh_div' : div,
    'js_resources' : js_resources,
    'css_resources' : css_resources
    }
return render(request, 'view2d/index.html', context)

def data(request):

response = JsonResponse(dict(x=[10],y=[10]))
response["Access-Control-Allow-Origin"] = "*"
response["Access-Control-Allow-Methods"] = "GET, POST, OPTIONS"
response["Access-Control-Max-Age"] = "1000"
response["Access-Control-Allow-Headers"] = "Content-Type"
return response

The reason:

  • “Access-Control-Allow-Headers” cannot use wildcard and must be set specifically;
  • Only ‘GET’ method is working, the default ‘POST’ would be blocked as a not allowed “Cross Origin Request”.

You received this message because you are subscribed to the Google Groups “Bokeh Discussion - Public” group.

To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].

To post to this group, send email to [email protected].

To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/1c6c4270-a741-40d5-bd4e-eed12334b47d%40continuum.io.

For more options, visit https://groups.google.com/a/continuum.io/d/optout.

You received this message because you are subscribed to a topic in the Google Groups “Bokeh Discussion - Public” group.

To unsubscribe from this topic, visit https://groups.google.com/a/continuum.io/d/topic/bokeh/Ftj-Dl1oTjk/unsubscribe.

To unsubscribe from this group and all its topics, send an email to [email protected].

To post to this group, send email to [email protected].

To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/BF8F5403-E281-4576-B424-63F301B04F7B%40continuum.io.
For more options, visit https://groups.google.com/a/continuum.io/d/optout.

This is awesome, thank you!

Daniel

MIT // EECS // Business Analytics

···

On Monday, July 25, 2016 at 5:34:14 AM UTC-4, Artur Scholz wrote:

Dear Bryan,

I made an example application that plots the track of the intl. space station, using bokeh plot and ajax requests.

Its implemented in flask and django:

https://github.com/artur-scholz/view2d-flask
https://github.com/artur-scholz/view2d-django

Hope this can be useful to others, dealing with periodic updates of a plot and fighting with crossdomain restrictions.

Regards

Artur

On Thu, Jul 21, 2016 at 10:27 PM, Bryan Van de Ven [email protected] wrote:

Hi Arthur,

I bet this information would be useful to other users, would you be interested in contributing a small PR to add this information to the documentation?

Thanks,

Bryan

On Jul 21, 2016, at 3:00 PM, Artur Scholz [email protected] wrote:

Hello to my yesterday’s self! To answer my question, the following two things must be changed to make the script working (edits are underlined):

from django.shortcuts import render

from django.http import JsonResponse

from bokeh.models import AjaxDataSource

from bokeh.plotting import figure

from bokeh.embed import components

from bokeh.resources import INLINE

def index(request):

plot = figure()
source = AjaxDataSource(method='GET',data_url='[http://localhost:8000/view2d/data/](http://localhost:8000/view2d/data/)',
                    polling_interval=1000)
source.data = dict(x=[0], y=[0]) # workaround
plot.circle(source=source, x='x', y='y')
script, div = components(plot, INLINE)
js_resources = INLINE.render_js()
css_resources = INLINE.render_css()
context = {
    'bokeh_script' : script,
    'bokeh_div' : div,
    'js_resources' : js_resources,
    'css_resources' : css_resources
    }
return render(request, 'view2d/index.html', context)

def data(request):

response = JsonResponse(dict(x=[10],y=[10]))
response["Access-Control-Allow-Origin"] = "*"
response["Access-Control-Allow-Methods"] = "GET, POST, OPTIONS"
response["Access-Control-Max-Age"] = "1000"
response["Access-Control-Allow-Headers"] = "Content-Type"
return response

The reason:

  • “Access-Control-Allow-Headers” cannot use wildcard and must be set specifically;
  • Only ‘GET’ method is working, the default ‘POST’ would be blocked as a not allowed “Cross Origin Request”.

For more options, visit https://groups.google.com/a/continuum.io/d/optout.

You received this message because you are subscribed to the Google Groups “Bokeh Discussion - Public” group.

To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].

To post to this group, send email to [email protected].

To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/1c6c4270-a741-40d5-bd4e-eed12334b47d%40continuum.io.

For more options, visit https://groups.google.com/a/continuum.io/d/optout.

You received this message because you are subscribed to a topic in the Google Groups “Bokeh Discussion - Public” group.

To unsubscribe from this topic, visit https://groups.google.com/a/continuum.io/d/topic/bokeh/Ftj-Dl1oTjk/unsubscribe.

To unsubscribe from this group and all its topics, send an email to [email protected].

To post to this group, send email to [email protected].

To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/BF8F5403-E281-4576-B424-63F301B04F7B%40continuum.io.

Thanks. Here is a more recent version: https://gitlab.com/artur-scholz/groundtrack

···

On Thu, Jan 18, 2018 at 5:42 PM, [email protected] wrote:

This is awesome, thank you!

Daniel

MIT // EECS // Business Analytics

On Monday, July 25, 2016 at 5:34:14 AM UTC-4, Artur Scholz wrote:

Dear Bryan,

I made an example application that plots the track of the intl. space station, using bokeh plot and ajax requests.

Its implemented in flask and django:

https://github.com/artur-scholz/view2d-flask
https://github.com/artur-scholz/view2d-django

Hope this can be useful to others, dealing with periodic updates of a plot and fighting with crossdomain restrictions.

Regards

Artur

On Thu, Jul 21, 2016 at 10:27 PM, Bryan Van de Ven [email protected] wrote:

Hi Arthur,

I bet this information would be useful to other users, would you be interested in contributing a small PR to add this information to the documentation?

Thanks,

Bryan

On Jul 21, 2016, at 3:00 PM, Artur Scholz [email protected] wrote:

Hello to my yesterday’s self! To answer my question, the following two things must be changed to make the script working (edits are underlined):

from django.shortcuts import render

from django.http import JsonResponse

from bokeh.models import AjaxDataSource

from bokeh.plotting import figure

from bokeh.embed import components

from bokeh.resources import INLINE

def index(request):

plot = figure()
source = AjaxDataSource(method='GET',data_url='[http://localhost:8000/view2d/data/](http://localhost:8000/view2d/data/)',
                    polling_interval=1000)
source.data = dict(x=[0], y=[0]) # workaround
plot.circle(source=source, x='x', y='y')
script, div = components(plot, INLINE)
js_resources = INLINE.render_js()
css_resources = INLINE.render_css()
context = {
    'bokeh_script' : script,
    'bokeh_div' : div,
    'js_resources' : js_resources,
    'css_resources' : css_resources
    }
return render(request, 'view2d/index.html', context)

def data(request):

response = JsonResponse(dict(x=[10],y=[10]))
response["Access-Control-Allow-Origin"] = "*"
response["Access-Control-Allow-Methods"] = "GET, POST, OPTIONS"
response["Access-Control-Max-Age"] = "1000"
response["Access-Control-Allow-Headers"] = "Content-Type"
return response

The reason:

  • “Access-Control-Allow-Headers” cannot use wildcard and must be set specifically;
  • Only ‘GET’ method is working, the default ‘POST’ would be blocked as a not allowed “Cross Origin Request”.

For more options, visit https://groups.google.com/a/continuum.io/d/optout.

You received this message because you are subscribed to the Google Groups “Bokeh Discussion - Public” group.

To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].

To post to this group, send email to [email protected].

To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/1c6c4270-a741-40d5-bd4e-eed12334b47d%40continuum.io.

For more options, visit https://groups.google.com/a/continuum.io/d/optout.

You received this message because you are subscribed to a topic in the Google Groups “Bokeh Discussion - Public” group.

To unsubscribe from this topic, visit https://groups.google.com/a/continuum.io/d/topic/bokeh/Ftj-Dl1oTjk/unsubscribe.

To unsubscribe from this group and all its topics, send an email to [email protected].

To post to this group, send email to [email protected].

To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/BF8F5403-E281-4576-B424-63F301B04F7B%40continuum.io.

You received this message because you are subscribed to a topic in the Google Groups “Bokeh Discussion - Public” group.

To unsubscribe from this topic, visit https://groups.google.com/a/continuum.io/d/topic/bokeh/Ftj-Dl1oTjk/unsubscribe.

To unsubscribe from this group and all its topics, send an email to [email protected].

To post to this group, send email to [email protected].

To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/74fe69ad-ff1a-47b3-9e77-9dfaa1776564%40continuum.io.

For more options, visit https://groups.google.com/a/continuum.io/d/optout.