heliport.ssh package

Subpackages

Submodules

heliport.ssh.admin module

Registers Django admin pages.

See django.contrib.admin.ModelAdmin from Django documentation.

heliport.ssh.apps module

Django app configuration.

Some HELIPORT hooks can be registered in app config django.apps.AppConfig.ready().

See also Django documentation

class heliport.ssh.apps.SshConfig(app_name, app_module)

Bases: AppConfig

App configuration for ssh app.

name = 'heliport.ssh'
ready()

Register object types and actions, and import settings.

heliport.ssh.interface module

Module with special name “interface” hooks into HELIPORT.

Some functions and heliport.core.app_interaction.Module subclasses are detected by HELIPORT and control how HELIPORT uses this app.

Note that this module must be imported in __init__.py of the django app.

class heliport.ssh.interface.SSHModule

Bases: Module

HELIPORT module in project graph that lists ssh files and directories and allows addition and editing.

get_url(project)

Url when user clicks on this in project graph.

is_configured(project)

Shown in project graph if files or directories added to project.

module_id = 'ssh_files_directories'

name in settings

name = 'SSH Files/Directories'

name in HELIPORT project graph

heliport.ssh.interface.get_search_url()

Url to get search results; used to implement global HELIPORT string search.

heliport.ssh.models module

Contains django.db.models.Model classes for Django ORM.

See Quick example from Django documentation. In HELIPORT the heliport.core.models.DigitalObject can be subclassed for models containing metadata in a project.

class heliport.ssh.models.DBSSHDirectory(*args, **kwargs)

Bases: DigitalObject, DBSSHPath, DirectoryObj

Django model to store SSH directory references in the HELIPORT database.

exception DoesNotExist

Bases: DoesNotExist

exception MultipleObjectsReturned

Bases: MultipleObjectsReturned

as_directory(context: Context) Directory

This is what makes this class into a directory digital object in HELIPORT.

Constructs and returns a SSHDirectory instance.

digitalobject_ptr

Accessor to the related object on the forward side of a one-to-one relation.

In the example:

class Restaurant(Model):
    place = OneToOneField(Place, related_name='restaurant')

Restaurant.place is a ForwardOneToOneDescriptor instance.

digitalobject_ptr_id
directory_id

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

is_directory = True
login

Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.

In the example:

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Child.parent is a ForwardManyToOneDescriptor instance.

login_id
path_str

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

sub_path(relative_path: Path | str, allow_hidden=False)

Helper function to get a pathlib path object that represents a path inside this directory.

Includes a check if the path is really inside the directory and does not access hidden directories.

class heliport.ssh.models.DBSSHFile(*args, **kwargs)

Bases: DigitalObject, DBSSHPath, FileObj

Django model to store SSH file references in the HELIPORT database.

exception DoesNotExist

Bases: DoesNotExist

exception MultipleObjectsReturned

Bases: MultipleObjectsReturned

as_file(context: Context) File

This is what makes this class into a file digital object in HELIPORT.

Constructs and returns a SSHFile instance.

digitalobject_ptr

Accessor to the related object on the forward side of a one-to-one relation.

In the example:

class Restaurant(Model):
    place = OneToOneField(Place, related_name='restaurant')

Restaurant.place is a ForwardOneToOneDescriptor instance.

digitalobject_ptr_id
file_id

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

is_file = True
login

Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.

In the example:

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Child.parent is a ForwardManyToOneDescriptor instance.

login_id
path_str

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

class heliport.ssh.models.DBSSHPath(*args, **kwargs)

Bases: Model

Abstract base class (in the Django Model way) to contain common functionality for SSH file and SSH directory Django models.

class Meta

Bases: object

class to specify additional options for this django model.

abstract = False

specify that this model is abstract (has no database table)

is_directory = False
is_file = False
login

Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.

In the example:

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Child.parent is a ForwardManyToOneDescriptor instance.

