Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions demo/demo/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,8 @@
"http_poke_enabled" : True, # Flag controlling availability of direct-to-messaging http endpoint

"view_decorator" : None, # Specify a function to be used to wrap each of the dpd view functions

"cache_arguments" : True, # True for cache, False for session-based argument propagation
}

# Static files (CSS, JavaScript, Images)
Expand Down
13 changes: 2 additions & 11 deletions django_plotly_dash/templatetags/plotly_dash.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,12 @@

# pylint: disable=too-many-arguments, unused-variable, unused-argument, possibly-unused-variable

import uuid

from django import template
from django.core.cache import cache

from django.contrib.sites.shortcuts import get_current_site

from django_plotly_dash.models import DashApp
from django_plotly_dash.util import pipe_ws_endpoint_name, cache_timeout_initial_arguments
from django_plotly_dash.util import pipe_ws_endpoint_name, store_initial_arguments

register = template.Library()

Expand Down Expand Up @@ -74,13 +71,7 @@ def plotly_app(context, name=None, slug=None, da=None, ratio=0.1, use_frameborde
height: 100%;
"""

if initial_arguments:
# Generate a cache id
cache_id = "dpd-initial-args-%s" % str(uuid.uuid4()).replace('-', '')
# Store args in json form in cache
cache.set(cache_id, initial_arguments, cache_timeout_initial_arguments())
else:
cache_id = None
cache_id = store_initial_arguments(context['request'], initial_arguments)

da, app = _locate_daapp(name, slug, da, cache_id=cache_id)

Expand Down
41 changes: 41 additions & 0 deletions django_plotly_dash/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,3 +203,44 @@ def test_injection_updating(client):
assert response3.status_code == 200

assert response3.content.find(b'Test 789 content') > 0

@pytest.mark.django_db
def test_argument_settings(settings, client):
'Test the setting that controls how initial arguments are propagated through to the dash app'

from django_plotly_dash.util import initial_argument_location, store_initial_arguments, get_initial_arguments

assert initial_argument_location()

settings.PLOTLY_DASH = {'cache_arguments': True}

assert initial_argument_location()

test_value = {"test":"first"}

cache_id = store_initial_arguments(None, test_value)

assert len(cache_id) > 10

fetched = get_initial_arguments(None, cache_id)

assert fetched == test_value

settings.PLOTLY_DASH = {'cache_arguments': False}

assert not initial_argument_location()

cache_id2 = store_initial_arguments(client, test_value)

assert len(cache_id2) > 10

assert cache_id != cache_id2

## For some reason, sessions are continually replaced, so lookup here doesnt work
#fetched2 = get_initial_arguments(client, cache_id2)
#assert fetched2 == test_value

assert store_initial_arguments(None, None) is None
assert get_initial_arguments(None, None) is None
assert store_initial_arguments(client, None) is None
assert get_initial_arguments(client, None) is None
4 changes: 2 additions & 2 deletions django_plotly_dash/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@

for base_type, args, name_prefix, url_ending, name_suffix in [('instance', {}, '', '', '', ),
('app', {'stateless':True}, 'app-', '', '', ),
('instance', {}, '', '/initial/<slug:cache_id>/', '--args', ),
('app', {'stateless':True}, 'app-', '/initial/<slug:cache_id>/', '--args', ),
('instance', {}, '', '/initial/<slug:cache_id>', '--args', ),
('app', {'stateless':True}, 'app-', '/initial/<slug:cache_id>', '--args', ),
]:

for url_part, view_function, name, url_suffix in [('_dash-routes', routes, 'routes', '', ),
Expand Down
38 changes: 38 additions & 0 deletions django_plotly_dash/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@

'''

import uuid

from django.conf import settings
from django.core.cache import cache

def _get_settings():
try:
Expand Down Expand Up @@ -57,3 +60,38 @@ def http_poke_endpoint_enabled():
def cache_timeout_initial_arguments():
'Return cache timeout, in seconds, for initial arguments'
return _get_settings().get('cache_timeout_initial_arguments', 60)

def initial_argument_location():
'Return True if cache to be used for setting and getting initial arguments, or False for a session'

setget_location = _get_settings().get('cache_arguments', True)

return setget_location

def store_initial_arguments(request, initial_arguments=None):
'Store initial arguments, if any, and return a cache identifier'

if initial_arguments is None:
return None

# Generate a cache id
cache_id = "dpd-initial-args-%s" % str(uuid.uuid4()).replace('-', '')

# Store args in json form in cache
if initial_argument_location():
cache.set(cache_id, initial_arguments, cache_timeout_initial_arguments())
else:
request.session[cache_id] = initial_arguments

return cache_id

def get_initial_arguments(request, cache_id=None):
'Extract initial arguments for the dash app'

if cache_id is None:
return None

if initial_argument_location():
return cache.get(cache_id)

return request.session[cache_id]
7 changes: 2 additions & 5 deletions django_plotly_dash/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@
import json

from django.http import HttpResponse, HttpResponseRedirect
from django.core.cache import cache

from .models import DashApp
from .util import get_initial_arguments

def routes(*args, **kwargs):
'Return routes'
Expand All @@ -52,10 +52,7 @@ def layout(request, ident, stateless=False, cache_id=None, **kwargs):
view_func = app.locate_endpoint_function('dash-layout')
resp = view_func()

if cache_id:
initial_arguments = cache.get(cache_id)
else:
initial_arguments = None
initial_arguments = get_initial_arguments(request, cache_id)

response_data, mimetype = app.augment_initial_layout(resp, initial_arguments)
return HttpResponse(response_data,
Expand Down
11 changes: 11 additions & 0 deletions docs/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ below.

# Name of view wrapping function
"view_decorator": None,

# Flag to control location of initial argument storage
"cache_arguments": True,
}

Defaults are inserted for missing values. It is also permissible to not have any ``PLOTLY_DASH`` entry in
Expand Down Expand Up @@ -72,4 +75,12 @@ To restrict all access to logged-in users, use the ``login_required`` wrapper:

More information can be found in the :ref:`view decoration <access_control>` section.

.. _cache_arguments:

Initial arguments
-----------------

Initial arguments are stored within the server between the specification of an app in a template tag and the invocation of the
view functions for the app. This storage is transient and can be efficiently performed using Django's caching framework. In some
situations, however, a suitably configured cache is not available. For this use case, setting the ``cache_arguments`` flag to ``False`` will
cause initial arguments to be placed inside the Django session.