Paths API

Last Updated: September 2024

Tip

If you are transitioning from using the Workspaces API then refer to the Guide to transitioning to the Paths API.

The Paths API makes it easy for you to retrieve the proper directories for accessing resource files in your app or writing files at runtime. This can be a tricky task for a web application, because of the multi-user, simultaneous-connection environment of the web. The Paths API provides a simple mechanism for creating and managing global, writable directories for your app and individual directories for each user of your app to prevent unwanted overwrites and file lock conflicts. It also provides a simple way to retrieve read-only file resources that are version controlled with the app source code.

Path Types

The Paths API provides access to the following types of Paths:

Read/Write

  • App Workspace: A location were the app can write files at runtime

  • App Media: A location were the app can store uploaded (publicly accessible) information

  • User Workspace: A location were the app can write user files at runtime

  • User Media: A location were the app can store user uploaded (publicly accessible) information

Read-Only

  • App Public: The location of the app's public directory (i.e. were static files like css and JavaScrip are stored)

  • App Resources: The location where version-controlled app resource files (e.g. configuration files) are stored

Getting Paths

There are several methods for obtaining the paths that are supported in Tethys Platform as follows:

Routing Decorators

The Tethys paths can easily be accessed in controllers, consumers, and handlers by specifying arguments to the various routing decorators. The arguments for each routing decorator is described below:

Controller Decorator

The method for obtaining Tethys paths in controllers is to use the following arguments in controller decorator:

  • app_workspace

  • user_workspace

  • app_media

  • user_media

  • app_public

  • app_resources

When you specify the argument in the controller decorator you must also specify the argument in the controller function itself as this is how the path will be passed to the controller function:

from tethys_sdk.routing import controller

@controller(app_workspace=True)
def my_controller(request, app_workspace):
   ...

@controller(user_workspace=True)
def my_controller(request, user_workspace):
   ...

@controller(app_media=True)
def my_controller(request, app_media):
   ...

@controller(user_media=True)
def my_controller(request, user_media):
   ...

@controller(app_public=True)
def my_controller(request, app_public):
   ...

@controller(app_resources=True)
def my_controller(request, app_resources):
   ...

@controller(
    app_workspace=True,
    user_workspace=True,
    app_media=True,
    user_media=True,
    app_public=True,
    app_resources=True,
)
def my_controller(request, app_workspace, user_workspace, app_media, user_media, app_public, app_resources):
   ...

Note that the argument name in the controller function must match the argument to the controller decorator since the paths are passed to the controller function as key-word arguments.

To learn more about the controller decorator, see: Controller Decorator

Consumer Decorator

To access Tethys paths in consumers, the with_paths argument to the consumer decorator should be set to True. The paths will then be accessible as attributes on the class object.

from channels.generic.websocket import AsyncWebsocketConsumer
from tethys_sdk.routing import consumer

@consumer(
    with_paths=True,
    login_required=True,
)
class MyConsumer(AsyncWebsocketConsumer):

    async def authorized_connect(self):
        self.app_workspace
        self.user_workspace
        self.app_media
        self.user_media
        self.app_public
        self.app_resources

Handler Decorator

To access Tethys paths in handlers, the with_paths argument to the handler decorator should be set to True. The paths will then be accessible on the document object that is passed to the handler.

from tethys_sdk.routing import handler

@handler(
    with_paths=True
)
def my_app_handler(document):
    # attributes available when using "with_paths" argument
    request = document.request
    user_workspace = document.user_workspace
    user_media = document.user_media
    app_workspace = document.app_workspace
    app_media = document.app_media
    app_public = document.app_public
    app_resources = document.app_resources
    ...

App Class Methods and Properties

In some cases, it may be necessary (or more convenient) to use the app class to access the Tethys paths:

from .app import App
from django.contrib.auth.models import User

user = User.objects.get(id=1)
app_workspace = App.get_app_workspace()
user_workspace = App.get_user_workspace(user)
app_media = App.get_app_media()
user_media = App.get_user_media(user)
app_public = App.public_path
app_resources App.resources_path
...

Note