login_id
property path

Access path as pathlib path object instead of string.

path_str

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

class heliport.ssh.models.SSHConnection(login: LoginInfo)

Bases: object

Immutable dataclass to describe an SSH connection. Implements the heliport.core.utils.context.Description protocol.

Note that the SSH connection is user specific since the login is user specific. This reduces the chance that somebody can use the connection of someone else on top of the fact that the context is specific for a request (and therefore user) anyway.

generate(context)

Build a heliport.core.utils.command_line_execution.SSHCommandExecutor as connection.

Raises:

UserMessage – if some error occurs.

login: LoginInfo

SSH login for the connection

class heliport.ssh.models.SSHDirectory(base_dir: DBSSHDirectory, relative_path: Path, context: Context)

Bases: SSHPath, Directory

The actual SSH directory that can be used to get directory contents. You should make sure the user has access before returning such a directory.

base_dir: DBSSHDirectory
get_file_info() Dict[str, str]

No extra information for the user implemented right now.

get_parts() Iterator[FileObj | DirectoryObj]

This is the most important method of a directory (similar to file.read()). Yield all the file or directory objects in this directory as SSHDirectoryObj or SSHFileObj. Omits hidden files/directories.

property login: LoginInfo

The ssh login to access this directory.

property path

Get pathlib path; checks if relative_path is really inside this directory. See also DBSSHDirectory.sub_path() that is used for implementation.

relative_path: Path
class heliport.ssh.models.SSHDirectoryObj(base_directory: DBSSHDirectory, relative_path: str)

Bases: SSHPathObj, DirectoryObj

Represent an SSH directory not stored in the HELIPORT database.

as_directory(context: Context) Directory

This method is what makes this class into something that represents a directory in HELIPORT. Checks permission and returns an SSHDirectory instance.

create_db_object() DigitalObject

Create an DBSSHDirectory instance and set the namespace for pid generation.

static related_db_class()
static type_id() str

String to represent this type when resolving an object of this type.

class heliport.ssh.models.SSHFile(login: LoginInfo, absolute_path: Path, context: Context)

Bases: SSHPath, File

The actual SSHFile that can be used to get file contents. You should make sure the user has access before returning such a file.

close()

Closes the file and frees resources; does nothing if the file is not open.

get_file_info() Dict[str, str]

Show size and last modified date to the user if available.

property login: LoginInfo

The ssh login that can be used to access the file.

mimetype() str

Guesses the mimetype based on file name.

open()

Establishes an ssh connection if none exists yet in the current context and opens the file. See also close(), which needs to be called to free the resources again.

Note that heliport.core.digital_object_aspects.File implements also a context manager, so you can use a with block to automatically open and close the file.

property path: Path

Path where this file is stored at the location specified by login.

read(number_of_bytes=None) bytes

Get contents of the file; file needs to be open().

size() int | None

Get file size in bytes if available.

class heliport.ssh.models.SSHFileObj(base_directory: DBSSHDirectory, relative_path: str)

Bases: SSHPathObj, FileObj

Represent an SSH file not stored in the HELIPORT database.

as_file(context: Context) File

This method is what makes this class into something that represents a file in HELIPORT. Checks permission and returns an SSHFile instance.

create_db_object() DigitalObject

Create an DBSSHFile instance and set the namespace for pid generation.

static related_db_class()

DBSSHFile stores the same information as this obj but in the DB.

static type_id() str

String to represent this type when resolving an object of this type.

class heliport.ssh.models.SSHFileStat(login: LoginInfo, path: Path)

Bases: object

Immutable dataclass to describe an SSH filesystem metadata for caching. Implements the heliport.core.utils.context.Description protocol.

Note that this is user specific since the login is user specific. This reduces the chance that somebody can use the connection of someone else on top of the fact that the context is specific for a request (and therefore user) anyway.

generate(context)

Download stat of file or directory; reuses existing SSHConnection.

