research_client.config

Configuration handler for L’ART Research Client.

This package provides an API to read, modify, and store app configuration. The configuration is stored in a JSON file and relevant paths (unless explicitly specified) are determined based on the Operating System (using the AppDirs package).

The configuration package only exposes the actual interface to the configuration, which is done via the singleton config object, an instantiation of the Config class.

To access and/or modify the configuration of the running app, you should import only config. The other classes and objects in the package will not typically be needed, perhaps with the exceptions of functions that deal with system updates and the like (as for instance the functionality in the research_client.utils module).

Example

Let’s imagine you want to ensure that the shutdown_delay setting is always at least three seconds. The following example shows how you would load the current app configuration, check the current value, and if it is below the threshold increase it to 3.00 and then save the modified configuration (so that it will persist when the app is restarted):

from .config import config

if config.shutdown_delay < 3.00:
    config.shutdown_delay = 3.00
    config.save()

Module Attributes

config

The default configuration object for the app.

Classes

Config

Class for keeping track of App configuration data.

DataclassDictMixin

Mixin adding asdict() and fromdict() methods to a dataclass.

DataclassDocMixin

Mixin adding a getdocs() method to a dataclass.

JSONPathEncoder

JSON Encoder capable of serialising pathlib Path objects.

Logging

Class for Logging configuration.

Paths

Class for configuration of App paths.

Sequences

Class for app-task sequencing configuration.

class Config[source]

Bases: DataclassDictMixin, DataclassDocMixin

Class for keeping track of App configuration data.

__init__(logging=Logging(max_files=10, default_level=30, stream_format='{levelname}:{name}: {message}', file_format='[{asctime} {levelname:<8} {name}] {message}'), paths=Paths(config=PosixPath('/home/docs/.config/Research_Client'), data=PosixPath('/home/docs/.local/share/Research_Client/Data'), logs=PosixPath('/home/docs/.local/state/Research_Client/log'), cache=PosixPath('/home/docs/.cache/Research_Client')), sequences=Sequences(agt='', atolc='memorygame', conclusion='', consent='lsbq', lsbq='atolc', memorygame=''), shutdown_delay=2.0)
Parameters:
Return type:

None

classmethod load(filename='settings.json')[source]

Load configuration from a file or return default Config().

Return type:

Config

Parameters:

filename (str)

save(filename='settings.json')[source]

Save configuration to a file.

Parameters:

filename (str)

appauthor = 'L’ART'

Type:    str

appname = 'Research Client'

Type:    str

appversion = '0.3.4'

Type:    str

logging = Logging(max_files=10, default_level=30, stream_format='{levelname}:{name}: {message}', file_format='[{asctime} {levelname:<8} {name}] {message}')

Type:    Logging

paths = Paths(config=PosixPath('/home/docs/.config/Research_Client'), data=PosixPath('/home/docs/.local/share/Research_Client/Data'), logs=PosixPath('/home/docs/.local/state/Research_Client/log'), cache=PosixPath('/home/docs/.cache/Research_Client'))

Type:    Paths

sequences = Sequences(agt='', atolc='memorygame', conclusion='', consent='lsbq', lsbq='atolc', memorygame='')

Type:    Sequences

shutdown_delay = 2.0

Type:    float

class DataclassDictMixin[source]

Bases: object

Mixin adding asdict() and fromdict() methods to a dataclass.

asdict()[source]

Return a deep copy of the dataclass as a dictionary.

Return type:

dict[str, Any]

classmethod fromdict(d, ignorefaults=False)[source]

Recursively converts a dictionary to a dataclass instance.

Parameters:
  • d (dict[str, Any])

  • ignorefaults (bool)

class DataclassDocMixin[source]

Bases: object

Mixin adding a getdocs() method to a dataclass.

This enables adding additional documentation to dataclass fields using the field’s metadata property. The following metadata properties are read by the DataclassDocMixin:

  • doc_label: A human-friendly label/short description of a field.

  • doc_help: A human-friendly explanation of what a field does / why it’s there.

  • doc_values: A dictionary of label-value pairs, which can be used to give an indication of specific values the field can take and what they mean.

getdocs(recurse=True, include_undocumented=False)[source]

Return a dictionary with documentation for the dataclass’s fields.

Parameters:
  • recurse (bool, default: True) – Whether to also fetch the field-docs for fields that are dataclasses.

  • include_undocumented (bool, default: False) – Whether to include fields that do not have at least doc_label assigned in their metadata.