While the workspace and media directories are accessed through methods on the app class, public_path and resources_path are properties of the App class.

For more details see App Base Class API

Path Functions

In the rare cases where you need to use a Tethys path where it is not convenient or not possible to use one of the decorators OR the app class methods, the Paths API provides function versions of the getters. Import them from tethys_sdk.paths:

paths.get_app_workspace()
Parameters:

app_or_request (TethysAppBase, TethysApp, or HttpRequest) -- The Tethys app class that is defined in app.py or HttpRequest to app endpoint.

Raises:
  • ValueError -- if app_or_request is not correct type.

  • AssertionError -- if quota for the app workspace/media directory has been exceeded.

Return type:

TethysPath

Returns: TethysPath representing the app workspace.

paths.get_user_workspace(user_or_request)

Get the dedicated user workspace for the given app. If an HttpRequest is given, the workspace of the logged-in user will be returned (i.e. request.user).

Parameters:
  • app_or_request (TethysAppBase, TethysApp, or HttpRequest) -- The Tethys app class that is defined in app.py or HttpRequest to app endpoint.

  • user_or_request (User or HttpRequest) -- Either an HttpRequest with active user session or Django User object.

Raises:
  • ValueError -- if app_or_request or user_or_request are not correct types.

  • AssertionError -- if quota for the user workspace/media directory has been exceeded.

Return type:

TethysPath

Returns:

TethysPath representing the user's workspace directory.

from tethys_sdk.workspaces import get_user_workspace
from .app import App

def some_function(user):
    user_workspace = get_user_workspace(App, user)
    ...
paths.get_app_media()
Parameters:

app_or_request (TethysAppBase, TethysApp, or HttpRequest) -- The Tethys app class that is defined in app.py or HttpRequest to app endpoint.

Raises:
  • ValueError -- if app_or_request is not correct type.

  • AssertionError -- if quota for the app workspace/media directory has been exceeded.

Returns: TethysPath representing the media directory for the app.

paths.get_user_media(username_or_request)
Parameters:
  • app_or_request (TethysAppBase, TethysApp, or HttpRequest) -- The Tethys app class that is defined in app.py or HttpRequest to app endpoint.

  • username_or_request (User or HttpRequest) -- A User instance or an authenticated request to get the media directory for.

Raises:
  • ValueError -- if app_or_request or user_or_request are not correct types.

  • AssertionError -- if quota for the user workspace/media directory has been exceeded.

Returns: TethysPath representing the user's media directory for the app.

paths.get_app_public()

Gets the public directory of an app or extension as a read-only TethysPath

Parameters:

app_or_request (TethysAppBase, TethysApp, TethysExtensionBase, TethysExtension, or HttpRequest) -- The Tethys app class that is defined in app.py (or extension class in ext.py) or HttpRequest to app endpoint.

Raises:

ValueError -- if app_or_request is not correct type.

Returns: TethysPath representing the public directory of the app (or extension).

paths.get_app_resources()

Gets the resources directory of an app or extension as a read-only TethysPath

Parameters:

app_or_request (TethysAppBase, TethysApp, TethysExtensionBase, TethysExtension, or HttpRequest) -- The Tethys app class that is defined in app.py (or extension class in ext.py) or HttpRequest to app endpoint.

Raises:

ValueError -- if app_or_request is not correct type.

Returns: TethysPath representing the public directory of the app (or extension).

Working with Tethys Paths

All of the methods described above return a TethysPath object that contains the location to the Tethys path and several convenience methods for working with the Tethys path directory. An explanation of the TethysPath object and examples of its usage are provided below.

TethysPath Objects

class tethys_apps.base.TethysPath(path, read_only=False)

Defines objects that represent paths (directories) for apps and users.

Parameters:

path (Path) -- The path to a directory. Cannot be overwritten.

clear(exclude=None, exclude_files=False, exclude_directories=False)

Remove all files and directories in the TethysPath directory.

Parameters:
  • exclude (iterable) -- A list or tuple of file and directory names to exclude from clearing operation.

  • exclude_files (bool) -- Excludes all files from clearing operation when True. Defaults to False.

  • exclude_directories (bool) -- Excludes all directories from clearing operation when True. Defaults to False.