login: LoginInfo

ssh login to get this stat

path: Path

path of the file for which to get the stat metadata for

class heliport.ssh.models.SSHPath(context: Context)

Bases: FileOrDirectory, ABC

Common functionality to represent actual ssh files and directories. See also HELIPORT docs on Special Digital Objects.

connection()

Get or create an SSH connection.

error(message)

Raise an error containing the message and additional infos about where the error was raised. The raised error message is intended to be shown to the user.

abstract property login: LoginInfo

The ssh login to access this path.

abstract property path: Path

The absolute path under login.

stat()

Get or download the file stat file system metadata for this path.

class heliport.ssh.models.SSHPathObj(base_directory: DBSSHDirectory, relative_path: str)

Bases: GeneralDigitalObject, ABC

Abstract base class for common functionality for ssh files and directories not stored in the heliport database. This mostly implements simple serialization functions and handles resolving the objects not stored in the database.

property absolute_path

Including checking if relative_path really is a sub path.

access(context: Context)

Define who can access how. No access if DBSSHDirectory.sub_path() raises heliport.core.utils.exceptions.AccessDenied otherwise normal access. See also heliport.core.permissions.PermissionChecker.

as_digital_object(context) DigitalObject

return a heliport.core.models.DigitalObject instance representing the same file or directory; return an existing one or create a new one.

as_html() str

Represent in html just by the filename.

as_rdf() RootedRDFGraph

Represent just as string in rdf for now. In the future this should probably construct a node of type file with the string as filename.

as_text() str

implements heliport.core.utils.serialization.GeneralValue interface.

Files need to be represented as string by their filename.

as_tuple()

To implement __hash__ and __eq__ easily.

abstract create_db_object() DigitalObject

Select django model and set category_str in subclass.

directory: DBSSHDirectory

this class represents something inside this base directory

get_identifying_params() Dict[str, str]

Parameters to resolve this object from.

abstract static related_db_class()

Get the django model that stores the same information as this class.

relative_path: str

the path of this object inside directory; this may be ../../a/secret.txt!

classmethod resolve(params: Dict, context: Context) GeneralDigitalObject | None

get the object from its identifying parameters (see get_identifying_params()).

Make sure to return a heliport.core.models.DigitalObject subclass instance if one already exists.

heliport.ssh.serializers module

This module is for serialization into Datacite, RDF and JSON.

The JSON format is used for API endpoints via Django rest framework. Using this, it is typical to put the serializer classes into a “serializers.py” file.

For the serialization into RDF, attributes are described. See heliport.core.attribute_description.BaseAttribute for more detail.

class heliport.ssh.serializers.DirectorySerializer(*args, **kwargs)

Bases: ModelSerializer

Django rest framework serializer for SSH directories.

class Meta

Bases: object

Description of the serializer.

fields = ['directory_id', 'digital_object_id', 'path_str', 'description', 'label', 'login', 'projects', 'persistent_id']
model

alias of DBSSHDirectory

class heliport.ssh.serializers.FileSerializer(*args, **kwargs)

Bases: ModelSerializer

Django rest framework serializer for SSH files.

class Meta

Bases: object

Description of the serializer.

fields = ['file_id', 'digital_object_id', 'path_str', 'description', 'label', 'login', 'projects', 'persistent_id']
model

alias of DBSSHFile

heliport.ssh.tests module

Test the behaviour of this app.

This follows the Writing tests guide in Django.

class heliport.ssh.tests.SSHTests(methodName='runTest')

Bases: WithProject

test_delete()
test_list()
test_update()
class heliport.ssh.tests.SearchAndAPITest(methodName='runTest')

Bases: WithProject

Test search including via API.

Test that search URL is accessible.

test_api()

Test api.

test_findable()

Test that files and directories are findable.

heliport.ssh.urls module

Map django views to urls.

See this Example including explanation from the Django documentation.

