diff --git a/.github/workflows/tethys-release.yml b/.github/workflows/tethys-release.yml
index 20f9174cd..78a0ef038 100644
--- a/.github/workflows/tethys-release.yml
+++ b/.github/workflows/tethys-release.yml
@@ -173,3 +173,45 @@ jobs:
conda activate tethys;
echo "Publishing to dev channel...";
anaconda -t "${{ secrets.CONDA_UPLOAD_TOKEN }}" upload -u ${{ secrets.CONDA_UPLOAD_USER }} -l dev $CONDA_BLD_PATH/noarch/tethys-platform*.tar.bz2 --force;
+
+ # BUILD micro-tethys-platform
+
+ # Generate Conda Recipe With Constrained Dependencies
+ - name: Generate Conda Recipe - micro
+ run: |
+ cd ..
+ . ~/miniconda/etc/profile.d/conda.sh;
+ conda activate tethys;
+ tethys gen metayaml -p minor --micro --overwrite;
+ # Show Tethys Meta
+ - name: Show Tethys Meta - micro
+ run: |
+ cd ..
+ cat ./tethys/conda.recipe/meta.yaml
+ # Build Conda
+ - name: Build Conda - micro
+ run: |
+ cd ..
+ . ~/miniconda/etc/profile.d/conda.sh;
+ conda create -y -c conda-forge -n conda-build conda-build anaconda-client
+ conda activate conda-build
+ conda config --set anaconda_upload no
+ mkdir -p ~/conda-bld
+ conda-build -c tethysplatform -c conda-forge ./tethys/conda.recipe
+ # Upload to Anaconda Cloud
+ - name: Upload to Conda Release Channel - micro
+ if: ${{ steps.version.outputs.prerelease == '' }}
+ run: |
+ cd ..
+ . ~/miniconda/etc/profile.d/conda.sh;
+ conda activate tethys;
+ echo "Publishing to release channel...";
+ anaconda -t "${{ secrets.CONDA_UPLOAD_TOKEN }}" upload -u ${{ secrets.CONDA_UPLOAD_USER }} $CONDA_BLD_PATH/noarch/micro-tethys-platform*.tar.bz2 --force;
+ - name: Upload to Conda Dev Channel - micro
+ if: ${{ steps.version.outputs.prerelease != '' }}
+ run: |
+ cd ..
+ . ~/miniconda/etc/profile.d/conda.sh;
+ conda activate tethys;
+ echo "Publishing to dev channel...";
+ anaconda -t "${{ secrets.CONDA_UPLOAD_TOKEN }}" upload -u ${{ secrets.CONDA_UPLOAD_USER }} -l dev $CONDA_BLD_PATH/noarch/micro-tethys-platform*.tar.bz2 --force;
diff --git a/.github/workflows/tethys.yml b/.github/workflows/tethys.yml
index eddb9c422..e91e8bc45 100644
--- a/.github/workflows/tethys.yml
+++ b/.github/workflows/tethys.yml
@@ -217,7 +217,7 @@ jobs:
conda activate conda-build
conda config --set anaconda_upload no
mkdir -p ~/conda-bld
- conda-build -c tethysplatform -c conda-forge ./tethys/conda.recipe
+ conda-build -c conda-forge ./tethys/conda.recipe
# Upload Conda No Pull Request No Tag
- name: Upload Conda No Tag
if: ${{ github.event_name != 'pull_request' }}
@@ -232,3 +232,42 @@ jobs:
if: ${{ github.event_name == 'pull_request' }}
run: |
echo "Uploading is skipped for pull requests."
+
+ # BUILD micro-tethys-platform
+
+ # Generate Conda Recipe Without Constrained Dependencies
+ - name: Generate Conda Recipe - micro
+ run: |
+ cd ..
+ . ~/miniconda/etc/profile.d/conda.sh;
+ conda activate tethys;
+ tethys gen metayaml --micro --overwrite;
+ # Show Tethys Meta
+ - name: Show Tethys Meta - micro
+ run: |
+ cd ..
+ cat ./tethys/conda.recipe/meta.yaml
+ # Build Conda
+ - name: Build Conda - micro
+ run: |
+ cd ..
+ . ~/miniconda/etc/profile.d/conda.sh;
+ conda create -y -c conda-forge -n conda-build conda-build anaconda-client
+ conda activate conda-build
+ conda config --set anaconda_upload no
+ mkdir -p ~/conda-bld
+ conda-build -c conda-forge ./tethys/conda.recipe
+ # Upload Conda No Pull Request No Tag
+ - name: Upload Conda No Tag - micro
+ if: ${{ github.event_name != 'pull_request' }}
+ run: |
+ cd ..
+ . ~/miniconda/etc/profile.d/conda.sh;
+ ls ~/conda-bld/noarch
+ conda activate conda-build
+ anaconda -t "${{ secrets.CONDA_UPLOAD_TOKEN }}" upload -u ${{ secrets.CONDA_UPLOAD_USER }} -l dev $CONDA_BLD_PATH/noarch/micro-tethys-platform*.tar.bz2 --force;
+ # No Upload if Pull Request
+ - name: No Upload - micro
+ if: ${{ github.event_name == 'pull_request' }}
+ run: |
+ echo "Uploading is skipped for pull requests."
diff --git a/.gitignore b/.gitignore
index 23dcfa07b..da65bfd81 100644
--- a/.gitignore
+++ b/.gitignore
@@ -34,4 +34,5 @@ build/
dist/
tethys_portal/_version.py
# Required for docs build
-git-lfs-*/*
\ No newline at end of file
+git-lfs-*/*
+conda.recipe/meta.yaml
diff --git a/conda.recipe/meta.yaml b/conda.recipe/meta.yaml
deleted file mode 100644
index e1eccd748..000000000
--- a/conda.recipe/meta.yaml
+++ /dev/null
@@ -1,107 +0,0 @@
-# Conda Recipe for Tethys Platform
-# WARNING: THIS IS A GENERATED FILE. DO NOT EDIT.
-# TO CHANGE THIS FILE, SEE $TETHYS_SRC/tethys_cli/gen_templates/meta yaml
-
-
-package:
- name: tethys-platform
- version: 3.4.1.dev24+gb092a0af.d20220421
-
-source:
- path: ..
-
-build:
- number: 0
- string: {% if environ.get('GIT_DESCRIBE_NUMBER', 0)|int > 0 %}dev{{ GIT_BUILD_STR }}{% endif %}
- noarch: python
- script: python -m pip install --no-deps --ignore-installed .
- entry_points:
- - tethys = tethys_cli:tethys_command
-
-requirements:
- build:
- - python
- - pbr
- run:
- - python
- - pycrypto
- - pyopenssl
- - docker-py
- - distro
- - postgresql
- - psycopg2
- - sqlalchemy
- - geoalchemy2
- - plotly
- - bokeh
- - tethys_dataset_services>=2.0.0
- - hs_restclient
- - owslib
- - requests
- - dask
- - tethys_dask_scheduler>=1.0.2
- - service_identity
- - condorpy
- - siphon
- - python-jose
- - pyjwt<2.0.0
- - arrow
- - isodate
- - django=3.2.*
- - channels=3.*
- - daphne=3.*
- - django-analytical
- - django-axes
- - django-filter
- - djangorestframework
- - django-bootstrap5
- - django-model-utils
- - django-guardian
- - django-gravatar2
- - django-mfa2
- - django-recaptcha2
- - django-simple-captcha
- - django-session-security
- - django-termsandconditions
- - social-auth-app-django
- - selenium
- - coverage
- - factory_boy
- - pillow
- - pip
- - future
- - flake8
- - git
- - setuptools_scm
- - openssl<3.0.0
- - conda
-
-
-test:
- imports:
- - tethys_apps
- - tethys_cli
- - tethys_compute
- - tethys_config
- - tethys_gizmos
- - tethys_portal
- - tethys_quotas
- - tethys_sdk
- - tethys_services
-
-about:
- license: BSD-2-Clause
- license_family: BSD
- license_file: LICENSE
- summary: Primary Tethys Platform Django Site Project
- description: |
- Tethys Platform provides both a development environment
- and a hosting environment for scientific web applications.
- home: https://www.tethysplatform.org
- doc_url: http://docs.tethysplatform.org
- dev_url: https://github.com/tethysplatform/tethys
-
-extra:
- recipe-maintainers:
- - sdc50
- - swainn
\ No newline at end of file
diff --git a/docs/installation.rst b/docs/installation.rst
index f41a3e6ad..cd4522ed4 100644
--- a/docs/installation.rst
+++ b/docs/installation.rst
@@ -19,11 +19,11 @@ Also, be sure that the system you are using meets the minimum :ref:`system_reqs`
1. Install the ``tethys-platform`` Conda Package
------------------------------------------------
-a. To install the ``tethys-platform`` into a new conda environment then run the following commands:
+a. To install ``tethys-platform`` into a new conda environment then run the following commands:
.. code-block:: bash
- conda create -n tethys -c tethysplatform -c conda-forge tethys-platform
+ conda create -n tethys -c conda-forge tethys-platform
.. tip::
@@ -31,14 +31,25 @@ a. To install the ``tethys-platform`` into a new conda environment then run the
If conda is taking too long to solve the Tethys environment, try using the ``libmamba`` solver: :ref:`libmamba_solver`.
+ **Install Micro-Tethys**
+
+ The ``micro-tethys-platform`` conda package is a minimal version of ``tethys-platform``. It has the exact same code base, but doesn't include any of the optional dependencies. As a result the environment is much smaller, but none of the optional features will be enabled. Any of the optional features can be enabled simply by installing the dependencies required by those features (see :ref:`optional_features`).
+
+ .. code-block:: bash
+
+ conda create -n tethys -c tethysplatform -c conda-forge micro-tethys-platform
+
**Install Development Build**
- To install the latest development build of ``tethys-platform`` add the ``tethysplatform/label/dev`` channel to the list of conda channels::
+ To install the latest development build of ``tethys-platform`` add the ``tethysplatform/label/dev`` channel to the list of conda channels:
+
+ .. code-block:: bash
- conda create -n tethys -c tethysplatform/label/dev -c tethysplatform -c conda-forge tethys-platform
+ conda create -n tethys -c tethysplatform/label/dev -c conda-forge tethys-platform
Alternatively, to install from source refer to the :ref:`developer_installation` docs.
+
2. Activate the Tethys Conda Environment
----------------------------------------
@@ -51,7 +62,9 @@ Anytime you want to work with Tethys Platform, you'll need to activate the ``tet
3. Create a :file:`portal_config.yml` File
------------------------------------------
-To add custom configurations such as the database and other local settings you will need to generate a :file:`portal_config.yml` file. To generate a new template :file:`portal_config.yml` run::
+To add custom configurations such as the database and other local settings you will need to generate a :file:`portal_config.yml` file. To generate a new template :file:`portal_config.yml` run:
+
+.. code-block:: bash
tethys gen portal_config
@@ -61,20 +74,24 @@ You can customize your settings in the :file:`portal_config.yml` file after you
4. Configure the Tethys Database
--------------------------------
-Tethys Platform requires a PostgreSQL database server. There are several options for setting up a DB server: local, docker, or dedicated. For development environments you can use Tethys to create a local server::
+There are several options for setting up a DB server: local, docker, or remote. Tethys Platform uses a local SQLite database by default. For development environments you can use Tethys to create a local server:
+
+.. code-block:: bash
tethys db configure
.. note::
- The tethys db command (:ref:`tethys_db_cmd`) will create a local database server in the directory specified by the ``DIR`` setting in the ``DATABASES`` section of the :file:`portal_config.yml` file. If the value of ``DIR`` is a relative path then the database server will be created relative to directory specified by the ``TETHYS_HOME`` environment variable. By default ``TETHYS_HOME`` is at `~/.tethys`.
+ The tethys db command (:ref:`tethys_db_cmd`) will create a local database file in the location specified by the ``NAME`` setting in the ``DATABASES`` section of the :file:`portal_config.yml` file (by default ``tethys_platform.sqlite``). If the value of ``NAME`` is a relative path then the database file will be created relative to directory specified by the ``TETHYS_HOME`` environment variable. By default ``TETHYS_HOME`` is at `~/.tethys`.
- As an alternative to creating a local database server you can also configure a Docker DB server (see :ref:`using_docker`). A local database server is only recommended for development environments. For production environments please refer to :ref:`production_installation`.
+For additional options for configuring a database see :ref:`database_configuration`
5. Start the Development Server
-------------------------------
-Once you have a database successfully configured you can run the Tethys development server::
+Once you have a database successfully configured you can run the Tethys development server:
+
+.. code-block:: bash
tethys manage start
@@ -84,7 +101,7 @@ This will start up a locally running web server. You can access the Tethys Porta
You can customize the port that the server is running on by adding the ``-p`` option.
- ::
+ .. code-block:: bash
tethys manage start -p 8001
@@ -110,6 +127,7 @@ Related Docs
installation/system_requirements
tethys_portal/configuration
+ installation/database_configuration
installation/conda
installation/application
installation/showcase_apps
diff --git a/docs/installation/application.rst b/docs/installation/application.rst
index d00481329..d3cf346b4 100644
--- a/docs/installation/application.rst
+++ b/docs/installation/application.rst
@@ -72,6 +72,18 @@ install.yml
This file is generated with your application scaffold. Dependencies that are listed in the ``install.yml`` will be installed with conda and will honor the specified channel priority. If there are any dependencies listed in the ``setup.py`` that are not specified in the ``install.yml`` then these packages will be installed with pip as part of the setup process. This file should be committed with your application code in order to aid installation on a Tethys Portal.
+.. important::
+
+ The ``conda`` sections of the ``install.yml`` file require the ``conda`` library and optionally the ``conda-libmamba-solver`` library to be installed. Starting with Tethys 5.0 or if you are using ``micro-tethys-platform``, you will need to install these libraries using conda or pip as follows:
+
+ .. code-block:: bash
+
+ # conda: conda-forge channel strongly recommended
+ conda install -c conda-forge conda conda-libmamba-solver
+
+ # pip
+ pip install conda
+
.. literalinclude:: resources/example-install.yml
:language: yaml
diff --git a/docs/installation/production/docker/docker_compose.rst b/docs/installation/production/docker/docker_compose.rst
index d79e72b83..e038af829 100644
--- a/docs/installation/production/docker/docker_compose.rst
+++ b/docs/installation/production/docker/docker_compose.rst
@@ -305,7 +305,7 @@ c. Add the following contents to each ``.env`` file:
**db.env**
- .. code-block:: env
+ .. code-block:: docker
# Password of the db admin account
POSTGRES_PASSWORD=please_dont_use_default_passwords
@@ -323,7 +323,7 @@ c. Add the following contents to each ``.env`` file:
**thredds.env**
- .. code-block:: env
+ .. code-block:: docker
# Password of the TDM admin user
TDM_PW=please_dont_use_default_passwords
@@ -355,7 +355,7 @@ c. Add the following contents to each ``.env`` file:
**web.env**
- .. code-block:: env
+ .. code-block:: docker
# Domain name of server should be first in the list if multiple entries added
ALLOWED_HOSTS="\"[localhost]\""
@@ -471,7 +471,7 @@ a. Create a :file:`.gitignore` file:
b. Add the following contents to the :file:`.gitignore` file to omit the contents of these directories from being tracked:
- .. code-block:: gitignore
+ .. code-block:: text
data/
keys/
diff --git a/docs/installation/production/manual/configuration/advanced/images/webanalytics.png b/docs/installation/production/manual/configuration/advanced/images/webanalytics.png
deleted file mode 100644
index 38725750a..000000000
--- a/docs/installation/production/manual/configuration/advanced/images/webanalytics.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:9e008b4396af02e9341686d28fd10d5dc981d9f049401b908097a8dcc4719e0d
-size 34841
diff --git a/docs/installation/production/manual/configuration/advanced/lockout.rst b/docs/installation/production/manual/configuration/advanced/lockout.rst
index 07eb0b4fe..a7b0267d7 100644
--- a/docs/installation/production/manual/configuration/advanced/lockout.rst
+++ b/docs/installation/production/manual/configuration/advanced/lockout.rst
@@ -6,6 +6,18 @@ Lockout (Optional)
**Last Updated:** May 2020
+.. important::
+
+ This feature requires the ``django-axes`` library to be installed. Starting with Tethys 5.0 or if you are using ``micro-tethys-platform``, you will need to install ``django-axes`` using conda or pip as follows:
+
+ .. code-block:: bash
+
+ # conda: conda-forge channel strongly recommended
+ conda install -c conda-forge django-axes
+
+ # pip
+ pip install django-axes
+
Tethys Portal includes lockout capabilities to prevent brute-force login attempts. This capability is provided by the `Django Axes `_ add-on for Django. This document describes the different configuration options that are available for lockout capabilities in Tethys Portal.
.. image:: ./images/locked_out.png
diff --git a/docs/installation/production/manual/configuration/advanced/multi_factor_auth.rst b/docs/installation/production/manual/configuration/advanced/multi_factor_auth.rst
index 0b6e0febc..99c562ba6 100644
--- a/docs/installation/production/manual/configuration/advanced/multi_factor_auth.rst
+++ b/docs/installation/production/manual/configuration/advanced/multi_factor_auth.rst
@@ -6,6 +6,19 @@ Multi Factor Authentication (Optional)
**Last Updated:** September 2020
+.. important::
+
+ These settings require the ``django-mfa2``, ``arrow``, and ``isodate`` libraries to be installed. Starting with Tethys 5.0 or if you are using ``micro-tethys-platform``, you will need to install these libraries using conda or pip as follows:
+
+ .. code-block:: bash
+
+ # conda: conda-forge channel strongly recommended
+ conda install -c conda-forge django-mfa2 arrow isodate
+
+ # pip
+ pip install django-mfa2 arrow isodate
+
+
Tethys allows you to enable/enforce the use of multi factor authentication through apps such as LastPass Authenticator or Google Authenticator. This capability is provided by `Django MFA2 `_. This tutorial will show you how to enable that functionality.
diff --git a/docs/installation/production/manual/configuration/advanced/social_auth.rst b/docs/installation/production/manual/configuration/advanced/social_auth.rst
index e8cae6692..48642430f 100644
--- a/docs/installation/production/manual/configuration/advanced/social_auth.rst
+++ b/docs/installation/production/manual/configuration/advanced/social_auth.rst
@@ -6,6 +6,18 @@ Single Sign On (Optional)
**Last Updated:** December 2020
+.. important::
+
+ This feature requires the ``social-auth-app-django`` library to be installed. Starting with Tethys 5.0 or if you are using ``micro-tethys-platform``, you will need to install ``social-auth-app-django`` using conda or pip as follows:
+
+ .. code-block:: bash
+
+ # conda: conda-forge channel strongly recommended
+ conda install -c conda-forge social-auth-app-django
+
+ # pip
+ pip install social-auth-app-django
+
Tethys Portal supports authenticating users with several social authentication and single sign on providers such as Google, Facebook, and LinkedIn via the OAuth 2.0 method. The social authentication and authorization features have been implemented using the `Python Social Auth `_ module. Social login is disabled by default, because enabling it requires registering your tethys portal instance with each provider.
@@ -187,7 +199,7 @@ Facebook
b. Press the ``Setup`` button on the tile (or ``Settings`` if setup previously).
c. Specify the following for the Valid OAuth Redirect URIs field:
- ::
+ .. code-block::
https:///oauth2/complete/facebook/
@@ -245,7 +257,7 @@ Google
As a security precaution, Google will only accept authentication requests from the hosts listed in the ``Authorized JavaScript Origins`` box. Add the domain of your Tethys Portal to the list. Optionally, you may add a localhost domain to the list to be used during testing:
- ::
+ .. code-block::
https://
http://localhost:8000
@@ -258,7 +270,7 @@ Google
You also need to provide the callback URI for Google to call once it has authenticated the user. This follows the pattern ``http:///oauth2/complete/google-oauth2/``:
- ::
+ .. code-block::
https:///oauth2/complete/google-oauth2/
https://localhost:8000/oauth2/complete/google-oauth2/
@@ -299,6 +311,18 @@ For more detailed information about using Google social authentication see the f
HydroShare
----------
+.. important::
+
+ This feature requires the ``hs_restclient`` library to be installed. Starting with Tethys 5.0 or if you are using ``micro-tethys-platform``, you will need to install ``hs_restclient`` using conda or pip as follows:
+
+ .. code-block:: bash
+
+ # conda: conda-forge channel strongly recommended
+ conda install -c conda-forge hs_restclient
+
+ # pip
+ pip install hs_restclient
+
1. Create a HydroShare Account
You will need a HydroShare account to register your Tethys Portal with HydroShare. To create an account, visit `https://www.hydroshare.org `_.
@@ -319,7 +343,7 @@ HydroShare
g. Redirect uris: Add the call back URLs. The protocol (http or https) that matches your Tethys Portal settings should be included in this url. For example:
- ::
+ .. code-block::
if your Tethys Portal was located at the domain ``https://www.my-tethys-portal.com``:
https://www.my-tethys-portal.com/oauth2/complete/hydroshare/
@@ -509,7 +533,7 @@ LinkedIn
a. Add the call back URLs under the **OAuth 2.0 settings** section:
- ::
+ .. code-block::
https:///oauth2/complete/linkedin-oauth2/
http://localhost:8000/oauth2/complete/linkedin-oauth2/
diff --git a/docs/installation/production/manual/configuration/advanced/webanalytics.rst b/docs/installation/production/manual/configuration/advanced/webanalytics.rst
index ecf19ba16..4f2974a5d 100644
--- a/docs/installation/production/manual/configuration/advanced/webanalytics.rst
+++ b/docs/installation/production/manual/configuration/advanced/webanalytics.rst
@@ -4,9 +4,17 @@ Web Analytics (Optional)
**Last Updated:** May 2020
-.. image:: ./images/webanalytics.png
- :width: 300px
- :align: right
+.. important::
+
+ This feature requires the ``django-analytical`` library to be installed. Starting with Tethys 5.0 or if you are using ``micro-tethys-platform``, you will need to install ``django-analytical`` using conda or pip as follows:
+
+ .. code-block:: bash
+
+ # conda: conda-forge channel strongly recommended
+ conda install -c conda-forge django-analytical
+
+ # pip
+ pip install django-analytical
Tethys portals are configured to allow portal administrators to track how users interact with their portal and applications using web based analytical services. 24 services, including common services like Google Analytical and Optimizely, can be configured using the `Django-Analytical `_ package.
diff --git a/docs/installation/production/manual/configuration/basic/database.rst b/docs/installation/production/manual/configuration/basic/database.rst
index c229e2b85..399769874 100644
--- a/docs/installation/production/manual/configuration/basic/database.rst
+++ b/docs/installation/production/manual/configuration/basic/database.rst
@@ -4,11 +4,22 @@
Production Database
*******************
-**Last Updated:** September 2022
+**Last Updated:** September 2023
In this part of the production deployment guide, you will learn how to initialize and configure the Tethys Portal database for production.
-1. Set Database Settings
+1. Install Python dependencies
+==============================
+
+Using a PostgreSQL database for production requires the ``psycopg2`` Python package. Also, While we do not recommend having your database on the same server as Tethys Portal, the commands to automate setting up and configuring the database require that the PostgreSQL database and the ``psycopg2`` library be installed on the web server. Starting with Tethys 5.0 or if you are using ``micro-tethys-platform``, you will need to install ``postgresql`` and ``psycopg2`` using conda as follows:
+
+
+ .. code-block:: bash
+
+ # conda: conda-forge channel strongly recommended
+ conda install -c conda-forge postgresql psycopg2
+
+2. Set Database Settings
========================
Set the database settings in the :file:`portal_config.yml` using the ``tethys settings`` command:
@@ -25,7 +36,7 @@ Set the database settings in the :file:`portal_config.yml` using the ``tethys se
**DO NOT USE DEFAULT USERNAMES OR PASSWORDS FOR PRODUCTION DATABASE ACCOUNTS**
-2. Create Tethys Database and Database Users
+3. Create Tethys Database and Database Users
============================================
Use the ``tethys db create`` command to create the database users and tables required by Tethys Portal:
@@ -42,7 +53,7 @@ Use the ``tethys db create`` command to create the database users and tables req
**DO NOT USE DEFAULT USERNAMES OR PASSWORDS FOR PRODUCTION DATABASE ACCOUNTS**
-3. Create Tethys Database Tables
+4. Create Tethys Database Tables
================================
Run the following command to create the Tethys database tables:
@@ -51,7 +62,7 @@ Run the following command to create the Tethys database tables:
tethys db migrate
-4. Create Portal Admin User
+5. Create Portal Admin User
===========================
You will need to create at least one Portal Admin account to allow you to login to your Tethys Portal. Create the account as follows:
diff --git a/docs/installation/production/manual/installation.rst b/docs/installation/production/manual/installation.rst
index cad9abf11..be45aa306 100644
--- a/docs/installation/production/manual/installation.rst
+++ b/docs/installation/production/manual/installation.rst
@@ -11,27 +11,81 @@ This article will provide an overview of how to install Tethys Portal in a produ
Install Miniconda
=================
- 1. As of version 3.0, Tethys Platform can be installed using `conda `_. We recommend installing `Miniconda `_ as it provides a minimal installation of conda that is appropriate for servers:
+1. As of version 3.0, Tethys Platform can be installed using `conda `_. We recommend installing `Miniconda `_ as it provides a minimal installation of conda that is appropriate for servers:
- .. code-block:: bash
+ .. code-block:: bash
- cd /tmp
- wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
- bash ./Miniconda3-latest-Linux-x86_64.sh
+ cd /tmp
+ wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
+ bash ./Miniconda3-latest-Linux-x86_64.sh
- 2. Read the license and accept when prompted. Install to the default location (:file:`~/miniconda3`) and configure the shell to start on startup.
+2. Read the license and accept when prompted. Install to the default location (:file:`~/miniconda3`) and configure the shell to start on startup.
Install Tethys Platform
=======================
- 1. Create a new conda environment called ``tethys`` with the ``tethys-platform`` package installed:
+1. Create a new conda environment called ``tethys`` with the ``tethys-platform`` package installed:
- .. code-block:: bash
+ .. code-block:: bash
- conda create -n tethys -c conda-forge -c tethysplatform tethys-platform
+ conda create -n tethys -c conda-forge tethys-platform
- 2. Activate the ``tethys`` conda environment after it is created:
+2. Activate the ``tethys`` conda environment after it is created:
- .. code-block:: bash
+ .. code-block:: bash
- conda activate tethys
+ conda activate tethys
+
+Install Optional Dependencies
+=============================
+
+Beginning with Tethys v5.0 or if you are using ``micro-tethys-platform`` many features of Tethys that require additional dependencies are optional. This allows you to select only the dependencies that you need for the features required in your deployment and maintains a minimal environment size. To the the list of optional features and their required dependencies see :ref:`optional_features`.
+
+1. Gather the list of optional dependencies that you want to include in your portal. Refer to the :ref:`optional_features` documentation and ensure that you have any dependencies that are required by features used by the apps that you will install into your portal.
+
+
+2. Ensure that your ``tethys`` conda environment is active:
+
+ .. code-block:: bash
+
+ conda activate tethys
+
+3. Install the optional dependencies:
+
+ .. code-block:: bash
+
+ conda install -c conda-forge < DEPENDENCY_1 > < DEPENDENCY_2 > ...
+
+ For example, if the list of optional dependencies you wanted to install was: ``django-session-security``, ``django-axes``, ``django-gravatar2``, ``social-auth-app-django``, ``postgresql``, ``psycopg2``, ``sqlalchemy``, and ``tethys_dataset_services``, then you would install them with the following command:
+
+ .. code-block:: bash
+
+ conda install -c conda-forge django-session-security django-axes django-gravatar2 social-auth-app-django postgresql psycopg2 "sqlalchemy<2" tethys_dataset_services
+
+.. tip::
+
+ To simplify the process of installing ``tethys-platform`` and any optional dependencies, consider creating a conda environment YAML file (:file:`environment.yml`) for your portal. For example:
+
+ .. code-block:: yaml
+
+ name: tethys
+
+ channels:
+ - conda-forge
+
+ dependencies:
+ - tethys-platform
+ - django-session-security
+ - django-axes
+ - django-gravatar2
+ - social-auth-app-django
+ - postgresql
+ - psycopg2
+ - sqlalchemy<2
+ - tethys_dataset_services
+
+ Use the following command to create your environment from an environment YAML file:
+
+ .. code-block:: bash
+
+ conda env create -f environment.yml
diff --git a/docs/installation/resources/example-portal-config.yml b/docs/installation/resources/example-portal-config.yml
index 495307fe7..e13715396 100644
--- a/docs/installation/resources/example-portal-config.yml
+++ b/docs/installation/resources/example-portal-config.yml
@@ -36,6 +36,10 @@ settings:
# STATIC_ROOT: ''
# TETHYS_WORKSPACES_ROOT: ''
# STATICFILES_USE_NPM: True
+ # ADDITIONAL_TEMPLATE_DIRS:
+ # - tethysapp.myapp.templates
+ # ADDITIONAL_URLPATTERNS:
+ # - tethysext.myextension.urls
SESSION_CONFIG:
EXPIRE_AT_BROWSER_CLOSE: True
diff --git a/docs/supplementary.rst b/docs/supplementary.rst
index 7a324fbbe..66144ed70 100644
--- a/docs/supplementary.rst
+++ b/docs/supplementary.rst
@@ -7,14 +7,15 @@ Supplemental
This section provides a list of miscellaneous reference material that can be used to help you understand Tethys Platform and Tethys app development in more detail.
.. toctree::
- :maxdepth: 1
+ :maxdepth: 1
- supplementary/key_concepts
- supplementary/app_project
- supplementary/terminal_quick_guide
- supplementary/install_ubuntu
- supplementary/docker_testing
- supplementary/pgadmin
- ./glossary
- ./summary
+ supplementary/key_concepts
+ supplementary/optional_features
+ supplementary/app_project
+ supplementary/terminal_quick_guide
+ supplementary/install_ubuntu
+ supplementary/docker_testing
+ supplementary/pgadmin
+ ./glossary
+ ./summary
diff --git a/docs/supplementary/optional_features.rst b/docs/supplementary/optional_features.rst
new file mode 100644
index 000000000..73478e5a7
--- /dev/null
+++ b/docs/supplementary/optional_features.rst
@@ -0,0 +1,271 @@
+.. _optional_features:
+
+*****************
+Optional Features
+*****************
+
+With the release of ``micro-tethys-platform`` and starting with Tethys v5.0 many features of Tethys Platform will become optional and require additional dependencies to be installed. This is done to limit the size of the environment and allow Tethys Portal administrators more flexibility in deciding what features are needed in their deployment. The following list of features are optional and will require the listed dependencies to be installed for that feature to be enabled:
+
+Security Features
+=================
+
+Session Security
+----------------
+
+Session security enables setting timeouts for user sessions and automatically logging them out.
+
+**dependencies**
+ - ``django-session-security``
+
+
+Track Failed Login Attempts
+---------------------------
+
+Tracking failed logins allows Tethys to lock user accounts after a certain number of failed attempts, and alerts users of the number of failed attempts when they login.
+
+**dependencies**
+ - ``django-axes``
+
+
+Add CORS Headers
+----------------
+
+Adds CORS headers to enable Tethys resources to be accessed on other domains.
+
+**dependencies**
+ - ``django-cors-headers``
+
+Login/Accounts
+==============
+
+Gravatar
+--------
+
+Gravatar provides a user avatar image in the user's profile.
+
+**dependencies**
+ - ``django-gravatar2``
+
+Captcha
+-------
+
+Captcha requires users to type the code from an image during login.
+
+**dependencies**
+ - ``django-simple-captcha``
+
+ReCaptcha
+---------
+
+ReCaptcha uses a Google provided service to verify that the user logging in is human.
+
+**dependencies**
+ - ``django-recaptcha2``
+
+Multi-Factor Authentication
+---------------------------
+
+Allows users to enable multi-factor authentication for their Tethys Portal account.
+
+**dependencies**
+ - ``django-mfa2``
+ - ``arrow``
+ - ``isodate``
+
+Single Sign On with Social Accounts
+-----------------------------------
+
+Allow users to login to Tethys using 3rd party accounts (e.g. GitHub, Google, Facebook, etc.).
+
+**dependencies**
+ - ``social-auth-app-django``
+
+SSO with HydroShare
++++++++++++++++++++
+
+Allows configuration of HydroShare as an SSO
+
+**dependencies**
+ - ``hs_restclient``
+
+SSO with OneLogin
++++++++++++++++++
+
+Allows configuration of OneLogin as an SSO
+
+**dependencies**
+ - ``python-jose``
+
+OAuth2 Provider
+---------------
+
+Enables a Tethys Portal to be a provider of OAuth2 authentication.
+
+**dependencies**
+ - ``django-oauth-toolkit``
+
+Portal Enhancements
+===================
+
+Terms and Conditions
+--------------------
+
+Enables portal administrators to define terms and conditions that users must accept to use the portal.
+
+**dependencies**
+ - ``django-termsandconditions``
+
+Web Analytics Tracking
+----------------------
+
+Gathers web analytics statistics from portal usage.
+
+**dependencies**
+ - ``django-analytical``
+
+JSON Widget
+-----------
+
+Enables a JSON widget in the admin pages for app settings.
+
+**dependencies**
+ - ``django-json-widget``
+
+RESTful Framework
+-----------------
+
+Provides a framework for defining REST APIs.
+
+**dependencies**
+ - ``djangorestframework``
+
+Mapping
+=======
+
+May Layout Shapefile Support
+----------------------------
+
+Enables converting geojson to shapefile.
+
+
+**dependencies**
+ - ``PyShp``
+
+Command Line Interface
+======================
+
+Docker
+------
+
+Enables the ``docker`` command on the ``tethys`` CLI.
+
+**dependencies**
+ - ``docker-py``
+
+Conda Installer
+---------------
+
+Enables the `tethys install`` commands to install conda packages.
+
+**dependencies**
+ - ``conda``
+ - ``conda-libmamba-solver``
+
+Databases
+=========
+
+PostgreSQL
+----------
+
+Enables ``tethys db`` commands to setup local or remote PostgreSQL databases.
+
+**dependencies**
+ - ``postgresql``
+ - ``psycopg2``
+
+Persistent Stores
+-----------------
+
+Enables apps to define and use persistent stores.
+
+**dependencies**
+ - ``sqlalchemy<2``
+ - ``psycopg2`` (or other DB driver for Persistent Store type)
+
+Spatial Persistent Stores
+-------------------------
+
+Enables apps to define spatial persistent stores.
+
+**dependencies**
+ - ``sqlalchemy<2``
+ - ``geoalchemy2``
+
+Gizmos
+======
+
+Bokeh Plots
+-----------
+
+Enables the Bokeh plotting gizmo.
+
+**dependencies**
+ - ``bokeh``
+
+Plotly Plots
+------------
+
+Enables the Plotly plotting gizmo.
+
+**dependencies**
+ - ``plotly``
+
+Tethys Compute
+==============
+
+Dask Job Type
+-------------
+
+Enables the Dask job type.
+
+**dependencies**
+ - ``dask``
+ - ``tethys_dask_scheduler``
+
+HTCondor Job Types
+------------------
+
+Enables the HTCondor job and workflow types
+
+**dependencies**
+ - ``condorpy``
+
+External Services
+=================
+
+Dataset Services
+----------------
+
+Enables the :term:`dataset services` APIs for CKAN and GeoServer.
+
+**dependencies**
+ - ``tethys_dataset_services``
+
+THREDDS Spatial Dataset Service
+-------------------------------
+
+Enables using THREDDS as a spatial dataset service.
+
+**dependencies**
+ - ``siphon``
+
+
+Web Processing Services (WPS)
+-----------------------------
+
+Enables apps to define WPS endpoints.
+
+**dependencies**
+ - ``owslib``
+
+
diff --git a/docs/tethys_cli/db.rst b/docs/tethys_cli/db.rst
index ef4f6950d..837c42510 100644
--- a/docs/tethys_cli/db.rst
+++ b/docs/tethys_cli/db.rst
@@ -5,6 +5,23 @@ db command
Setup and manage a Tethys database.
+.. important::
+
+ The default database configuration uses SQLite. Many of these commands are not applicable to SQLite databases and only support PostgreSQL databases. To use a PostgreSQL database be sure to set your settings accordingly. At the very least:
+
+ .. code-block:: bash
+
+ tethys settings --set DATABASES.default.ENGINE django.db.backends.postgresql
+
+ For more details see :ref:`database_configuration`
+
+ Additionally, the PostgreSQL database and the ``psycopg2`` library must be installed. Starting with Tethys 5.0 or if you are using ``micro-tethys-platform``, you will need to install ``postgresql`` and ``psycopg2`` using conda as follows:
+
+ .. code-block:: bash
+
+ # conda: conda-forge channel strongly recommended
+ conda install -c conda-forge postgresql psycopg2
+
.. argparse::
:module: tethys_cli
:func: tethys_command_parser
diff --git a/docs/tethys_cli/docker.rst b/docs/tethys_cli/docker.rst
index 2b8926807..ac1bc2ba0 100644
--- a/docs/tethys_cli/docker.rst
+++ b/docs/tethys_cli/docker.rst
@@ -9,6 +9,14 @@ Manage Tethys-sponsored Docker containers. To learn more about Docker, see `What
You must have Docker installed and add your user to the ``docker`` group to use the Tethys ``docker`` command (see: `Install Docker `_ and `Post-installation steps for Linux `_).
+ Additionally, this feature requires the ``docker-py`` library to be installed. Starting with Tethys 5.0 or if you are using ``micro-tethys-platform``, you will need to install ``docker-py`` using conda as follows:
+
+ .. code-block:: bash
+
+ # conda: conda-forge channel strongly recommended
+ conda install -c conda-forge docker-py
+
+
.. argparse::
:module: tethys_cli
:func: tethys_command_parser
diff --git a/docs/tethys_portal.rst b/docs/tethys_portal.rst
index 20e6768b1..f0c4331c2 100644
--- a/docs/tethys_portal.rst
+++ b/docs/tethys_portal.rst
@@ -2,7 +2,7 @@
Tethys Portal
*************
-**Last Updated:** April 29, 2019
+**Last Updated:** August 2023
Tethys Portal is the Django web site provided by Tethys Platform that acts as the runtime environment for apps. It leverages the capabilities of Django to provide the core website functionality that is often taken for granted in modern web applications. A description of the primary capabilities of Tethys Portal is provided in this section.
@@ -12,7 +12,6 @@ Tethys Portal is the Django web site provided by Tethys Platform that acts as th
tethys_portal/configuration
tethys_portal/admin_pages
tethys_portal/tethys_users
- tethys_portal/developer_tools
tethys_portal/feedback
diff --git a/docs/tethys_portal/admin_pages.rst b/docs/tethys_portal/admin_pages.rst
index e18197518..0882e4b0f 100644
--- a/docs/tethys_portal/admin_pages.rst
+++ b/docs/tethys_portal/admin_pages.rst
@@ -17,7 +17,7 @@ Tethys Portal includes administration pages that can be used to manage the websi
If you did not create an administrator user during installation, run the following command in the terminal:
- ::
+ .. code-block:: console
tethys manage createsuperuser
@@ -26,6 +26,18 @@ Tethys Portal includes administration pages that can be used to manage the websi
Auth Token
==========
+.. important::
+
+ This feature requires the ``djangorestframework`` library to be installed. Starting with Tethys 5.0 or if you are using ``micro-tethys-platform``, you will need to install ``djangorestframework`` using conda or pip as follows:
+
+ .. code-block:: bash
+
+ # conda: conda-forge channel strongly recommended
+ conda install -c conda-forge djangorestframework
+
+ # pip
+ pip install djangorestframework
+
Tethys REST API tokens for individual users can be managed using the ``Tokens`` link under the ``AUTH TOKEN`` heading (see Figure 2).
.. figure:: ../images/site_admin/auth_token.png
@@ -154,6 +166,18 @@ Tethys leverages the excellent `Python Social Auth /workspaces`.
STATIC_ROOT the Django `STATIC_ROOT `_ setting. Defaults to :file:`/static`.
STATICFILES_USE_NPM serves JavaScript dependencies through Tethys rather than using a content delivery network (CDN) when ``True``. Defaults to ``False``. When set to ``True`` then you must run ``tethys gen package_json`` to npm install the JS dependencies locally so they can be served by Tethys.
+ADDITIONAL_TEMPLATE_DIRS a list of dot-paths to template directories. These will be prepended to Tethys's list of template directories so specific templates can be overriden.
+ADDITIONAL_URLPATTERNS a list of dot-paths to list or tuples that define additional URL patterns to register in the portal. Additional URL patterns will precede default URL patterns so URLs will first match against user specified URL patterns.
================================================== ================================================================================
SESSION_CONFIG
++++++++++++++
+.. important::
+
+ These settings require the ``django-session-security`` library to be installed. Starting with Tethys 5.0 or if you are using ``micro-tethys-platform``, you will need to install ``django-session-security`` using conda or pip as follows:
+
+ .. code-block:: bash
+
+ # conda: conda-forge channel strongly recommended
+ conda install -c conda-forge django-session-security
+
+ # pip
+ pip install django-session-security
+
================================================== ================================================================================
Setting Description
================================================== ================================================================================
@@ -94,6 +108,8 @@ SESSION_SECURITY_WARN_AFTER the Django Session Security `
SESSION_SECURITY_EXPIRE_AFTER the Django Session Security `EXPIRE_AFTER `_ setting. Defaults to 900 seconds.
================================================== ================================================================================
+.. _database_settings:
+
DATABASES
+++++++++
@@ -116,7 +132,7 @@ See the Django `DATABASES `_ setting. Not used with SQLite. |
+--+----------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
-| | DIR | name of psql directory for conda installation of PostgreSQL that ships with Tethys (if using the ``django.db.backends.postgresql`` ``ENGINE``). This directory will be created relative to the ``TETHYS_HOME`` directory when ``tethys db create`` is executed, unless an absolute path is provided. Defaults to ``psql``. If you are using the ``sqlite3`` ``ENGINE`` or an external database server then exclude this key or set it to `None`. |
+| | DIR | name of psql directory for a local PostgreSQL database (if using the ``django.db.backends.postgresql`` ``ENGINE``). This directory will be created relative to the ``TETHYS_HOME`` directory when ``tethys db create`` is executed, unless an absolute path is provided. If you are using the ``sqlite3`` ``ENGINE`` or an external database server then exclude this key or set it to `None`. |
+--+----------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
LOGGING
@@ -153,9 +169,26 @@ LOGGING
CAPTCHA_CONFIG
++++++++++++++
+.. important::
+
+ These Captcha feature requires either the ``django-simple-captcha`` library or the ``django-recaptcha2`` library to be installed. Starting with Tethys 5.0 or if you are using ``micro-tethys-platform``, you will need to install one of these libraries using conda or pip as follows:
+
+ .. code-block:: bash
+
+ # conda: conda-forge channel strongly recommended
+ conda install -c conda-forge django-simple-captcha
+ # Or
+ conda install -c conda-forge django-recaptcha2
+
+ # pip
+ pip install django-simple-captcha
+ # Or
+ pip install django-recaptcha2
+
================================================== ================================================================================
Setting Description
================================================== ================================================================================
+ENABLE_CAPTCHA Boolean specifying if captcha should be enabled on the login screen. If using Google ReCaptcha then the following two settings are required. Default is ``False``
RECAPTCHA_PRIVATE_KEY Private key for Google ReCaptcha. Required to enable ReCaptcha on the login screen. See `Django Recaptcha 2 Installation `_.
RECAPTCHA_PUBLIC_KEY Public key for Google ReCaptcha. Required to enable ReCaptcha on the login screen. See `Django Recaptcha 2 Installation `_.
RECAPTCHA_PROXY_HOST Proxy host for Google ReCaptcha. Optional. See `Django Recaptcha 2 Installation `_.
@@ -164,6 +197,38 @@ RECAPTCHA_PROXY_HOST Proxy host for Google ReCaptc
OAUTH_CONFIG
++++++++++++
+.. important::
+
+ These settings require the ``social-auth-app-django`` library to be installed. Starting with Tethys 5.0 or if you are using ``micro-tethys-platform``, you will need to install ``social-auth-app-django`` using conda or pip as follows:
+
+ .. code-block:: bash
+
+ # conda: conda-forge channel strongly recommended
+ conda install -c conda-forge social-auth-app-django
+
+ # pip
+ pip install social-auth-app-django
+
+ If using the OneLogin OIDC provider, you will also need to install the ``python-jose`` library:
+
+ .. code-block:: bash
+
+ # conda: conda-forge channel strongly recommended
+ conda install -c conda-forge python-jose
+
+ # pip
+ pip install python-jose
+
+ If using the HydroShare provider, you will also need the ``hs_restclient`` library:
+
+ .. code-block:: bash
+
+ # conda: conda-forge channel strongly recommended
+ conda install -c conda-forge hs_restclient
+
+ # pip
+ pip install hs_restclient
+
================================================== ================================================================================
Setting Description
================================================== ================================================================================
@@ -214,6 +279,18 @@ SOCIAL_AUTH_ONELOGIN_OIDC_SUBDOMAIN Your OneLogin Subdomain. See
MFA_CONFIG
++++++++++
+.. important::
+
+ These settings require the ``django-mfa2``, ``arrow``, and ``isodate`` libraries to be installed. Starting with Tethys 5.0 or if you are using ``micro-tethys-platform``, you will need to install these libraries using conda or pip as follows:
+
+ .. code-block:: bash
+
+ # conda: conda-forge channel strongly recommended
+ conda install -c conda-forge django-mfa2 arrow isodate
+
+ # pip
+ pip install django-mfa2 arrow isodate
+
================================================== ================================================================================
Setting Description
================================================== ================================================================================
@@ -230,7 +307,20 @@ MFA_UNALLOWED_METHODS A list of MFA methods to be d
ANALYTICS_CONFIG
++++++++++++++++
-the Django Analytical configuration settings for enabling analytics services on the Tethys Portal (see: `Enabling Services - Django Analytical `_. The following is a list of settings for some of the supported services that can be enabled.
+The Django Analytical configuration settings for enabling analytics services on the Tethys Portal (see: `Enabling Services - Django Analytical `_. The following is a list of settings for some of the supported services that can be enabled.
+
+
+.. important::
+
+ These settings require the ``django-analytical`` library to be installed. Starting with Tethys 5.0 or if you are using ``micro-tethys-platform``, you will need to install ``django-analytical`` using conda or pip as follows:
+
+ .. code-block:: bash
+
+ # conda: conda-forge channel strongly recommended
+ conda install -c conda-forge django-analytical
+
+ # pip
+ pip install django-analytical
================================================== ================================================================================
Setting Description
@@ -278,14 +368,26 @@ EMAIL_FROM the email alias setting (e.g.
LOCKOUT_CONFIG
++++++++++++++
-the Django Axes configuration settings for enabling lockout capabilities on Tethys Portal (see: :ref:`advanced_config_lockout`). The following is a list of the Django Axes settings that are configured for the default lockout capabilities in Tethys Portal. For a full list of Django Axes settings, see: `Django Axes Configuration Documentation `_.
+The Django Axes configuration settings for enabling lockout capabilities on Tethys Portal (see: :ref:`advanced_config_lockout`). The following is a list of the Django Axes settings that are configured for the default lockout capabilities in Tethys Portal. For a full list of Django Axes settings, see: `Django Axes Configuration Documentation `_.
+
+.. important::
+
+ These settings require the ``django-axes`` library to be installed. Starting with Tethys 5.0 or if you are using ``micro-tethys-platform``, you will need to install ``django-axes`` using conda or pip as follows:
+
+ .. code-block:: bash
+
+ # conda: conda-forge channel strongly recommended
+ conda install -c conda-forge django-axes
+
+ # pip
+ pip install django-axes
================================================== ================================================================================
Setting Description
================================================== ================================================================================
AXES_FAILURE_LIMIT Number of failed login attempts to allow before locking. Default ``3``.
AXES_COOLOFF_TIME Time to elapse before locked user is allowed to attempt logging in again. In the :file:`portal_config.yml` this setting accepts only integers or `ISO 8601 time duration formatted strings `_ (e.g.: ``"PT30M"``). Default is 30 minutes.
-AXES_ONLY_USER_FAILURES Only lock based on username and do not lock based on IP when True. Defaults to ``True``.
+AXES_LOCKOUT_PARAMETERS A list of parameters that Axes uses to lock out users. See `Django Axes - Customizing lockout parameters `_ for more details. Defaults to ``['username']``.
AXES_ENABLE_ADMIN Enable the Django Axes admin interface. Defaults to ``True``.
AXES_VERBOSE More logging for Axes when True. Defaults to ``True``.
AXES_RESET_ON_SUCCESS Successful login (after the cooloff time has passed) will reset the number of failed logins when True. Defaults to ``True``.
@@ -293,6 +395,61 @@ AXES_LOCKOUT_TEMPLATE Template to render when user
AXES_LOGGER The logger for Django Axes to use. Defaults to ``'tethys.watch_login'``.
================================================== ================================================================================
+CORS_CONFIG
++++++++++++
+
+These CORS settings are used to configure Cross-Origin Resource Sharing (CORS) for the Tethys Portal. See: `Django CORS Headers `_ for more information for the complete list of availalbe settings.
+
+.. important::
+
+ These settings require the ``django-cors-headers`` library to be installed. Starting with Tethys 5.0 or if you are using ``micro-tethys-platform``, you will need to install ``django-cors-headers`` using conda or pip as follows:
+
+ .. code-block:: bash
+
+ # conda: conda-forge channel strongly recommended
+ conda install -c conda-forge django-cors-headers
+
+ # pip
+ pip install django-cors-headers
+
+================================================== ================================================================================
+Setting Description
+================================================== ================================================================================
+CORS_ALLOWED_ORIGINS A list of origins that are authorized to make cross-site HTTP requests. Defaults to ``[]``.
+CORS_ALLOWED_ORIGIN_REGEXES A list of strings representing regexes that match Origins that are authorized to make cross-site HTTP requests. Defaults to ``[]``.
+CORS_ALLOW_ALL_ORIGINS If ``True``, all origins will be allowed. Other settings restricting allowed origins will be ignored. Defaults to ``False``.
+CORS_ALLOW_METHODS A list of HTTP verbs that are allowed for cross-site requests. Defaults to ``("DELETE", "GET", "OPTIONS", "PATCH", "POST", "PUT")``.
+CORS_ALLOW_HEADERS The list of non-standard HTTP headers that you permit in requests from the browser. Sets the Access-Control-Allow-Headers header in responses to preflight requests. Defaults to ``("accept", "authorization", "content-type", "user-agent", "x-csrftoken", "x-requested-with")``.
+================================================== ================================================================================
+
+Gravatar Settings
++++++++++++++++++
+
+The Gravatar settings are used to configure the Gravatar service user profile pictures for the Tethys Portal. See: `Django Gravatar 2 `_ for more information.
+
+.. important::
+
+ These settings require the ``django-gravatar2`` library to be installed. Starting with Tethys 5.0 or if you are using ``micro-tethys-platform``, you will need to install ``django-gravatar2`` using conda or pip as follows:
+
+ .. code-block:: bash
+
+ # conda: conda-forge channel strongly recommended
+ conda install -c conda-forge django-gravatar2
+
+ # pip
+ pip install django-gravatar2
+
+================================================== ================================================================================
+Setting Description
+================================================== ================================================================================
+GRAVATAR_URL the Gravatar service endpoint. Defaults to ``"http://www.gravatar.com/"``.
+GRAVATAR_SECURE_URL the secure Gravatar service endpoint. Defaults to ``"https://secure.gravatar.com/"``.
+GRAVATAR_DEFAULT_SIZE the default size in pixels of the Gravatar image. Defaults to ``"80"``.
+GRAVATAR_DEFAULT_IMAGE the default Gravatar image. Defaults to ``"retro"``.
+GRAVATAR_DEFAULT_RATING the default allowable image rating. Defaults to ``"g"``.
+GRAVATAR_DEFAULT_SECURE uses Gravatar secure endpoint when ``True``. Defaults to ``True``.
+================================================== ================================================================================
+
Other Settings
++++++++++++++
diff --git a/docs/tethys_portal/developer_tools.rst b/docs/tethys_portal/developer_tools.rst
deleted file mode 100644
index 305ca6999..000000000
--- a/docs/tethys_portal/developer_tools.rst
+++ /dev/null
@@ -1,13 +0,0 @@
-***************
-Developer Tools
-***************
-
-**Last Updated:** August 4, 2015
-
-Tethys provides a Developer Tools page that is accessible when you run Tethys in developer mode. Developer Tools contain documentation, code examples, and live demos of the features of various features of Tethys. Use it to learn how to add a map or a plot to your web app using Gizmos or browse the available geoprocessing capabilities and formulate geoprocessing requests interactively.
-
-.. figure:: ../images/features/developer_tools.png
- :width: 500px
-
-
-**Figure 4.** Use the Developer Tools page to assist you in development.
\ No newline at end of file
diff --git a/docs/tethys_portal/tethys_users.rst b/docs/tethys_portal/tethys_users.rst
index 8e0175df1..40fe495cf 100644
--- a/docs/tethys_portal/tethys_users.rst
+++ b/docs/tethys_portal/tethys_users.rst
@@ -4,7 +4,7 @@
Tethys Users
************
-**Last Updated:** April 2019
+**Last Updated:** September 2023
User Settings
=============
@@ -15,6 +15,18 @@ The User Settings page can be accessed through the drop-down menu located at the
A non-editable view of the user's information can be accessed by clicking the user avatar icon to the left of the drop-down menu (see Figure 1).
+.. note::
+
+ This icon next to the users name come from `Gravatar `_. This feature requires the ``django-gravatar2`` library to be installed. Starting with Tethys 5.0 or if you are using ``micro-tethys-platform``, you will need to install ``django-gravatar2`` using conda or pip as follows:
+
+ .. code-block:: bash
+
+ # conda: conda-forge channel strongly recommended
+ conda install -c conda-forge django-gravatar2
+
+ # pip
+ pip install django-gravatar2
+
.. figure:: ../images/tethys_portal/tethys_portal_user_profile.png
:width: 675px
@@ -39,4 +51,75 @@ Within a user's settings page there is a ``Workspace`` section that provides a s
.. tip::
- See :ref:`tethys_quotas_workspace_manage` for information on how to pre/post process the user workspace when it is cleared.
\ No newline at end of file
+ See :ref:`tethys_quotas_workspace_manage` for information on how to pre/post process the user workspace when it is cleared.
+
+Manage User OAuth2 Application Registrations
+============================================
+
+.. important::
+
+ This feature requires the ``django-oauth-toolkit`` library to be installed. Starting with Tethys 5.0 or if you are using ``micro-tethys-platform``, you will need to install ``django-oauth-toolkit`` using conda or pip as follows:
+
+ .. code-block:: bash
+
+ # conda: conda-forge channel strongly recommended
+ conda install -c conda-forge django-oauth-toolkit
+
+ # pip
+ pip install django-oauth-toolkit
+
+This section provides a link to the OAuth2 application management page for the user. This allows a user to register an external application that will use Tethys Portal as the OAuth2 provider. This enables users of the external application to authenticate using Tethys.
+
+Customization
+=============
+
+The Tethys User Profile and Settings pages can be customized by overriding the template used to render them (see the ``Custom Templates`` section in :ref:`tethys_configuration`).
+
+When providing a custom template you may just want to extend the default template and override specific blocks. For example:
+
+.. code-block:: html+django
+
+ {% extends "tethys_portal/user/profile.html" %}
+
+ {% block api_key_override %}
+ {% endblock %}
+
+ {% block custom_sections %}
+
+
+
Custom Section
+
+
+
+
{{ custom_user_attribute }}
+
+
+
+
+ {% endblock %}
+
+The following blocks are defined in the ``profile.html`` file:
+
+- ``title``
+- ``back_button``
+- ``secondary_content``
+ - ``profile_sections``
+ - ``name_override``
+ - ``name_parameters``
+ - ``email_override``
+ - ``email_parameters``
+ - ``credentials_override``
+ - ``credential_parameters``
+ - ``sso_override``
+ - ``social_parameters``
+ - ``api_key_override``
+ - ``account_override``
+ - ``account_parameters``
+ - ``workspace_override``
+ - ``storage_parameters``
+ - ``oauth2_provider_override``
+ - ``custom_sections``
+
+.. note::
+
+ The ``settings.html`` file is what is shown when the user selects the ``Edit`` button on the user profile page. It just extends the ``profile.html`` file and overrides the ``*_parameters`` blocks.
diff --git a/docs/tethys_sdk/gizmos/bokeh_view.rst b/docs/tethys_sdk/gizmos/bokeh_view.rst
index 9105d8a3a..4b1ab59c8 100644
--- a/docs/tethys_sdk/gizmos/bokeh_view.rst
+++ b/docs/tethys_sdk/gizmos/bokeh_view.rst
@@ -2,7 +2,24 @@
Bokeh View
**********
-**Last Updated:** November 11, 2016
+**Last Updated:** August 2023
+
+.. important::
+
+ This gizmo requires the ``bokeh`` library to be installed. Starting with Tethys 5.0 or if you are using ``micro-tethys-platform``, you will need to install ``bokeh`` using conda or pip as follows:
+
+ .. code-block:: bash
+
+ # conda: conda-forge channel strongly recommended
+ conda install -c conda-forge "bokeh<3"
+
+ # pip
+ pip install "bokeh<3"
+
+ **Don't Forget**: If you end up using this gizmo in your app, add ``bokeh`` as a requirement to your :file:`install.yml`.
+
+Python
+------
.. autoclass:: tethys_sdk.gizmos.BokehView
@@ -21,21 +38,25 @@ to do so with Bokeh.
in the ``import_gizmos`` block.
For example:
- ::
+
+ .. code-block:: html+django
{% block import_gizmos %}
{% import_gizmo_dependency bokeh_view %}
{% endblock %}
-Four elements are required:
+Three elements are required:
1) A controller for the AJAX call with a BokehView gizmo.
-::
+
+
+.. code-block:: python
from tethys_sdk.gizmos import BokehView
+ from tethys_sdk.routing import controller
from bokeh.plotting import figure
- @login_required()
+ @controller(name="bokeh_ajax", url="app-name/bokeh")
def bokeh_ajax(request):
"""
Controller for the bokeh ajax request.
@@ -49,23 +70,16 @@ Four elements are required:
return render(request, 'app_name/bokeh_ajax.html', context)
2) A template for with the tethys gizmo (e.g. bokeh_ajax.html)
-::
+
+.. code-block:: html+django
{% load tethys_gizmos %}
{% gizmo bokeh_view_input %}
-3) A url map to the controller in app.py
-::
-
- ...
- UrlMap(name='bokeh_ajax',
- url='app_name/bokeh',
- controller='app_name.controllers.bokeh_ajax'),
- ...
+3) The AJAX call in the javascript
-4) The AJAX call in the javascript
-::
+.. code-block:: javascript
$(function() { //wait for page to load
diff --git a/docs/tethys_sdk/gizmos/cesium_map_view.rst b/docs/tethys_sdk/gizmos/cesium_map_view.rst
index 0d8939365..8488eba07 100644
--- a/docs/tethys_sdk/gizmos/cesium_map_view.rst
+++ b/docs/tethys_sdk/gizmos/cesium_map_view.rst
@@ -48,12 +48,15 @@ This method is intended for initializing a map generated from an AJAX request.
{% import_gizmo_dependency cesium_map_view %}
{% endblock %}
-Four elements are required:
+Three elements are required:
1) A controller for the AJAX call with a Cesium map view gizmo.
-::
- @login_required()
+.. code-block:: python
+
+ @controller(
+ url="dam-break/map/dam_break_map_ajax",
+ )
def dam_break_map_ajax(request):
"""
Controller for the dam_break_map ajax request.
@@ -66,29 +69,22 @@ Four elements are required:
cesium_map_view = CesiumMapView(...)
- context = { 'cesium_map_view': cesium_map_view }
+ context = { "cesium_map_view": cesium_map_view }
- return render(request, 'dam_break_map_ajax/map_ajax.html', context)
+ return render(request, "dam_break_map_ajax/map_ajax.html", context)
-2) A url map to the controller in app.py
-::
+2) A template for with the tethys gizmo (e.g. map_ajax.html)
- ...
- UrlMap(name='dam_break_map_ajax',
- url='dam-break/map/dam_break_map_ajax',
- controller='dam_break.controllers.dam_break_map_ajax'),
- ...
-
-3) A template for with the tethys gizmo (e.g. map_ajax.html)
-::
+.. code-block:: html+django
{% load tethys_gizmos %}
{% gizmo cesium_map_view %}
-4) The AJAX call in the javascript
-::
+3) The AJAX call in the javascript
+
+.. code-block:: javascript
$(function() { //wait for page to load
diff --git a/docs/tethys_sdk/gizmos/datatable_view.rst b/docs/tethys_sdk/gizmos/datatable_view.rst
index 8677de431..a3e75f7c0 100644
--- a/docs/tethys_sdk/gizmos/datatable_view.rst
+++ b/docs/tethys_sdk/gizmos/datatable_view.rst
@@ -26,58 +26,51 @@ to do so with the DataTableView gizmo.
{% import_gizmo_dependency datatable_view %}
{% endblock %}
-Four elements are required:
+Three elements are required:
1) A controller for the AJAX call with a DataTableView gizmo.
-::
+
+.. code-block:: python
import json
- @login_required()
+ @controller
def datatable_ajax(request):
"""
Controller for the datatable ajax request.
"""
searching = False
- if request.GET.get('searching') is not None:
- searching = json.loads(request.GET.get('searching'))
+ if request.GET.get("searching") is not None:
+ searching = json.loads(request.GET.get("searching"))
if searching != True and searching != False:
searching = False
- datatable_default = DataTableView(column_names=('Name', 'Age', 'Job'),
- rows=[('Bill', 30, 'contractor'),
- ('Fred', 18, 'programmer'),
- ('Bob', 26, 'boss')],
+ datatable_default = DataTableView(column_names=("Name", "Age", "Job"),
+ rows=[("Bill", 30, "contractor"),
+ ("Fred", 18, "programmer"),
+ ("Bob", 26, "boss")],
searching=searching,
orderClasses=False,
lengthMenu=[ [10, 25, 50, -1], [10, 25, 50, "All"] ],
)
- context = {'datatable_options': datatable_default}
+ context = {"datatable_options": datatable_default}
- return render(request, 'app_name/datatable_ajax.html', context)
+ return render(request, "app_name/datatable_ajax.html", context)
2) A template for with the tethys gizmo (e.g. datatable_ajax.html)
-::
+
+.. code-block:: html+django
{% load tethys_gizmos %}
{% gizmo datatable_options %}
-3) A url map to the controller in app.py
-::
-
- ...
- UrlMap(name='datatable_ajax',
- url='dam-break/datatable_ajax',
- controller='dam_break.controllers.datatable_ajax'),
- ...
-
+3) The AJAX call in the javascript
-4) The AJAX call in the javascript
-::
+.. code-block:: javascript
$(function() { //wait for page to load
diff --git a/docs/tethys_sdk/gizmos/map_view.rst b/docs/tethys_sdk/gizmos/map_view.rst
index 5d28f1552..2662fdb68 100644
--- a/docs/tethys_sdk/gizmos/map_view.rst
+++ b/docs/tethys_sdk/gizmos/map_view.rst
@@ -247,12 +247,15 @@ This method is intended for initializing a map generated from an AJAX request.
{% import_gizmo_dependency map_view %}
{% endblock %}
-Four elements are required:
+Three elements are required:
1) A controller for the AJAX call with a map view gizmo.
-::
- @login_required()
+.. code-block:: python
+
+ @controller(
+ url="dam-break/map/dam_break_map_ajax",
+ )
def dam_break_map_ajax(request):
"""
Controller for the dam_break_map ajax request.
@@ -265,7 +268,7 @@ Four elements are required:
# Define initial view for Map View
view_options = MVView(
- projection='EPSG:4326',
+ projection="EPSG:4326",
center=[(bbox[0]+bbox[2])/2.0, (bbox[1]+bbox[3])/2.0],
zoom=10,
maxZoom=18,
@@ -274,38 +277,31 @@ Four elements are required:
# Configure the map
map_options = MapView(
- height='500px',
- width='100%',
+ height="500px",
+ width="100%",
layers=map_layer_list,
- controls=['FullScreen'],
+ controls=["FullScreen"],
view=view_options,
- basemap=['OpenStreetMap'],
+ basemap=["OpenStreetMap"],
legend=True,
)
- context = { 'map_options': map_options }
+ context = { "map_options": map_options }
- return render(request, 'dam_break_map_ajax/map_ajax.html', context)
+ return render(request, "dam_break_map_ajax/map_ajax.html", context)
-2) A url map to the controller in app.py
-::
+2) A template for with the tethys gizmo (e.g. map_ajax.html)
- ...
- UrlMap(name='dam_break_map_ajax',
- url='dam-break/map/dam_break_map_ajax',
- controller='dam_break.controllers.dam_break_map_ajax'),
- ...
-
-3) A template for with the tethys gizmo (e.g. map_ajax.html)
-::
+.. code-block:: html+django
{% load tethys_gizmos %}
{% gizmo map_options %}
-4) The AJAX call in the javascript
-::
+3) The AJAX call in the javascript
+
+.. code-block:: javascript
$(function() { //wait for page to load
diff --git a/docs/tethys_sdk/gizmos/plot_view.rst b/docs/tethys_sdk/gizmos/plot_view.rst
index 2ab3f0b05..99be97da0 100644
--- a/docs/tethys_sdk/gizmos/plot_view.rst
+++ b/docs/tethys_sdk/gizmos/plot_view.rst
@@ -75,12 +75,15 @@ This method initializes a chart generated from an AJAX request. An example is de
{% import_gizmo_dependency plot_view %}
{% endblock %}
-Four elements are required:
+Three elements are required:
1) A controller for the AJAX call with a plot view gizmo.
-::
- @login_required()
+.. code-block:: python
+
+ @controller(
+ url="dam-break/map/hydrograph",
+ )
def hydrograph_ajax(request):
"""
Controller for the hydrograph ajax request.
@@ -91,30 +94,22 @@ Four elements are required:
...
)
- context = {'flood_plot': flood_plot}
+ context = {"flood_plot": flood_plot}
- return render(request, 'dam_break/hydrograph_ajax.html', context)
+ return render(request, "dam_break/hydrograph_ajax.html", context)
2) A template for with the tethys gizmo (e.g. hydrograph_ajax.html)
-::
+
+.. code-block:: html+django
{% load tethys_gizmos %}
{% gizmo flood_plot %}
-3) A url map to the controller in app.py
-::
-
- ...
- UrlMap(name='hydrograph_ajax',
- url='dam-break/map/hydrograph',
- controller='dam_break.controllers.hydrograph_ajax'),
- ...
+3) The AJAX call in the javascript
-
-4) The AJAX call in the javascript
-::
+.. code-block:: javascript
$(function() { //wait for page to load
diff --git a/docs/tethys_sdk/gizmos/plotly_view.rst b/docs/tethys_sdk/gizmos/plotly_view.rst
index b48fd52fe..afee113d2 100644
--- a/docs/tethys_sdk/gizmos/plotly_view.rst
+++ b/docs/tethys_sdk/gizmos/plotly_view.rst
@@ -4,7 +4,25 @@
Plotly View
***********
-**Last Updated:** November 11, 2016
+**Last Updated:** August 2023
+
+
+.. important::
+
+ This gizmo requires the ``plotly`` library to be installed. Starting with Tethys 5.0 or if you are using ``micro-tethys-platform``, you will need to install ``plotly`` using conda or pip as follows:
+
+ .. code-block:: bash
+
+ # conda: conda-forge channel strongly recommended
+ conda install -c conda-forge plotly
+
+ # pip
+ pip install plotly
+
+ **Don't Forget**: If you end up using this gizmo in your app, add ``plotly`` as a requirement to your :file:`install.yml`.
+
+Python
+------
.. autoclass:: tethys_sdk.gizmos.PlotlyView
@@ -28,16 +46,19 @@ to do so with PlotlyView.
{% import_gizmo_dependency plotly_view %}
{% endblock %}
-Four elements are required:
+Three elements are required:
1) A controller for the AJAX call with a PlotlyView gizmo.
-::
+
+.. code-block:: python
from datetime import datetime
import plotly.graph_objs as go
from tethys_sdk.gizmos import PlotlyView
+ from tethys_sdk.routing import controller
+
- @login_required()
+ @controller(name='plotly_ajax', url='app-name/plotly')
def plotly_ajax(request):
"""
Controller for the plotly ajax request.
@@ -53,23 +74,16 @@ Four elements are required:
return render(request, 'app_name/plotly_ajax.html', context)
2) A template for with the tethys gizmo (e.g. plotly_ajax.html)
-::
+
+.. code-block:: html+django
{% load tethys_gizmos %}
{% gizmo plotly_view_input %}
-3) A url map to the controller in app.py
-::
-
- ...
- UrlMap(name='plotly_ajax',
- url='app_name/plotly',
- controller='app_name.controllers.plotly_ajax'),
- ...
+3) The AJAX call in the javascript
-4) The AJAX call in the javascript
-::
+.. code-block:: javascript
$(function() { //wait for page to load
diff --git a/docs/tethys_sdk/gizmos/select_input.rst b/docs/tethys_sdk/gizmos/select_input.rst
index b6e8eb51a..b3d9cc4f9 100644
--- a/docs/tethys_sdk/gizmos/select_input.rst
+++ b/docs/tethys_sdk/gizmos/select_input.rst
@@ -20,55 +20,51 @@ to do so with the SelectInput gizmo.
in the ``import_gizmos`` block.
For example:
- ::
+
+ .. code-block:: html+django
{% block import_gizmos %}
{% import_gizmo_dependency select_input %}
{% endblock %}
-Four elements are required:
+Three elements are required:
1) A controller for the AJAX call with a SelectInput gizmo.
-::
+
+.. code-block:: python
from tethys_sdk.gizmos import SelectInput
- @login_required()
+ @controller(
+ url="app_name/select",
+ )
def select_input_ajax(request):
"""
Controller for the bokeh ajax request.
"""
- select_input2 = SelectInput(display_text='Select2',
- name='select2',
+ select_input2 = SelectInput(display_text="Select2",
+ name="select2",
multiple=False,
- options=[('One', '1'), ('Two', '2'), ('Three', '3')],
- initial=['Three'])
+ options=[("One", "1"), ("Two", "2"), ("Three", "3")],
+ initial=["Three"])
- context = {'select_input2': select_input2}
+ context = {"select_input2": select_input2}
- return render(request, 'app_name/select_input_ajax.html', context)
+ return render(request, "app_name/select_input_ajax.html", context)
2) A template for with the tethys gizmo (e.g. select_input_ajax.html)
-::
+
+.. code-block:: html+django
{% load tethys_gizmos %}
{% gizmo select_input2 %}
-3) A url map to the controller in app.py
-::
-
- ...
- UrlMap(name='select_input_ajax',
- url='app_name/select',
- controller='app_name.controllers.select_input_ajax'),
- ...
-
-4) The AJAX call in the javascript
+3) The AJAX call in the javascript
.. note:: You only need to call the init function if you are using select2.
-::
+.. code-block:: javascript
$(function() { //wait for page to load
diff --git a/docs/tethys_sdk/gizmos/toggle_switch.rst b/docs/tethys_sdk/gizmos/toggle_switch.rst
index cb5c3338c..b624650a7 100644
--- a/docs/tethys_sdk/gizmos/toggle_switch.rst
+++ b/docs/tethys_sdk/gizmos/toggle_switch.rst
@@ -26,46 +26,38 @@ to do so with the ToggleSwitch gizmo.
{% import_gizmo_dependency toggle_switch %}
{% endblock %}
-Four elements are required:
+Three elements are required:
1) A controller for the AJAX call with a ToggleSwitch gizmo.
-::
+
+.. code-block:: python
import json
- @login_required()
+ @controller
def toggle_ajax(request):
"""
Controller for the datatable ajax request.
"""
- toggle_switch = ToggleSwitch(display_text='Defualt Toggle',
- name='toggle1')
+ toggle_switch = ToggleSwitch(display_text="Defualt Toggle",
+ name="toggle1")
- context = {'toggle_switch': toggle_switch}
+ context = {"toggle_switch": toggle_switch}
- return render(request, 'app_name/toggle_ajax.html', context)
+ return render(request, "app_name/toggle_ajax.html", context)
2) A template for with the tethys gizmo (e.g. toggle_ajax.html)
-::
+
+.. code-block:: html+django
{% load tethys_gizmos %}
{% gizmo toggle_switch %}
-3) A url map to the controller in app.py
-::
-
- ...
- UrlMap(name='toggle_ajax',
- url='app-name/toggle_ajax',
- controller='app_name.controllers.toggle_ajax'),
- ...
-
-
+3) The AJAX call in the javascript
-4) The AJAX call in the javascript
-::
+.. code-block:: javascript
$(function() { //wait for page to load
diff --git a/docs/tethys_sdk/jobs/condor_job_type.rst b/docs/tethys_sdk/jobs/condor_job_type.rst
index a95f51fc3..157d91df5 100644
--- a/docs/tethys_sdk/jobs/condor_job_type.rst
+++ b/docs/tethys_sdk/jobs/condor_job_type.rst
@@ -4,6 +4,18 @@ Condor Job Type
**Last Updated:** January 2022
+.. important::
+
+ This feature requires the ``condorpy`` library to be installed. Starting with Tethys 5.0 or if you are using ``micro-tethys-platform``, you will need to install ``condorpy`` using conda or pip as follows:
+
+ .. code-block:: bash
+
+ # conda: conda-forge channel strongly recommended
+ conda install -c conda-forge condorpy
+
+ # pip
+ pip install condorpy
+
The :doc:`condor_job_type` (and :doc:`condor_workflow_type`) are used to create jobs to be run by a pool of cluster resources managed by HTCondor. HTCondor makes it possible for jobs to be offloaded from the main web server to a scalable computing cluster, which in turn enables very large scale jobs to be processed.
diff --git a/docs/tethys_sdk/jobs/condor_workflow_type.rst b/docs/tethys_sdk/jobs/condor_workflow_type.rst
index e950c1d5d..006e319ea 100644
--- a/docs/tethys_sdk/jobs/condor_workflow_type.rst
+++ b/docs/tethys_sdk/jobs/condor_workflow_type.rst
@@ -4,6 +4,18 @@ Condor Workflow Job Type
**Last Updated:** January 2022
+.. important::
+
+ This feature requires the ``condorpy`` library to be installed. Starting with Tethys 5.0 or if you are using ``micro-tethys-platform``, you will need to install ``condorpy`` using conda or pip as follows:
+
+ .. code-block:: bash
+
+ # conda: conda-forge channel strongly recommended
+ conda install -c conda-forge condorpy
+
+ # pip
+ pip install condorpy
+
A Condor Workflow provides a way to run a group of jobs (which can have hierarchical relationships) as a single (Tethys) job. The hierarchical relationships are defined as parent-child relationships. For example, suppose a workflow is defined with three jobs: ``JobA``, ``JobB``, and ``JobC``, which must be run in that order. These jobs would be defined with the following relationships: ``JobA`` is the parent of ``JobB``, and ``JobB`` is the parent of ``JobC``.
.. seealso::
diff --git a/docs/tethys_sdk/jobs/dask_job_type.rst b/docs/tethys_sdk/jobs/dask_job_type.rst
index e0544c299..aac29db87 100644
--- a/docs/tethys_sdk/jobs/dask_job_type.rst
+++ b/docs/tethys_sdk/jobs/dask_job_type.rst
@@ -4,6 +4,18 @@ Dask Job Type
**Last Updated:** January 2022
+.. important::
+
+ This feature requires the ``dask`` and ``tethys_dask_scheduler`` libraries to be installed. Starting with Tethys 5.0 or if you are using ``micro-tethys-platform``, you will need to install these libraries using conda or pip as follows:
+
+ .. code-block:: bash
+
+ # conda: conda-forge channel strongly recommended
+ conda install -c conda-forge dask tethys_dask_scheduler
+
+ # pip
+ pip install dask tethys_dask_scheduler
+
A Dask Job Type wraps Dask functionality in a Tethys Jobs interface. The Tethys Dask Job type supports two different Dask APIs for creating Dask Tasks: ``dask.delayed`` and ``dask.distributed``.
Dask Delayed
diff --git a/docs/tethys_sdk/layouts/map_layout.rst b/docs/tethys_sdk/layouts/map_layout.rst
index a0e09e784..a1a0da9d6 100644
--- a/docs/tethys_sdk/layouts/map_layout.rst
+++ b/docs/tethys_sdk/layouts/map_layout.rst
@@ -862,6 +862,11 @@ build_param_string
.. automethod:: tethys_layouts.views.map_layout.MapLayout.build_param_string
+convert_geojson_to_shapefile
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. automethod:: tethys_layouts.views.map_layout.MapLayout.convert_geojson_to_shapefile
+
JavaScript API Documentation
============================
diff --git a/docs/tethys_sdk/rest_api.rst b/docs/tethys_sdk/rest_api.rst
index 5ced46055..1b11c02a9 100644
--- a/docs/tethys_sdk/rest_api.rst
+++ b/docs/tethys_sdk/rest_api.rst
@@ -4,40 +4,50 @@
REST API
********
-REST API's in Tethys Platform use token authentication
-(see: http://www.django-rest-framework.org/api-guide/authentication/#tokenauthentication).
+.. important::
-You can find the API token for your user on the user management page
-(http://[HOST_Portal]/user/[username]/).
+ This feature requires the ``djangorestframework`` library to be installed. Starting with Tethys 5.0 or if you are using ``micro-tethys-platform``, you will need to install ``djangorestframework`` using conda or pip as follows:
-Example Url Map (app.py)::
+ .. code-block:: bash
- UrlMap(name='api_get_data',
- url='[your_app_name]/api/get_data',
- controller='[your_app_name].api.get_data')
+ # conda: conda-forge channel strongly recommended
+ conda install -c conda-forge djangorestframework
+ # pip
+ pip install djangorestframework
-Example API Controller (api.py)::
+ **Don't Forget**: If you end up using this feature in your app, add ``djangorestframework`` as a requirement to your :file:`install.yml`.
+
+REST API's in Tethys Platform use token authentication (see: http://www.django-rest-framework.org/api-guide/authentication/#tokenauthentication).
+
+You can find the API token for your user on the user management page (http://[HOST_Portal]/user/[username]/).
+
+Example API Controller (api.py):
+
+.. code-block:: python
from django.http import JsonResponse
from rest_framework.authentication import TokenAuthentication
from rest_framework.decorators import api_view, authentication_classes
+ from tethys_sdk.routing import controller
- @api_view(['GET'])
+ @controller(url='api/get-data')
+ @api_view(['GET', 'POST'])
@authentication_classes((TokenAuthentication,))
- def get_data(request):
- '''
- API Controller for getting data
- '''
- name = request.GET.get('name')
- data = {"name": name}
- return JsonResponse(data)
+ def get_time_series(request):
+ """
+ Controller for the get-time-series REST endpoint.
+ """
+ name = request.GET.get('name', None)
+ response_data = {'name': name}
+ return JsonResponse(response_data)
+Example Accessing Data:
-Example Accessing Data::
+.. code-block:: python
>>> import requests
- >>> res = requests.get('http://[HOST_Portal]/apps/[your_app_name]/api/get_data?name=oscar',
+ >>> res = requests.get('http://[HOST_Portal]/apps/[your_app_name]/api/get-data?name=oscar',
headers={'Authorization': 'Token asdfqwer1234'})
- >>> da.text
- '{"name": "oscar"}'
+ >>> da.text
+ '{"name": "oscar"}'
diff --git a/docs/tethys_sdk/routing.rst b/docs/tethys_sdk/routing.rst
index deed522f4..09560170b 100644
--- a/docs/tethys_sdk/routing.rst
+++ b/docs/tethys_sdk/routing.rst
@@ -1,4 +1,4 @@
-.. _url_maps_api:
+.. _routing_api:
***********
Routing API
@@ -126,9 +126,11 @@ A ``Bokeh Document`` comes with a ``Bokeh Request``. This request contains most
.. important::
- To use the ``handler`` decorator you will need the ``bokeh_django`` package which is not installed by default. It can be installed with::
+ To use the ``handler`` decorator you will need the ``bokeh`` and ``bokeh-django`` packages which may not be installed by default. They can be installed with:
- conda install -c conda-forge -c erdc/label/dev bokeh-django openssl=1.1.1q
+ .. code-block:: bash
+
+ conda install -c conda-forge -c erdc/label/dev bokeh bokeh-django
.. tip::
For more information regarding Bokeh Server and available models visit the `Bokeh Server Documentation `_ and the `Bokeh model widgets reference guide `_.
diff --git a/docs/tethys_sdk/templating.rst b/docs/tethys_sdk/templating.rst
index 5cebc7823..3d754ceab 100644
--- a/docs/tethys_sdk/templating.rst
+++ b/docs/tethys_sdk/templating.rst
@@ -91,6 +91,17 @@ Examples:
See the `Django Tag Reference `_ for a complete list of tags that Django provides.
+Tethys Tags
++++++++++++
+
+In addition to Django's library of template tags, Tethys also defines a few additional template tags that can be used in your templates.
+
+.. automodule:: tethys_apps.templatetags.humanize
+ :members: human_duration
+
+.. automodule:: tethys_apps.templatetags.app_theme
+ :members: lighten
+
Template Inheritance
--------------------
diff --git a/docs/tethys_sdk/testing.rst b/docs/tethys_sdk/testing.rst
index b29319b7e..8073e7ea7 100644
--- a/docs/tethys_sdk/testing.rst
+++ b/docs/tethys_sdk/testing.rst
@@ -49,6 +49,18 @@ https://docs.python.org/2.7/library/unittest.html#module-unittest
Testing Controllers that Use OAuth2 Authentication
++++++++++++++++++++++++++++++++++++++++++++++++++
+.. important::
+
+ This feature requires the ``social-auth-app-django`` library to be installed. Starting with Tethys 5.0 or if you are using ``micro-tethys-platform``, you will need to install ``social-auth-app-django`` using conda or pip as follows:
+
+ .. code-block:: bash
+
+ # conda: conda-forge channel strongly recommended
+ conda install -c conda-forge social-auth-app-django
+
+ # pip
+ pip install social-auth-app-django
+
Using the ``force_login`` method above works great for testing controllers where login is required. However, additional steps are required to test controllers that must be authenticated with a specific OAuth2 provider (i.e. specify the ``ensure_oauth_provider`` argument to the ``controller`` decorator). For example, if you have a controller like this:
.. code-block:: python
diff --git a/docs/tethys_sdk/tethys_services/dataset_services.rst b/docs/tethys_sdk/tethys_services/dataset_services.rst
index dda23082a..854e23eaa 100644
--- a/docs/tethys_sdk/tethys_services/dataset_services.rst
+++ b/docs/tethys_sdk/tethys_services/dataset_services.rst
@@ -4,6 +4,18 @@ Dataset Services API
**Last Updated**: May 2017
+.. important::
+
+ This feature requires the ``tethys_dataset_services`` library to be installed. Starting with Tethys 5.0 or if you are using ``micro-tethys-platform``, you will need to install ```tethys_dataset_services`` using conda or pip as follows:
+
+ .. code-block:: bash
+
+ # conda: conda-forge channel strongly recommended
+ conda install -c conda-forge tethys_dataset_services
+
+ # pip
+ pip install tethys_dataset_services
+
:term:`Dataset services` are web services external to Tethys Platform that can be used to store and publish file-based :term:`datasets` (e.g.: text files, Excel files, zip archives, other model files). Tethys app developers can use the Dataset Services API to access :term:`datasets` for use in their apps and publish any resulting :term:`datasets` their apps may produce. Supported options include `CKAN `_ and `HydroShare `_.
Key Concepts
@@ -119,13 +131,17 @@ After dataset services have been properly configured, you can use the services t
1. Get a Dataset Service Engine
-------------------------------
-Call the ``get_dataset_service()`` method of the app class to get a ``DatasetEngine``::
+Call the ``get_dataset_service()`` method of the app class to get a ``DatasetEngine``:
+
+.. code-block:: python
from my_first_app.app import MyFirstApp as app
ckan_engine = app.get_dataset_service('primary_ckan', as_engine=True)
-You can also create a ``DatasetEngine`` object directly. This can be useful if you want to vary the credentials for dataset access frequently (e.g.: using user specific credentials)::
+You can also create a ``DatasetEngine`` object directly. This can be useful if you want to vary the credentials for dataset access frequently (e.g.: using user specific credentials):
+
+.. code-block:: python
from tethys_dataset_services.engines import CkanDatasetEngine
@@ -139,7 +155,9 @@ You can also create a ``DatasetEngine`` object directly. This can be useful if y
2. Use the Dataset Service Engine
---------------------------------
-After you have a ``DatasetEngine``, simply call the desired method on it. All ``DatasetEngine`` methods return a dictionary with an item named ``'success'`` that contains a boolean. If the operation was successful, the value of ``'success'`` will be ``True``, otherwise it will be ``False``. If the value of ``'success'`` is ``True``, the dictionary will also contain an item named ``'result'`` that will contain the results. If it is ``False``, the dictionary will contain an item named ``'error'`` that will contain information about the error that occurred. This can be used for debugging purposes as illustrated in the following example::
+After you have a ``DatasetEngine``, simply call the desired method on it. All ``DatasetEngine`` methods return a dictionary with an item named ``'success'`` that contains a boolean. If the operation was successful, the value of ``'success'`` will be ``True``, otherwise it will be ``False``. If the value of ``'success'`` is ``True``, the dictionary will also contain an item named ``'result'`` that will contain the results. If it is ``False``, the dictionary will contain an item named ``'error'`` that will contain information about the error that occurred. This can be used for debugging purposes as illustrated in the following example:
+
+.. code-block:: python
from my_first_app.app import MyFirstApp as app
@@ -162,7 +180,7 @@ Use the dataset service engines references above for descriptions of the methods
The HydroShare dataset engine uses OAuth 2.0 to authenticate and authorize interactions with the HydroShare via the REST API. This requires passing the ``request`` object as one of the arguments in ``get_dataset_engine()`` method call. Also, to ensure the user is connected to HydroShare, app developers must use the ``ensure_oauth2()`` decorator on any controllers that use the HydroShare dataset engine. For example:
- ::
+ .. code-block:: python
from tethys_sdk.services import get_dataset_engine, ensure_oauth2
from .app import MyFirstApp as app
diff --git a/docs/tethys_sdk/tethys_services/persistent_store.rst b/docs/tethys_sdk/tethys_services/persistent_store.rst
index b196fc55e..9f254956c 100644
--- a/docs/tethys_sdk/tethys_services/persistent_store.rst
+++ b/docs/tethys_sdk/tethys_services/persistent_store.rst
@@ -4,6 +4,18 @@ Persistent Stores API
**Last Updated:** May 2017
+.. important::
+
+ This feature requires the ``psycopg2`` and ``sqlalchmey`` libraries to be installed. Starting with Tethys 5.0 or if you are using ``micro-tethys-platform``, you will need to install these libraries using conda or pip as follows:
+
+ .. code-block:: bash
+
+ # conda: conda-forge channel strongly recommended
+ conda install -c conda-forge psycopg2 "sqlalchemy<2"
+
+ # pip
+ pip install psycopg2 "sqlalchemy<2"
+
The Persistent Store API streamlines the use of SQL databases in Tethys apps. Using this API, you can provision SQL databases for your app. The databases that will be created are `PostgreSQL `_ databases. Currently, no other databases are supported.
The process of creating a new persistent database can be summarized in the following steps:
diff --git a/docs/tethys_sdk/tethys_services/spatial_dataset_service/geoserver_reference.rst b/docs/tethys_sdk/tethys_services/spatial_dataset_service/geoserver_reference.rst
index d18d6b335..7648148df 100644
--- a/docs/tethys_sdk/tethys_services/spatial_dataset_service/geoserver_reference.rst
+++ b/docs/tethys_sdk/tethys_services/spatial_dataset_service/geoserver_reference.rst
@@ -114,7 +114,7 @@ These links can be passed to a web mapping client like OpenLayers or Google Maps
When you are learning how to use the spatial dataset engine methods, run the commands with the debug parameter set to true. This will automatically pretty print the result dictionary to the console so that you can inspect its contents:
- ::
+ .. code-block:: python
# Example method with debug option
engine.list_layers(debug=True)
diff --git a/docs/tethys_sdk/tethys_services/spatial_dataset_service/thredds_reference.rst b/docs/tethys_sdk/tethys_services/spatial_dataset_service/thredds_reference.rst
index 2e6d301c6..57d7e6c58 100644
--- a/docs/tethys_sdk/tethys_services/spatial_dataset_service/thredds_reference.rst
+++ b/docs/tethys_sdk/tethys_services/spatial_dataset_service/thredds_reference.rst
@@ -6,6 +6,18 @@ THREDDS Engine (Siphon) Reference
**Last Updated**: December 2019
+.. important::
+
+ This feature requires the ``siphon`` library to be installed. Starting with Tethys 5.0 or if you are using ``micro-tethys-platform``, you will need to install ``siphon`` using conda or pip as follows:
+
+ .. code-block:: bash
+
+ # conda: conda-forge channel strongly recommended
+ conda install -c conda-forge siphon
+
+ # pip
+ pip install siphon
+
This guide introduces `Siphon `_, the which is used as the engine for the THREDDS spatial dataset service. Siphon is a 3rd-party library developed by Unidata for interacting with data on remote services, currently focused on THREDDS services. Siphon does not implement the ``SpatialDatasetEngine`` pattern.
Example Usage
diff --git a/docs/tethys_sdk/tethys_services/spatial_dataset_services.rst b/docs/tethys_sdk/tethys_services/spatial_dataset_services.rst
index 162b596b6..e25c059f4 100644
--- a/docs/tethys_sdk/tethys_services/spatial_dataset_services.rst
+++ b/docs/tethys_sdk/tethys_services/spatial_dataset_services.rst
@@ -7,6 +7,18 @@ Spatial Dataset Services API
**Last Updated:** December 2019
+.. important::
+
+ This feature requires the ``tethys_dataset_services`` library to be installed. Starting with Tethys 5.0 or if you are using ``micro-tethys-platform``, you will need to install ``tethys_dataset_services`` using conda or pip as follows:
+
+ .. code-block:: bash
+
+ # conda: conda-forge channel strongly recommended
+ conda install -c conda-forge tethys_dataset_services
+
+ # pip
+ pip install tethys_dataset_services
+
Spatial dataset services are web services that can be used to store and publish file-based :term:`spatial datasets` (e.g.: Shapefile, GeoTiff, NetCDF). The spatial datasets published using spatial dataset services are made available in a variety of formats, many of which or more web friendly than the native format (e.g.: PNG, JPEG, GeoJSON, OGC Services).
One example of a spatial dataset service is `GeoServer `_, which is capable of storing and serving vector and raster datasets in several popular formats including Shapefiles, GeoTiff, ArcGrid and others. GeoServer serves the data in a variety of formats via the `Open Geospatial Consortium (OGC) `_ standards including `Web Feature Service (WFS) `_, `Web Map Service (WMS) `_, and `Web Coverage Service (WCS) `_.
@@ -123,13 +135,17 @@ After spatial dataset services have been properly configured, you can use the se
1. Get an Engine for the Spatial Dataset Service
------------------------------------------------
-Call the ``get_spatial_dataset_service()`` method of the app class to get the engine for the Spatial Dataset Service::
+Call the ``get_spatial_dataset_service()`` method of the app class to get the engine for the Spatial Dataset Service:
+
+.. code-block:: python
from my_first_app.app import MyFirstApp as app
geoserver_engine = app.get_spatial_dataset_service('primary_geoserver', as_engine=True)
-You can also create a ``SpatialDatasetEngine`` object directly. This can be useful if you want to vary the credentials for dataset access frequently (e.g.: using user specific credentials)::
+You can also create a ``SpatialDatasetEngine`` object directly. This can be useful if you want to vary the credentials for dataset access frequently (e.g.: using user specific credentials):
+
+.. code-block:: python
from tethys_dataset_services.engines import GeoServerSpatialDatasetEngine
diff --git a/docs/tethys_sdk/tethys_services/spatial_persistent_store.rst b/docs/tethys_sdk/tethys_services/spatial_persistent_store.rst
index 028682102..51cfbaad9 100644
--- a/docs/tethys_sdk/tethys_services/spatial_persistent_store.rst
+++ b/docs/tethys_sdk/tethys_services/spatial_persistent_store.rst
@@ -4,6 +4,18 @@ Spatial Persistent Stores API
**Last Updated:** May 2017
+.. important::
+
+ This feature requires the ``psycopg2``, ``sqlalchmey``, and ``geoalchemy2`` libraries to be installed. Starting with Tethys 5.0 or if you are using ```micro-tethys-platform``, you will need to install these libraries using conda or pip as follows:
+
+ .. code-block:: bash
+
+ # conda: conda-forge channel strongly recommended
+ conda install -c conda-forge psycopg2 "sqlalchemy<2" geoalchemy2
+
+ # pip
+ pip install psycopg2 "sqlalchemy<2" geoalchemy2
+
Persistent store databases can support spatial data types. The spatial capabilities are provided by the `PostGIS `_ extension for the `PostgreSQL `_ database. PostGIS extends the column types of PostgreSQL databases by adding ``geometry``, ``geography``, and ``raster`` types. PostGIS also provides hundreds of database functions that can be used to perform spatial operations on data stored in spatial columns. For more information on PostGIS, see ``_.
The following article details the the spatial capabilities of persistent stores in Tethys Platform. This article builds on the concepts and ideas introduced in the :doc:`./persistent_store` documentation. Please review it before continuing.
diff --git a/docs/tethys_sdk/tethys_services/web_processing_services.rst b/docs/tethys_sdk/tethys_services/web_processing_services.rst
index 05eb481a7..88561947a 100644
--- a/docs/tethys_sdk/tethys_services/web_processing_services.rst
+++ b/docs/tethys_sdk/tethys_services/web_processing_services.rst
@@ -9,7 +9,7 @@ Web Processing Services (WPS) are web services that can be used perform geoproce
Web Processing Service Settings
===============================
-Using web processing services in your app is accomplised by adding the ``web_processing_service_settings()`` method to your :term:`app class`, which is located in your :term:`app configuration file` (:file:`app.py`). This method should return a list or tuple of ``WebProcessingServiceSetting`` objects. For example:
+Using web processing services in your app is accomplished by adding the ``web_processing_service_settings()`` method to your :term:`app class`, which is located in your :term:`app configuration file` (:file:`app.py`). This method should return a list or tuple of ``WebProcessingServiceSetting`` objects. For example:
::
@@ -87,6 +87,18 @@ The ``WebProcessingServiceSetting`` can be thought of as a socket for a connecti
Working with WPS Services in Apps
=================================
+.. important::
+
+ This feature requires the ``owslib`` library to be installed. Starting with Tethys 5.0 or if you are using ``micro-tethys-platform``, you will need to install ``owslib`` using conda or pip as follows:
+
+ .. code-block:: bash
+
+ # conda: conda-forge channel strongly recommended
+ conda install -c conda-forge owslib
+
+ # pip
+ pip install owslib
+
The Web Processing Service API is powered by `OWSLib `_, a Python client that can be used to interact with OGC web services. For detailed explanations the WPS client provided by OWSLib, refer to the `OWSLib WPS Documentation `_. This article only provides a basic introduction to working with the OWSLib WPS client.
Get a WPS Engine
@@ -130,34 +142,3 @@ After you have retrieved a valid ``owslib.wps.WebProcessingService`` engine obje
It is also possible to perform requests using data that are hosted on WFS servers, such as the GeoServer that is provided as part of the Tethys Platform software suite. See the `OWSLib WPS Documentation `_ for more details on how this is to be done.
-
-Web Processing Service Developer Tool
-=====================================
-
-Tethys Platform provides a developer tool that can be used to browse the sitewide WPS services and the processes that they provide. This tool is useful for formulating new process requests. To use the tool:
-
-1. Browse to the Developer Tools page of your Tethys Platform by selecting the "Developer" link from the menu at the top of the page.
-
-2. Select the tool titled "Web Processing Services".
-
- .. figure:: ../../images/wps_tool/developer_tools_wps.png
- :width: 600px
- :align: center
-
-3. Select a WPS service from the list of services that are linked with your Tethys Instance. If no WPS services are linked to your Tethys instance, follow the steps in Sitewide Configuration, above, to setup a WPS service.
-
- .. figure:: ../../images/wps_tool/wps_tool_services.png
- :width: 600px
- :align: center
-
-4. Select the process you wish to view.
-
- .. figure:: ../../images/wps_tool/wps_tool_processes.png
- :width: 600px
- :align: center
-
-A description of the process and the inputs and outputs will be displayed.
-
- .. figure:: ../../images/wps_tool/wps_tool_buffer.png
- :width: 600px
- :align: center
\ No newline at end of file
diff --git a/docs/tutorials/bokeh.rst b/docs/tutorials/bokeh.rst
index 67775948e..2ab56a74d 100644
--- a/docs/tutorials/bokeh.rst
+++ b/docs/tutorials/bokeh.rst
@@ -12,11 +12,11 @@ This tutorial introduces ``Bokeh Server`` integration concepts for Tethys develo
* Handler functions using Bokeh Widgets
* Handler functions using Param and Panel
-Create a and install a new Tethys app named bokeh_tutorial.
+Create and install a new Tethys app named bokeh_tutorial.
::
- t
+ conda activate tethys
tethys scaffold bokeh_tutorial
cd tethysapp-bokeh_tutorial
tethys install -d
@@ -24,7 +24,42 @@ Create a and install a new Tethys app named bokeh_tutorial.
1. Bokeh Server
===============
-``Bokeh`` is an interactive visualization library for Python. ``Bokeh Server`` is a component of the ``Bokeh`` architecture. It provides a way to sync model objects in Python on the backend to JavaScript model objects on the client. This is done by levering the ``Websocket`` protocol. With the addition of ``Django Channels`` to Tethys, this ability to sync backend python objects and frontend plots has also been integrated without the need of other components such as a ``Tornado`` server (see `Tethys Bokeh Integration documentation <../../tethys_sdk/url_maps.html#bokeh-integration>`_). This integration facilitates the linking of objects and ``Bokeh`` widgets as well as the creation of the necessary ``websocket`` and ``http`` ``consumers``.
+``Bokeh`` is an interactive visualization library for Python. ``Bokeh Server`` is a component of the ``Bokeh`` architecture. It provides a way to sync model objects in Python on the backend to JavaScript model objects on the client. This is done by levering the ``Websocket`` protocol. With the addition of ``Django Channels`` to Tethys, this ability to sync backend python objects and frontend plots has also been integrated without the need of other components such as a ``Tornado`` server (see the Tethys Bokeh Integration documentation :ref:`bokeh_integration`). This integration facilitates the linking of objects and ``Bokeh`` widgets as well as the creation of the necessary ``websocket`` and ``http`` ``consumers``.
+
+To leverage the Bokeh integration with Tethys you will need the ``bokeh`` and ``bokeh-django`` libraries.
+
+1. Install the ``bokeh`` and ``bokeh-django`` libraries by running one of the following commands with your Tethys environment activated:
+
+.. code-block:: bash
+
+ # conda: conda-forge channel strongly recommended for bokeh (the erdc/label/dev channel is currently needed for bokeh-django)
+ conda install -c conda-forge -c erdc/label/dev bokeh bokeh-django
+
+ # pip
+ pip install bokeh bokeh-django
+
+2. Add the new dependencies to your :file:`install.yml` as follows so that the app will work when installed in a new environment:
+
+.. code-block:: yaml
+
+ # This file should be committed to your app code.
+ version: 1.0
+ # This should match the app - package name in your setup.py
+ name: bokeh_tutorial
+
+ requirements:
+ # Putting in a skip true param will skip the entire section. Ignoring the option will assume it be set to False
+ skip: false
+ conda:
+ channels:
+ - conda-forge
+ packages:
+ - bokeh
+ - bokeh_django
+
+ pip:
+
+ post:
The logic for creating a Bokeh widget along with other related functionality is provided in a ``handler function``. This handler will be associated to a specific ``controller function`` where the resulting Bokeh widget will be displayed in a later step.
@@ -33,7 +68,7 @@ The logic for creating a Bokeh widget along with other related functionality is
Let's use Bokeh's sea temperature sample data to create a time series plot and link it to a slider that will provide the value to perform a rolling-window analysis on the time series. This example is based on a similar example in Bokeh's main documentation.
-1. Create a ``handler function`` by adding the following imports and logic to ``controller.py``.
+1. Create a ``handler function`` by adding the following imports and logic to ``handlers.py``.
.. code-block:: Python
@@ -41,9 +76,13 @@ Let's use Bokeh's sea temperature sample data to create a time series plot and l
from bokeh.models import ColumnDataSource
from bokeh.sampledata.sea_surface_temperature import sea_surface_temperature
- ...
+ from tethys_sdk.routing import handler
- def home_handler(document):
+
+ @handler(
+ template="bokeh_tutorial/home.html",
+ )
+ def home(document):
df = sea_surface_temperature.copy()
source = ColumnDataSource(data=df)
@@ -53,65 +92,31 @@ Let's use Bokeh's sea temperature sample data to create a time series plot and l
document.add_root(plot)
-This simple handler contains the logic for a time series plot of the sea surface temperature sample data provided by ``Bokeh``.
-
-2. Clear the default home function in ``controller.py`` and add the following code to it.
-
-.. code-block:: Python
-
- from bokeh.embed import server_document
-
- @login_required()
- def home(request):
- script = server_document(request.build_absolute_uri())
- context = {'script': script}
- return render(request, 'bokeh_tutorial/home.html', context)
-
-The home controller can now load the time series plot from (a) using the Bokeh ``server_document`` function. However, we still need to link the ``handler`` and the ``controller`` in the ``app.py``, and add the script context variable to the template as with any other variable.
-
-3. Modify ``app.py`` by adding a dot-formatted path to the handler function created in (1) to the ``handler`` parameter and providing a ``handler_type`` with a value equal to 'bokeh' as shown in the code below.
-
-.. code-block:: Python
-
- from tethys_sdk.base import TethysAppBase
+This simple handler contains the logic for a time series plot of the sea surface temperature sample data provided by ``Bokeh``. The ``handler`` decorator marks this function as a handler. It auto generates a default ``controller function`` that is linked to the handler. A default template can also be used, but we specified a custom template using the ``template`` argument to the ``handler`` decorator. The ``handler`` decorator also sets up the routing. By default the route name and the URL are derived from the ``handler function`` name (in this case ``home``). For more information about the ``handler`` decorator and additional arguments that can be passed see :ref:`handler-decorator`. Since this default controller is sufficient, we don't need to create a custom controller and can just delete the ``controller.py`` file.
+2. Delete the ``controller.py`` file.
- class BokehTutorial(TethysAppBase):
- """
- Tethys app class for Bokeh Tutorial.
- """
-
- name = 'Bokeh Tutorial'
- index = 'bokeh_tutorial:home'
- icon = 'bokeh_tutorial/images/icon.gif'
- package = 'bokeh_tutorial'
- root_url = 'bokeh-tutorial'
- color = '#2980b9'
- description = ''
- tags = ''
- enable_feedback = False
- feedback_emails = []
-
-4. Clear the default ``home.html`` template and add the following code to it.
+3. Clear the default ``home.html`` template and add the following code to it.
.. code-block:: html+django
{% extends "bokeh_tutorial/base.html" %}
- {% load tethys_gizmos %}
{% block app_content %}
Bokeh Integration Example
{{ script|safe }}
{% endblock %}
-As you can see, the script context variable has been added to the app_content block. If you start tethys and go to the home page of this app you should see something like this:
+As you can see, a ``script`` context variable has been added to the app_content block. The default ``controller function`` defines this script which handles loading the content specified in the ``handler function``. We customized the template by adding in a heading which will render above the content from the ``handler function``.
+
+If you start tethys and go to the home page of this app you should see something like this:
.. figure:: ../images/tutorial/bokeh_integration/bokeh_integration_1.png
:width: 650px
This is a simple Bokeh plot. We will now add the rest of the logic to make it an interactive plot. We will add a ``Slider`` widget. Then, we will create a callback function to modify the time-series plot based on the slider. Finally, we will add both our plot and slider to the document tree using a ``Column`` layout.
-5. Modify the ``handler function`` from ``controller.py`` to look like this.
+5. Modify the ``handler function`` from ``handlers.py`` to look like this.
.. code-block:: python
@@ -156,7 +161,7 @@ The ``Slider`` and ``Plot`` will appear in the order they were added to the ``Co
In this example we will build on top of the ``bokeh_tutorial`` app to demonstrate how to use ``Param`` and ``Panel`` in combination with ``bokeh Server``. This same example can be found in `Panel's documentation `_.
-1. Install the ``param`` library by running the following with your Tethys environment activated:
+1. Install the ``param`` and ``panel`` libraries by running the following with your Tethys environment activated:
.. code-block:: bash
@@ -178,6 +183,8 @@ In this example we will build on top of the ``bokeh_tutorial`` app to demonstrat
channels:
- conda-forge
packages:
+ - bokeh
+ - bokeh_django
- panel
- param
@@ -210,6 +217,8 @@ In this example we will build on top of the ``bokeh_tutorial`` app to demonstrat
return [], []
def view(self):
+ if not self.figure.renderers:
+ self.__init__(name=self.name)
return self.figure
@@ -253,82 +262,45 @@ In this example we will build on top of the ``bokeh_tutorial`` app to demonstrat
def title(self):
return '## %s (radius=%.1f)' % (type(self.shape).__name__, self.shape.radius)
+ @param.depends('shape')
+ def controls(self):
+ return pn.Param(self.shape)
+
def panel(self):
- return pn.Column(self.title, self.view)
+ expand_layout = pn.Column()
+
+ return pn.Column(
+ pn.pane.HTML('
Bokeh Integration Example using Param and Panel
'),
+ pn.Row(
+ pn.Column(
+ pn.panel(self.param, expand_button=False, expand=True, expand_layout=expand_layout),
+ "#### Subobject parameters:",
+ expand_layout),
+ pn.Column(self.title, self.view)
+ ),
+ sizing_mode='stretch_width',
+ )
The added classes depend on ``Bokeh``. The `Circle` and `NGon` classes depend on the `Shape` class, while the `ShapeViewer` allows the user to pick one of the two available shapes.
-4. Add a ``handler function`` that uses the classes created in the previous step by adding the following code to ``controller.py``.
+4. Add a ``handler function`` that uses the classes created in the previous step by adding the following code to ``handlers.py``.
.. code-block:: python
- import panel as pn
from .param_model import ShapeViewer
...
- def shapes_handler(document):
- viewer = ShapeViewer()
- panel = pn.Row(viewer.param, viewer.panel())
- panel.server_doc(document)
-
-5. Add a ``controller function`` to pass the ``Panel`` object to a template and to link it with the ``handler`` created in the previous step.
+ @handler(
+ app_package='bokeh_tutorial',
+ )
+ def shapes(document):
+ viewer = ShapeViewer().panel()
+ viewer.server_doc(document)
-.. code-block:: python
-
- def shapes_with_panel(request):
- script = server_document(request.build_absolute_uri())
- context = {'script': script}
- return render(request, "bokeh_tutorial/shapes.html", context)
-
-6. Create a new ``UrlMap`` in ``app.py`` to link the new ``handler-controller pair`` to an endpoint.
-
-.. code-block:: python
-
- def url_maps(self):
- """
- Add controllers
- """
- UrlMap = url_map_maker(self.root_url)
-
- url_maps = (
- UrlMap(
- name='home',
- url='bokeh-tutorial',
- controller='bokeh_tutorial.controllers.home',
- handler='bokeh_tutorial.controllers.home_handler',
- handler_type='bokeh'
- ),
- UrlMap(
- name='shapes',
- url='bokeh-tutorial/shapes',
- controller='bokeh_tutorial.controllers.shapes_with_panel',
- handler='bokeh_tutorial.controllers.shapes_handler',
- handler_type='bokeh'
- ),
- )
-
- return url_maps
-
-7. Add a new template to match the path rendered in the new ``controller`` from (c) (`bokeh_tutorial/shapes.html`).
-
-.. code-block:: html+django
-
- {% extends "bokeh_tutorial/base.html" %}
- {% load tethys_gizmos %}
-
- {% block header_buttons %}
-
-
-
- {% endblock %}
-
- {% block app_content %}
-
Bokeh Integration Example using Param and Panel
- {{ script|safe }}
- {% endblock %}
+Note that in this case we are not using a custom template, but we add the ``app_package`` argument to the the ``handler`` decorator so that the default template that Tethys uses will inherit from the ``base.html`` template from our app.
-8. To add the new endpoint to the app navigation bar, go to the ``base.html`` template and replace the ``app_navigation`` block content with the code below.
+5. To add the new endpoint to the app navigation bar, go to the ``base.html`` template and replace the ``app_navigation`` block content with the code below.
.. code-block:: html+django
diff --git a/docs/tutorials/dask/new_app_project.rst b/docs/tutorials/dask/new_app_project.rst
index 73781c024..76718e378 100644
--- a/docs/tutorials/dask/new_app_project.rst
+++ b/docs/tutorials/dask/new_app_project.rst
@@ -4,8 +4,8 @@ New Tethys App Project
**Last Updated:** May 2022
-1. Setting up the scaffold
-==========================
+1. Generate Scaffold
+====================
Tethys Platform provides an easy way to create new app projects called a scaffold. The scaffold generates a Tethys app project with the minimum files and the folder structure that is required (see :doc:`../../supplementary/app_project`).
@@ -23,20 +23,73 @@ b. Scaffold a new app named ``dask_tutorial``:
tethys scaffold dask_tutorial
-c. Install the app in development mode:
+2. Add App Dependencies to :file:`install.yml`
+==============================================
+
+App dependencies should be managed using the :file:`install.yml` instead of the :file:`setup.py`. This app will require the ``dask`` and ``tethys_dask_scheduler`` packages. Both packages are available on ``conda-forge``, which is the preferred Conda channel for Tethys. Open :file:`tethysapp-dask_tutorial/install.yml` and add these dependencies to the ``requirements.conda`` section of the file:
+
+.. code-block:: yaml
+
+ # This file should be committed to your app code.
+ version: 1.0
+ # This should match the app - package name in your setup.py
+ name: dask_tutorial
+
+ requirements:
+ # Putting in a skip true param will skip the entire section. Ignoring the option will assume it be set to False
+ skip: false
+ conda:
+ channels:
+ - conda-forge
+ packages:
+ - dask
+ - tethys_dask_scheduler
+
+ pip:
+
+ post:
+
+3. Development Installation
+===========================
+
+Install the app and it's dependencies into your development Tethys Portal. In a terminal, change into the :file:`tethysapp-dask_tutorial` directory and execute the :command:`tethys install -d` command.
+
+.. code-block:: bash
+
+ cd tethysapp-dask_tutorial
+ tethys install -d
+
+5. View Your New App
+====================
+
+1. Start up the development server to view the new app:
+
+.. code-block:: bash
+
+ tethys manage start
+
+.. tip::
+
+ To stop the development server press :kbd:`CTRL-C`.
+
+ If you get errors related to Tethys not being able to connect to the database, start the database by running:
.. code-block:: bash
- cd tethysapp-dask_tutorial
- tethys install -d
+ tethys db start
-d. Start the Tethys development server:
+ You can also stop the Tethys database by running:
.. code-block:: bash
- tethys manage start
+ tethys db stop
+
+2. Browse to ``_ in a web browser and login. The default portal user is:
+
+* **username**: admin
+* **password**: pass
-2. Dask
+6. Dask
=======
Documentation for Dask may be found at ``_
diff --git a/docs/tutorials/google_earth_engine/part_1/new_app_project.rst b/docs/tutorials/google_earth_engine/part_1/new_app_project.rst
index e8dfc87c8..15edef36a 100644
--- a/docs/tutorials/google_earth_engine/part_1/new_app_project.rst
+++ b/docs/tutorials/google_earth_engine/part_1/new_app_project.rst
@@ -56,17 +56,17 @@ App dependencies should be managed using the :file:`install.yml` instead of the
name: earth_engine
requirements:
- # Putting in a skip true param will skip the entire section. Ignoring the option will assume it be set to False
- skip: false
- conda:
- channels:
- - conda-forge
- packages:
- - earthengine-api
- - oauth2client
- pip:
-
- npm:
+ # Putting in a skip true param will skip the entire section. Ignoring the option will assume it be set to False
+ skip: false
+ conda:
+ channels:
+ - conda-forge
+ packages:
+ - earthengine-api
+ - oauth2client
+ pip:
+
+ npm:
post:
diff --git a/docs/tutorials/google_earth_engine/part_2/file_upload.rst b/docs/tutorials/google_earth_engine/part_2/file_upload.rst
index f9ec615b6..9d1f32461 100644
--- a/docs/tutorials/google_earth_engine/part_2/file_upload.rst
+++ b/docs/tutorials/google_earth_engine/part_2/file_upload.rst
@@ -395,12 +395,16 @@ Now that the file is written to disk, use the built-in ``zipfile`` module to ver
In this step you will add the logic to validate that the file contained in the ZIP archive is a shapefile. You will use the ``pyshp`` library to do this, which will introduce a new dependency for the app.
-1. Install ``pyshp`` library into your Tethys conda environment. Run the following command in the terminal with your Tethys environment activated:
+1. Install ``pyshp`` library into your Tethys conda environment using conda or pip. Run the following command in the terminal with your Tethys environment activated:
.. code-block:: bash
+ # conda: conda-forge channel highly recommended
conda install -c conda-forge pyshp
+ # pip
+ pip install pyshp
+
2. Add ``pyshp`` as a new dependency in the ``install.yml``:
.. code-block:: yaml
diff --git a/docs/tutorials/google_earth_engine/part_2/rest_api.rst b/docs/tutorials/google_earth_engine/part_2/rest_api.rst
index 288896242..4658ff874 100644
--- a/docs/tutorials/google_earth_engine/part_2/rest_api.rst
+++ b/docs/tutorials/google_earth_engine/part_2/rest_api.rst
@@ -27,7 +27,52 @@ If you wish to use the previous solution as a starting point:
cd tethysapp-earth_engine
git checkout -b clip-by-asset-solution clip-by-asset-solution-|version|
-1. Reorganize Controller Functions into Separate Files
+1. Install dependencies
+=======================
+
+The REST API capability requires ``djangorestframework`` to be installed. Install it using conda or pip as follows:
+
+.. code-block:: bash
+
+ # conda: conda-forge channel strongly recommended
+ conda install -c conda-forge djangorestframework
+
+ # pip
+ pip install djangorestframework
+
+2. Add dependencies to install.yml
+==================================
+
+Add ``djangorestframework`` to the ``install.yml`` file to ensure it is installed when your app is installed as follows:
+
+.. code-block:: yaml
+
+ # This file should be committed to your app code.
+ version: 1.0
+ # This should be greater or equal to your tethys-platform in your environment
+ tethys_version: ">=4.0.0"
+ # This should match the app - package name in your setup.py
+ name: earth_engine
+
+ requirements:
+ # Putting in a skip true param will skip the entire section. Ignoring the option will assume it be set to False
+ skip: false
+ conda:
+ channels:
+ - conda-forge
+ packages:
+ - earthengine-api
+ - oauth2client
+ - geojson
+ - pyshp
+ - djangorestframework
+ pip:
+
+ npm:
+
+ post:
+
+3. Reorganize Controller Functions into Separate Files
======================================================
The :file:`controllers.py` file is beginning to get quite long. To make the controller code more manageable, in this step you will refactor the controllers into several files.
@@ -132,7 +177,7 @@ The :file:`controllers.py` file is beginning to get quite long. To make the cont
6. Navigate to ``_ and verify that the app functions as it did before the change.
-2. Create New Controller for REST API Endpoint
+4. Create New Controller for REST API Endpoint
==============================================
REST endpoints are similar to normal controllers. The primary difference is that they typically return data using JSON or XML format instead of HTML. In this step you will create a new controller function for the REST endpoint.
@@ -168,7 +213,7 @@ REST endpoints are similar to normal controllers. The primary difference is that
3. Navigate to ``_. You should see an API page that is auto generated by the `Django REST Framework `_ titled **Get Time Series**. The page should display an *HTTP 401 Unauthorized* error and display a result object with detail "Authentication credentials were not provided."
-3. Test with Postman Application
+5. Test with Postman Application
================================
Most web browsers are surprisingly limited when it comes to testing REST APIs. The reason the test in the previous step resulted in a *401 Unauthorized* is because we sent a request without an authentication token. To more easily test this, you'll want to get a REST client that will allow you to set request headers and parameters. In this tutorial you will use the Postman client to test the REST API as you develop it.
@@ -191,7 +236,7 @@ Most web browsers are surprisingly limited when it comes to testing REST APIs. T
9. Press the **Send** button. You should see the same response object as before with the "Authentication credentials were not provided." message.
-4. Add Token Authorization Headers to Postman Request
+6. Add Token Authorization Headers to Postman Request
=====================================================
In this step you will retrieve the API token for your user account and set authentication headers on the request.
@@ -210,7 +255,7 @@ In this step you will retrieve the API token for your user account and set authe
7. Press the **Save** button to save your changes to the Postman request.
-5. Define Parameters for REST API
+7. Define Parameters for REST API
=================================
In this step you'll define the parameters that the REST endpoint will accept. If you think of the REST endpoint as a function, then the parameters are like the arguments to the function. The controller will be configured to work with both the ``GET`` and ``POST`` methods for illustration purposes.
@@ -292,7 +337,7 @@ In this step you'll define the parameters that the REST endpoint will accept. If
6. Press the **Save** button to save your changes to the Postman request.
-6. Validate Platform, Sensor, Product, and Index
+8. Validate Platform, Sensor, Product, and Index
================================================
In this step you'll add the validation logic for the ``platform``, ``sensor``, ``product``, and ``index`` parameters. The REST endpoint is like a function shared publicly on the internet--anyone can call it with whatever parameters they want. This includes bots that may try to exploit your website through its REST endpoints. Be sure to only allow valid values through and provide helpful feedback for users of the REST API.
@@ -396,7 +441,7 @@ In this step you'll add the validation logic for the ``platform``, ``sensor``, `
9. Repeat this process, adding first the ``sensor`` parameter, then the ``product`` parameter to confirm that the validation logic is working as expected.
-7. Validate Dates
+9. Validate Dates
=================
In this step you'll add the validation logic for the ``start_date`` and ``end_date`` parameters. There is logic that already exists in the ``viewer`` controller that you can use to validate the date parameters in our REST API function. However, you should avoid copying code to prevent duplicating bugs and make the app easier to maintain. Instead, you will generalize the bit of code from the ``viewer`` controller into a helper function and then use that function in both the ``viewer`` controller and the ``get_time_series`` controller.
@@ -581,8 +626,8 @@ In this step you'll add the validation logic for the ``start_date`` and ``end_da
* ``start_date`` and ``end_date`` outside of valid range of selected product (see :file:`gee/products.py`)
* Incorrect date format given for either date parameter
-8. Validate Reducer, Orient, and Scale
-======================================
+10. Validate Reducer, Orient, and Scale
+=======================================
In this step you'll add the validation logic for the ``reducer``, ``orient``, and ``scale`` parameters. The ``reducer`` and ``orient`` parameters each have a short list of valid options and the ``scale`` parameter needs to be a number.
@@ -648,8 +693,8 @@ In this step you'll add the validation logic for the ``reducer``, ``orient``, an
8. Change ``scale`` to a valid value other than the default (e.g.: ``150``). Verify this value is returned.
-9. Validate Geometry
-====================
+11. Validate Geometry
+=====================
In this step you'll add the logic to validate the ``geometry`` parameter, which should be valid GeoJSON. An optimistic strategy will be used in which an attempt will be made to convert the string into a GeoJSON object. If it fails, then the given string is not valid GeoJSON and an error will be returned.
@@ -703,7 +748,7 @@ In this step you'll add the logic to validate the ``geometry`` parameter, which
When pasting the ``geometry`` value from above, ensure that there are no new lines / returns after (i.e. press Backspace after pasting).
-10. Reuse Existing Helper Function to Get Time Series
+12. Reuse Existing Helper Function to Get Time Series
=====================================================
With the parameters properly vetted, you are now ready to call the ``get_time_series_from_image_collection`` function. It should be a fairly straightforward call of the function, mapping the REST parameters to the arguments of the function. You will need to make a few minor changes to the function, however, to accommodate the new ``orient`` option.
@@ -832,7 +877,7 @@ With the parameters properly vetted, you are now ready to call the ``get_time_se
4. Press the **Send** button to submit the request and verify that the time series is included in the response object.
-11. Test & Verify
+13. Test & Verify
=================
1. Use Postman to try different values for each of the parameters. Use some that are valid and others that are not to ensure the validation is working.
@@ -941,7 +986,7 @@ With the parameters properly vetted, you are now ready to call the ``get_time_se
}
}
-12. Solution
+14. Solution
============
This concludes this portion of the GEE Tutorial. You can view the solution on GitHub at ``_ or clone it as follows:
diff --git a/docs/tutorials/key_concepts/advanced.rst b/docs/tutorials/key_concepts/advanced.rst
index c66bf3ff0..e17b9c3ce 100644
--- a/docs/tutorials/key_concepts/advanced.rst
+++ b/docs/tutorials/key_concepts/advanced.rst
@@ -33,7 +33,43 @@ If you wish to use the intermediate solution as a starting point:
In the :doc:`./intermediate` tutorial we implemented a file-based database as the persisting mechanism for the app. However, simple file based databases typically don't perform well in a web application environment, because of the possibility of many concurrent requests trying to access the file. In this section we'll refactor the Model to use an SQL database, rather than files.
-a. Open the ``app.py`` and define a new ``PersistentStoreDatabaseSetting`` by adding the ``persistent_store_settings`` method to your app class:
+a. Add necessary dependencies:
+
+Persistent stores is an optional feature in Tethys, and requires that the ``sqlalchemy<2`` and ``psycopg2`` libraries are installed. Install these libraries using one of the following commands:
+
+.. code-block:: console
+
+ # conda: conda-forge channel strongly recommended
+ conda install -c conda-forge "sqlalchemy<2" psycopg2
+
+ # pip
+ pip install "sqlalchemy<2" psycopg2
+
+Now add the new dependencies to your :file:`install.yml` as follows so that the app will work when installed in a new environment:
+
+.. code-block:: yaml
+
+ # This file should be committed to your app code.
+ version: 1.0
+ # This should match the app - package name in your setup.py
+ name: dam_inventory
+
+ requirements:
+ # Putting in a skip true param will skip the entire section. Ignoring the option will assume it be set to False
+ skip: false
+ conda:
+ channels:
+ - conda-forge
+ packages:
+ - sqlalchemy<2
+ - psycopg2
+
+ pip:
+
+ post:
+
+
+b. Open the ``app.py`` and define a new ``PersistentStoreDatabaseSetting`` by adding the ``persistent_store_settings`` method to your app class:
.. code-block:: python
@@ -62,7 +98,7 @@ a. Open the ``app.py`` and define a new ``PersistentStoreDatabaseSetting`` by ad
Tethys provides the library SQLAlchemy as an interface with SQL databases. SQLAlchemy provides an Object Relational Mapper (ORM) API, which allows data models to be defined using Python and an object-oriented approach. With SQLAlchemy, you can harness the power of SQL databases without writing SQL. As a primer to SQLAlchemy ORM, we highly recommend you complete the `Object Relational Tutorial `_.
-b. Define a table called ``dams`` by creating a new class in ``model.py`` called ``Dam``:
+c. Define a table called ``dams`` by creating a new class in ``model.py`` called ``Dam``:
.. code-block:: python
@@ -102,7 +138,7 @@ b. Define a table called ``dams`` by creating a new class in ``model.py`` called
For more information on Persistent Stores, see: :doc:`../../tethys_sdk/tethys_services/persistent_store`.
-c. Replace the ``add_new_dam`` and ``get_all_dams`` functions in ``model.py`` with versions that use the SQL database instead of the files:
+d. Replace the ``add_new_dam`` and ``get_all_dams`` functions in ``model.py`` with versions that use the SQL database instead of the files:
.. code-block:: python
@@ -156,7 +192,7 @@ c. Replace the ``add_new_dam`` and ``get_all_dams`` functions in ``model.py`` wi
Don't forget to close your ``session`` objects when you are done. Eventually you will run out of connections to the database if you don't, which will cause unsightly errors.
-d. Create a new function called ``init_primary_db`` at the bottom of ``model.py``. This function is used to initialize the database by creating the tables and adding any initial data.
+e. Create a new function called ``init_primary_db`` at the bottom of ``model.py``. This function is used to initialize the database by creating the tables and adding any initial data.
.. code-block:: python
@@ -198,7 +234,7 @@ d. Create a new function called ``init_primary_db`` at the bottom of ``model.py`
session.commit()
session.close()
-e. Refactor ``home`` controller in ``controllers.py`` to use the updated model methods:
+f. Refactor ``home`` controller in ``controllers.py`` to use the updated model methods:
.. code-block:: python
:emphasize-lines: 1-2, 7, 13-14, 19-20, 23-27
@@ -236,7 +272,7 @@ e. Refactor ``home`` controller in ``controllers.py`` to use the updated model m
...
-f. Refactor the ``add_dam`` controller to use the updated model methods:
+g. Refactor the ``add_dam`` controller to use the updated model methods:
.. code-block:: python
:emphasize-lines: 1-2, 52
@@ -299,7 +335,7 @@ f. Refactor the ``add_dam`` controller to use the updated model methods:
...
-g. Refactor the ``list_dams`` controller to use updated model methods:
+h. Refactor the ``list_dams`` controller to use updated model methods:
.. code-block:: python
:emphasize-lines: 1-2, 6, 12-13
@@ -322,7 +358,7 @@ g. Refactor the ``list_dams`` controller to use updated model methods:
...
-h. Add a **Persistent Store Service** to Tethys Portal:
+i. Add a **Persistent Store Service** to Tethys Portal:
a. Go to Tethys Portal Home in a web browser (e.g. http://localhost:8000/apps/)
b. Select **Site Admin** from the drop down next to your username.
@@ -341,7 +377,7 @@ h. Add a **Persistent Store Service** to Tethys Portal:
The username and password for the persistent store service must be a superuser to use spatial persistent stores.
Note that the default installation of Tethys Portal includes a superuser named "tethys_super", password: "pass".
-9. Assign the new **Persistent Store Service** to the Dam Inventory App:
+j. Assign the new **Persistent Store Service** to the Dam Inventory App:
a. Go to Tethys Portal Home in a web browser (e.g. http://localhost:8000/apps/)
b. Select **Site Admin** from the drop down next to your username.
@@ -355,7 +391,7 @@ h. Add a **Persistent Store Service** to Tethys Portal:
:width: 100%
:align: center
-j. Execute the **syncstores** command to create the tables in the Persistent Store database:
+k. Execute the **syncstores** command to create the tables in the Persistent Store database:
.. code-block:: bash
diff --git a/docs/tutorials/key_concepts/beginner.rst b/docs/tutorials/key_concepts/beginner.rst
index 19e697d86..e3e1a39e5 100644
--- a/docs/tutorials/key_concepts/beginner.rst
+++ b/docs/tutorials/key_concepts/beginner.rst
@@ -103,7 +103,7 @@ Tethys apps are developed using the :term:`Model View Controller` (MVC) software
4. Views
========
-Views for Tethys apps are constructed using the standard web programming tools: HTML, JavaScript, and CSS. Additionally, HTML templates can use the Django Template Language, because Tethys Platform is build on Django. This allows you to insert Python code into your HTML documents making the web pages of your app dynamic and reusable.
+Views for Tethys apps are constructed using the standard web programming tools: HTML, JavaScript, and CSS. Additionally, HTML templates can use the Django Template Language, because Tethys Platform is build on Django. This allows you to coding logic into your HTML documents, using template tags, making the web pages of your app dynamic and reusable.
a. Open ``/templates/dam_inventory/home.html`` and replace it's contents with the following:
@@ -223,7 +223,7 @@ c. Save your changes to ``map.css`` and ``home.html`` and refresh the page to vi
7. Create a New Page
====================
-Creating a new page in your app consists of three steps: (1) create a new template, (2) add a new controller to ``controllers.py``, and (3) add a new ``UrlMap`` to the ``app.py``.
+Creating a new page in your app consists of three steps: (1) create a new template, (2) add a new controller to ``controllers.py``, and (3) define the routing using the ``controller`` decorator.
a. Create a new file ``/templates/dam_inventory/add_dam.html`` and add the following contents:
@@ -248,7 +248,7 @@ b. Create a new controller function called ``add_dam`` at the bottom of the ``co
This is the most basic controller function you can write: a function that accepts an argument called ``request`` and a return value that is the result of the ``render`` function. The ``render`` function renders the Django template into valid HTML using the ``request`` and ``context`` provided.
- Notice the use of the ``url`` argument in the ``controller`` decorator. The default URL that would have been generated without this argument would have been ``'add-dam'``. The ``url`` argument is used to provide a custom URL for a controller. URLs are defined relative to the root URL of the app. The full URL for the ``add_dam`` controller as shown above is ``'/apps/dam-inventory/dams/add/'``.
+ Notice the use of the ``url`` argument in the ``controller`` decorator. The ``controller`` decorator creates a route that maps a URL to this controller function. The default URL that would have been generated without this argument would have been ``'add-dam'``. The ``url`` argument is used to provide a custom URL for a controller. URLs are defined relative to the root URL of the app. The full URL for the ``add_dam`` controller as shown above is ``'/apps/dam-inventory/dams/add/'``. Also note that the name of the route created by the ``controller`` decorator is, by default, the same as the function name (``add_dam``). The name of the route will be important when we need to reference it in a template.
c. At this point you should be able to access the new page by entering its URL (``_) into the address bar of your browser. It is not a very exciting page, because it is blank.
@@ -363,7 +363,7 @@ b. Modify ``app_navigation_items`` block in ``/templates/dam_inventory/base.html