Examples:

# Clear everything
tethys_path.clear()

# Clear directories only
tethys_path.clear(exclude_files=True)

# Clear files only
tethys_path.clear(exclude_directories=True)

# Clear all but specified files and directories
tethys_path.clear(exclude=['file1.txt', '/full/path/to/directory1', 'directory2', '/full/path/to/file2.txt'])
directories(names_only=False)

Return a list of directories (as Path objects by default) that are in the TethysPath directory.

Parameters:

names_only (bool) -- Returns list of directory names as strings when True. Defaults to False.

Returns:

A list of directories in the TethysPath directory.

Return type:

list

Examples:

# List Path objects for each directory
tethys_path.directories()

# List of directory names
tethys_path.directories(names_only=True)
files(names_only=False)

Return a list of files (as Path objects by default) that are in the TethysPath directory.

Parameters:

names_only (bool) -- Returns list of filenames as strings when True. Defaults to False.

Returns:

A list of files in the TethysPath directory.

Return type:

list

Examples:

# List of Path objects for each file
tethys_path.files()

# List of file names
tethys_path.files(names_only=True)
remove(item)

Remove a file or directory from the TethysPath directory.

Parameters:

item (str | Path) -- Name, string path, or Path object of the item to remove from the TethysPath directory.

Examples:

tethys_path.remove('file.txt')
tethys_path.remove('/full/path/to/file.txt')
tethys_path.remove('relative/path/to/file.txt')
tethys_path.remove('directory')
tethys_path.remove('/full/path/to/directory')
tethys_path.remove('relative/path/to/directory')
tethys_path.remove(path_object)

Note: Though you can specify relative paths, the remove() method will not allow you to back into other directories using "../" or similar notation. Furthermore, absolute paths given must contain the path of the tethys_path to be valid.

Centralized Paths

For the workspace and media paths the location of the paths from all apps is centralized based on the TETHYS_WORKSPACES_ROOT and MEDIA_ROOT settings. By default these paths will be in the TETHYS_HOME directory, but they can be specified in the portal_config.yml file.

TETHYS_WORKSPACES_ROOT: /var/www/tethys/workspaces
MEDIA_ROOT: /var/www/tethys/media

Note

The public and the resources directories are relative to the source code of the app (i.e. not centralized). Even when the collectstatic command is used to copy all static files to a central location the Paths API will return the the public directory that is relative to the app source code.

Handling Workspace/Media Clearing

Users and portal administrators are able to clear their user and app workspaces through pages in the Tethys Portal. The app class provides methods to allow the app developer to customize how the app handles clearing user/app workspaces and media directories. Override these methods in your app class to handle clearing workspaces and media directories appropriately in your app. When a workspace/media directory is cleared through the portal admin pages or user profile pages, the appropriate 'pre-delete' method is called, the workspace or media directory is cleared, and then the appropriate 'post-delete' method is called.

classmethod TethysAppBase.pre_delete_app_workspace()

Override this method to pre-process the app workspace before it is emptied

classmethod TethysAppBase.post_delete_app_workspace()

Override this method to post-process the app workspace after it is emptied

classmethod TethysAppBase.pre_delete_user_workspace(user)

Override this method to pre-process a user's workspace before it is emptied

Parameters:

user (User, required) -- User that requested to clear their workspace

classmethod TethysAppBase.post_delete_user_workspace(user)

Override this method to post-process a user's workspace after it is emptied

Parameters:

user (User, required) -- User that requested to clear their workspace

classmethod TethysAppBase.pre_delete_app_media()

Override this method to pre-process the app media directory before it is emptied

classmethod TethysAppBase.post_delete_app_media()

Override this method to post-process the app media directory after it is emptied

classmethod TethysAppBase.pre_delete_user_media(user)

Override this method to pre-process a user's media directory before it is emptied

Parameters:

user (User, required) -- User that requested to clear their media directory

classmethod TethysAppBase.post_delete_user_media(user)

Override this method to post-process a user's media directory after it is emptied

Parameters:

user (User, required) -- User that requested to clear their media directory