*********** Setup Views *********** **Last Updated:** November 2019 In this section, you will setup most of the views needed for this app. For a refresher on setting up url maps, controllers, and templates, see: :ref:`key_concepts_tutorial`. 1. Link URL =========== Add `UrlMaps` for each view to :file:`app.py` in the url_maps function so that it looks like the following: :: from tethys_sdk.base import TethysAppBase, url_map_maker class DaskTutorial(TethysAppBase): """ Tethys app class for Dask Tutorial. """ name = 'Dask Tutorial' index = 'dask_tutorial:home' icon = 'dask_tutorial/images/icon.gif' package = 'dask_tutorial' root_url = 'dask-tutorial' color = '#f39c12' description = 'Place a brief description of your app here.' tags = '' enable_feedback = False feedback_emails = [] def url_maps(self): """ Add controllers """ UrlMap = url_map_maker(self.root_url) url_maps = ( UrlMap( name='home', url='dask-tutorial', controller='dask_tutorial.controllers.home' ), UrlMap( name='jobs-table', url='dask-tutorial/dask/jobs_table', controller='dask_tutorial.controllers.jobs_table' ), UrlMap( name='result', url='dask-tutorial/dask/result/{job_id}', controller='dask_tutorial.controllers.result' ), UrlMap( name='error_message', url='dask-tutorial/dask/error', controller='dask_tutorial.controllers.error_message' ), ) return url_maps 2. Add Job Functions ==================== Create :file:`job_functions.py` and set its contents to the following: :: import time import dask def inc(x): time.sleep(3) return x + 1 def double(x): time.sleep(3) return x + 2 def add(x, y): time.sleep(10) return x + y def sum_up(x): time.sleep(5) return sum(x) def convert_to_dollar_sign(result): return '$' + str(result) .. important:: The :file:`job_functions.py` module contains all the functions that we will call using Dask. It is recommended that you follow the same pattern in your apps--splitting Dask functions into a separate file. Dask produces strange results when functions are defined in the same files as controllers or models. .. note:: The ``sleep`` calls in each function are to simulate functions that do real work and hence take time to run. 3. Setup Controller =================== Add the jobs button to the ``home`` controller in :file:`controller.py` module such that it looks like this: :: import random from django.shortcuts import render, reverse, redirect from tethys_sdk.permissions import login_required from django.http.response import HttpResponseRedirect from django.contrib import messages from tethys_sdk.gizmos import Button from tethys_sdk.compute import get_scheduler from tethys_sdk.gizmos import JobsTable from tethys_compute.models.dask.dask_job_exception import DaskJobException from tethysapp.dask_tutorial.app import DaskTutorial as app # get job manager for the app job_manager = app.get_job_manager() @login_required() def home(request): """ Controller for the app home page. """ jobs_button = Button( display_text='Show All Jobs', name='dask_button', attributes={ 'data-toggle': 'tooltip', 'data-placement': 'top', 'title': 'Show All Jobs' }, href=reverse('dask_tutorial:jobs-table') ) context = { 'jobs_button': jobs_button } return render(request, 'dask_tutorial/home.html', context) Add two new controllers, ``jobs_table`` and ``result``, and the error handler, ``error_message``, to the :file:`controller.py` module: :: ... @login_required() def jobs_table(request): # Use job manager to get all the jobs. jobs = job_manager.list_jobs(order_by='-id', filters=None) # Table View jobs_table_options = JobsTable( jobs=jobs, column_fields=('id', 'name', 'description', 'creation_time'), hover=True, striped=False, bordered=False, condensed=False, results_url='dask_tutorial:result', refresh_interval=1000, delete_btn=True, show_detailed_status=True, ) home_button = Button( display_text='Home', name='home_button', attributes={ 'data-toggle': 'tooltip', 'data-placement': 'top', 'title': 'Home' }, href=reverse('dask_tutorial:home') ) context = {'jobs_table': jobs_table_options, 'home_button': home_button} return render(request, 'dask_tutorial/jobs_table.html', context) @login_required() def result(request, job_id): # Use job manager to get the given job. job = job_manager.get_job(job_id=job_id) # Get result and name job_result = job.result name = job.name home_button = Button( display_text='Home', name='home_button', attributes={ 'data-toggle': 'tooltip', 'data-placement': 'top', 'title': 'Home' }, href=reverse('dask_tutorial:home') ) jobs_button = Button( display_text='Show All Jobs', name='dask_button', attributes={ 'data-toggle': 'tooltip', 'data-placement': 'top', 'title': 'Show All Jobs' }, href=reverse('dask_tutorial:jobs-table') ) context = {'result': job_result, 'name': name, 'home_button': home_button, 'jobs_button': jobs_button} return render(request, 'dask_tutorial/results.html', context) @login_required() def error_message(request): messages.add_message(request, messages.ERROR, 'Invalid Scheduler!') return redirect(reverse('dask_tutorial:home')) 3. Set up HTML ============== Create :file:`jobs_table.html`. Change it so that the contents are as follows: :: {% extends "dask_tutorial/base.html" %} {% load static tethys_gizmos %} {% load tethys_gizmos %} {% block global_scripts %} {{ block.super }} {% gizmo_dependencies global_js %} {% endblock %} {% block styles %} {{ block.super }} {% gizmo_dependencies global_css %} {% endblock %} {% block app_content %}