heliport.ssh.views module

Contains Django View classes to handle HTTP requests.

See Using class-based views from Django documentation. In HELIPORT heliport.core.mixins are used to create uniform views. Also heliport.core.views.generic.HeliportObjectListView is used to quicly create a typical HELIPORT list view.

class heliport.ssh.views.DirectoryViewSet(**kwargs)

Bases: HeliportModelViewSet

SSH Directory.

Files in directory are available at /api/directories/<directory_id>/contents

contents(request, pk=None)

Get files and directories in directory.

contents_from_description(request)

Get files and directories in directory.

directory is specified via describing parameters to allow download of subdirectories

filter_backends = [<class 'rest_framework.filters.SearchFilter'>, <class 'django_filters.rest_framework.backends.DjangoFilterBackend'>]
filterset_fields = ['directory_id', 'persistent_id']
get_queryset()

Get users non-deleted SSH directories.

search_fields = ['attributes__value']
serializer_class

alias of DirectorySerializer

class heliport.ssh.views.FileViewSet(**kwargs)

Bases: HeliportModelViewSet

SSH File.

File contents is available for download at /api/files/<file_id>/download

download(request, pk=None)

Get streaming file response to download file contents.

download_from_description(request)

Get streaming file response to download file contents.

The file to download is specified by request parameters. This enables downloading files not directly stored in heliport e.g. inside a directory.

filter_backends = [<class 'rest_framework.filters.SearchFilter'>, <class 'django_filters.rest_framework.backends.DjangoFilterBackend'>]
filterset_fields = ['file_id', 'persistent_id']
get_queryset()

Get users non-deleted SSH files.

search_fields = ['attributes__value']
serializer_class

alias of FileSerializer

class heliport.ssh.views.MigrateDataSourceView(**kwargs)

Bases: HeliportProjectMixin, DetailView

View for migrating old heliport.data_source.models.DataSource to this app. This is used for MigrateSSHDatasource action.

do_migration(obj, context)

Creates a new SSH file and directory by connecting via ssh and checking if the path is a file or a directory. Raises a heliport.core.utils.exceptions.UserMessage if obj is not a valid SSH file or directory. Marks the old obj as deleted.

get(request, *args, **kwargs)

Handle get request; setup context for do_migration().

model

alias of Project

pk_url_kwarg = 'project'
class heliport.ssh.views.MigrateSSHDatasource(obj: ObjType = None, project: Project = None, user: HeliportUser = None)

Bases: Action

Action to migrate old ssh data sources to this app.

property applicable: bool

Applicable on digital objects having path, login and protocol="ssh".

icon = 'fa-wrench'

Construct url for MigrateDataSourceView.

name = 'Migrate'
class heliport.ssh.views.SSHListView(**kwargs)

Bases: HeliportProjectMixin, DetailView

List ssh files and directories and allow creation and edit.

create_new(context) DBSSHFile | DBSSHDirectory

Create new file or directory in database and set namespace for pid.

directory_type = 'directories'
get_context_data(**kwargs)

Get files and directories for rendering as well as the instance for edit.

get_instance()

Get existing file or directory from database.

get_login()

Get login from post data.

handle_update()

Get or create instance and set attributes.

model

alias of Project

pk_url_kwarg = 'project'
post(*args, **kwargs)

Handle post request, called by Django; handle delete directly.

set_attributes(instance)

Set parameters from post request on file or directory.

template_name = 'ssh/list.html'
class heliport.ssh.views.SearchView(**kwargs)

Bases: HeliportLoginRequiredMixin, TemplateView

search SSH files and directories; render results.

get_context_data(**kwargs)

Called by django TemplateView; search files and directories.

template_name = 'ssh/search.html'

Module contents

App to store metadata about and allow access to files via SSH.

The interface module is imported to the top level of the package for HELIPORT app interface discovery (see heliport.core.app_interaction.get_heliport_apps()).