Return type:

tuple[list[dict[str, Any]], list[dict[str, Any]]]

Returns: A two-tuple, where the first member is a list of dataclass

fields, the second member a list of non-dataclass fields. Each list contains a dictionary with information about the field.

class JSONPathEncoder[source]

Bases: JSONEncoder

JSON Encoder capable of serialising pathlib Path objects.

default(o)[source]

Encodes pathlib Path objects as strings, otherwise uses default JSONEncoder.

Parameters:

o (Any)

class Logging[source]

Bases: DataclassDictMixin, DataclassDocMixin

Class for Logging configuration.

__init__(max_files=10, default_level=30, stream_format='{levelname}:{name}: {message}', file_format='[{asctime} {levelname:<8} {name}] {message}')
Parameters:
  • max_files (int)

  • default_level (int)

  • stream_format (str)

  • file_format (str)

Return type:

None

_get_file_path(name, path)[source]

Determine log file path and clear old log files.

Scans path for logfiles named after name (name*_.log). If there are more than config.logging.max_files - 1, removes the oldest until that value is reached, and returns a path to a new log file (without creating it yet).

Return type:

Path

Parameters:
  • name (str)

  • path (Path)

get_file_handler(name, path=None)[source]

Return a logging.FileHandler object for logging.

Return type:

FileHandler

Parameters:
  • name (str)

  • path (Optional[Union[Path, str]])

get_stream_handler(stream=None)[source]

Return a logging.StreamHandler object for logging.

Parameters:

stream (Any)

Return type:

logging.StreamHandler[Any]

default_level = 30

Type:    int

file_format = '[{asctime} {levelname:<8} {name}] {message}'

Type:    str

max_files = 10

Type:    int

stream_format = '{levelname}:{name}: {message}'

Type:    str

class Paths[source]

Bases: DataclassDictMixin, DataclassDocMixin

Class for configuration of App paths.

__init__(data=PosixPath('/home/docs/.local/share/Research_Client/Data'), logs=PosixPath('/home/docs/.local/state/Research_Client/log'), cache=PosixPath('/home/docs/.cache/Research_Client'))
Parameters:
  • data (Path)

  • logs (Path)

  • cache (Path)

Return type:

None

cache = PosixPath('/home/docs/.cache/Research_Client')

Type:    Path

config = PosixPath('/home/docs/.config/Research_Client')

Type:    Path

data = PosixPath('/home/docs/.local/share/Research_Client/Data')

Type:    Path

logs = PosixPath('/home/docs/.local/state/Research_Client/log')

Type:    Path

class Sequences[source]

Bases: DataclassDictMixin, DataclassDocMixin

Class for app-task sequencing configuration.

__init__(agt='', atolc='memorygame', conclusion='', consent='lsbq', lsbq='atolc', memorygame='')
Parameters:
  • agt (str)

  • atolc (str)

  • conclusion (str)

  • consent (str)

  • lsbq (str)

  • memorygame (str)

Return type:

None

_sequence_options = {'AGT': 'agt', 'AToL-C': 'atolc', 'App start screen': '', 'Conclusion Screen': 'conclusion', 'Consent Form': 'consent', 'LSBQe': 'lsbq', 'Memory Task': 'memorygame'}

Type:    ClassVar[dict[str, str]]

agt = ''

Type:    str

atolc = 'memorygame'

Type:    str

conclusion = ''

Type:    str

consent = 'lsbq'

Type:    str

lsbq = 'atolc'

Type:    str

memorygame = ''

Type:    str

config = Config(appname='Research Client', appauthor='L’ART', appversion='0.3.4', logging=Logging(max_files=10, default_level=30, stream_format='{levelname}:{name}: {message}', file_format='[{asctime} {levelname:<8} {name}] {message}'), paths=Paths(config=PosixPath('/home/docs/.config/Research_Client'), data=PosixPath('/home/docs/.local/share/Research_Client/Data'), logs=PosixPath('/home/docs/.local/state/Research_Client/log'), cache=PosixPath('/home/docs/.cache/Research_Client')), sequences=Sequences(agt='', atolc='memorygame', conclusion='', consent='lsbq', lsbq='atolc', memorygame=''), shutdown_delay=2.0)

Type:    Final[Config]

The default configuration object for the app.

This is an instance of Config loaded from the users’ stored settings upon module initialisation (if available), otherwise it is populated with (sensible) default values.

When saved with config.save() it will automatically save in the correct file and location depending on the user’s system and installation type.