ResearchNotes package

Open ResearchNotes is an electronic lab book (ELN).

ResearchNotes.create_app(config_file: Optional[str] = None, testing: bool = False, testing_search: bool = False, debug: bool = False) Flask[source]

Create the flask web application.

This is the only function to be called directly. It is the Flask application factory function to create a Flask Class object to be run.

Parameters:
  • config_file (str|None, optional) – Provide a configuration file during app creation. That might be practical, if your config file is somewhere outside the standard path, and you cannot set an environment variable. The default is None.

  • testing (bool) – Switch to test mode. Default is False.

  • testing_search (bool) – Test the fulltext search. Default is False.

  • debug (bool) – Switch on debug mode

Returns:

app – Returns the flask webapp that then can be served by any uwsgi server like Gunicorn, uWSGI or waitress. These should in praxis sit behind a real webserver.

Return type:

flask.Flask

Example

app = create_app()

app = create_app(“path_to_your_file/ResearchNotes_conf.py”)

Subpackages

Submodules

ResearchNotes.app_configuration module

App configuration module.

Define the configuration of the app for different operating systems and usage scenarios.

class ResearchNotes.app_configuration.BaseConfig[source]

Bases: object

Base configuration class.

DEBUG = False
TESTING = False
SECRET_KEY = 'dev'
SEC_SESSION_KEY = 'dev'
CONFIG_FILE = 'config.py'
DATABASE_MIGRATION = 'migrations'
ALLOWED_EXTENSIONS = ({'.jpg', '.txt', '.png', '.gif', '.jpeg', '.pdf'},)
FORBIDDEN_EXTENSIONS = {'.386', '.ade', '.adp', '.app', '.asp', '.bas', '.bat', '.cer', '.cgi', '.chm', '.cmd', '.com', '.cpl', '.crt', '.csh', '.csr', '.dll', '.drv', '.exe', '.fxp', '.hlp', '.hta', '.htaccess', '.htpasswd', '.inf', '.ins', '.isp', '.jar', '.js', '.jse', '.jsp', '.ksh', '.lnk', '.mdb', '.mde', '.mdt', '.mdw', '.msc', '.msi', '.msp', '.mst', '.ops', '.pcd', '.php', '.pif', '.pl', '.prg', '.reg', '.scr', '.sct', '.sh', '.shb', '.shs', '.sys', '.torrent', '.url', '.vb', '.vbe', '.vbs', '.vbscript', '.wsc', '.wsf', '.wsh'}
MAX_CONTENT_LENGTH = 104857600
SQLALCHEMY_TRACK_MODIFICATIONS = True
FLATPAGES_ENCODING = 'cp1252'
FLATPAGES_EXTENSION = '.md'
ESS_PER_GROUP = False
LOG_FILE = True
LOG_FILENAME = 'researchnotes.log'
LOG_SYSLOG = False
LOG_SYSLOG_ADDR = ('localhost', 514)
LOG_SYSLOG_FAC = 'local3'
ELASTICSEARCH_URL = None
MEILISEARCH_URL = None
MEILISEARCH_MKEY = None
class ResearchNotes.app_configuration.TestConfig[source]

Bases: BaseConfig

Testing configuration used in the moment of create_app.

DEBUG = True
TESTING = True
SECRET_KEY = 'dev'
SEC_SESSION_KEY = 'dev'
UPLOAD_PATH = ''
SQLALCHEMY_DATABASE_URI = 'sqlite://'
LOG_FILE = False
class ResearchNotes.app_configuration.TestSearchConfig[source]

Bases: TestConfig

Search-specific testing configuration used in the moment of create_app.

ELASTICSEARCH_URL = 'http://localhost:9200'
class ResearchNotes.app_configuration.DevConfig[source]

Bases: BaseConfig

Development configuration used in the moment of create_app.

DEBUG = True
SECRET_KEY

meta hide-value: Uses os.environ.get(“SECRET_KEY”, default=”dev”)

SEC_SESSION_KEY

meta hide-value: Uses os.environ.get(“SECRET_KEY”, default=”dev”)

UPLOAD_PATH = 'D:\\ResearchNotes'
SQLALCHEMY_DATABASE_URI

meta hide-value:

LOG_FILE = False
LOG_PATH = 'D:\\ResearchNotes/logs'
LOG_FILENAME = 'researchnotes.log'
ELASTICSEARCH_URL = None
MEILISEARCH_URL = None
class ResearchNotes.app_configuration.ProConfig[source]

Bases: BaseConfig

Production configuration used in the moment of create_app.

SECRET_KEY

meta hide-value: os.environ.get(“SEC_SESSION_KEY”, default=secrets.token_hex(32))

SEC_SESSION_KEY

meta hide-value: Created using secrets.token_hex(32)

UPLOAD_PATH = ''
CONFIG_FILE = 'ResearchNotes_conf.py'
LOG_PATH = 'researchnotes_logs/'
DATABASE_MIGRATION = ''
SQLALCHEMY_DATABASE_URI

meta hide-value:

ResearchNotes.auth module

Authorisation model.

Everything with user will go here regarding login/logout and authorisation to access something (if not done in get_item function.)

Several function are decorators for called views, e.g. login_required or role_required

ResearchNotes.auth.login() str | werkzeug.wrappers.response.Response[source]

Login of registered user.

Returns:

Renders either the login template or redirects to the main index.

Return type:

str|Flask.Response

ResearchNotes.auth.load_logged_in_user()[source]

Before request function.

Loads the user data from the session cookie before a request. Will be needed for the user logic.

Return type:

None.

ResearchNotes.auth.logout() Response[source]

Logout current user.

Logs user out and closes the session (remove session cookie).

Returns:

Redirect to log-in view .

Return type:

Flask.Response

ResearchNotes.auth.login_required(view: Callable) Callable[source]

Check login decorator.

Decorator function that checks, if user is logged in. We can also use this later, if we create an admin group to give rights to groups or persons.

Parameters:

view (function) – View or function to be decorated.

Returns:

Returns decorated function or redirects to log-in screen.

Return type:

Callable|Flask.Response

ResearchNotes.auth.role_required(roles: list[str]) Callable[source]

Check rights decorator.

Decorator function that checks, if user is in the group to carry out a certain task.

Parameters:

roles (List) – List of roles that can access the view.

Returns:

The function the role_required decorator is applied to or redirect to log-in view.

Return type:

Callable|Flask.Response

ResearchNotes.cli module

Module to take command line instructions. We later register them as click commands.

This module should not contain any views or calls to web functions. For some reason, functions are not found by sphinx autodoc - most likely has to do with the cli.command decorator.

ResearchNotes.cli.check_datetime(obj: str) Union[str, datetime][source]

Convert a string to a datetime object. If fail (ValueError) return the string.

Parameters:

obj (str) – String to be converted should follow the fingerprint: “%a, %d %b %Y %H:%M:%S %Z”. This is the current format of a json dump

Returns:

If succeed, return the datetime object otherwise the original string

Return type:

str|datetime

ResearchNotes.documents module

All documentation related functions/views go here.

Basically, all the wiki functionality is defined here.

ResearchNotes.documents.create(label: List) Union[str, Response][source]

Create document entry.

We do a quick check, if document exist and in case do an internal server error abort (abort(500)).

Parameters:

label (List) – List containing the parent id (p_id) and the label of document (e_label).

Returns:

Redirects to document. show or shows the creation form.

Return type:

str, Flask.Response

ResearchNotes.documents.get_doc(label: str, check_author: bool = True) Documents[source]

Get a single Document (Wiki page) from the database.

Parameters:
  • label (Str) – Name of the document in the database.

  • check_author (TYPE, optional) – DESCRIPTION. The default is True.

Returns:

doc – Database entry of the document.

Return type:

Documents

ResearchNotes.documents.update(label: List) Union[str, Response][source]

Update document entry.

Parameters:

label (List) – List containing the parent id (p_id) and the label of document (e_label).

Returns:

Redirects to document. show or shows the creation form.

Return type:

str, Flask.Response

ResearchNotes.documents.show(label: str, check_author: bool = True) Union[str, Response][source]

Display as well as create documents.

If the document is not found but implemented as link in an existing document, we create it if first clicked.

Parameters:
  • label (str) – Label of the document to be shown (or None, if index).

  • check_author (bool, optional) – If ture access is checked. The default is True.

Returns:

Render a Documents class database entry.

Return type:

str|Flask.Response

ResearchNotes.documents.export_doc_text(doc: Documents) str[source]

Create a Markdown string for a document for later export.

Parameters:

doc (Documents) – Entry of Documents to create string for.

Returns:

Markdown string.

Return type:

str

ResearchNotes.documents.download(label: str) Response[source]

Download a given document as a Markdown text file.

This is a good way, e.g. for archiving it or sharing.

Parameters:

label (str) – Label of the document to download.

Returns:

Sends file as attachment to user.

Return type:

Flask.Response

ResearchNotes.documents.docs_tree() str[source]

Display the document tree, i.e. all documents linked to and below this document.

Returns:

Returns the document tree view for the group of the user.

Return type:

str

ResearchNotes.documents.remove_child(d_id: int) Response[source]

Remove a child from the child list, if there is more than one parent around.

This still can lead to orphans, but should minimize the risk.

Parameters:

d_id (int) – ID of the document to be removed. As parameter, we also have to pass the parent doc.id

Returns:

Redirect back to parent page.

Return type:

Flask.Response

ResearchNotes.documents.delete(label: str) Response[source]

Delete a document from the database.

The document to be deleted is not allowed to have any children to not create orphan pages that are not linked.

Parameters:

label (str) – Document label of document to be deleted.

Returns:

Redirect to ‘doc.index’

Return type:

Flask.Response

ResearchNotes.documents.last_updates() Documents[source]

Return the database records of the last updated documents.

Needed for the index page at sign in.

Returns:

Last five database entries of Documents ordered after update.

Return type:

Documents

ResearchNotes.entry module

Instrumentation Journal Entry submodule.

ResearchNotes.entry.show_all_entire() str | werkzeug.wrappers.response.Response[source]

Renders all Instrumentation Journal Entries of the group.

Returns:

Render template to show all entries.

Return type:

str | Response

ResearchNotes.entry.create_create_form(tid: int, iid: int, template=None)[source]

Create the create entry form.

Parameters:
  • tid (int) – Template ID to be used.

  • iid (int) – Instrument ID for which the template is used.

  • template (JEntry) – Data recortd to be filled. Default is None.

Returns:

The form object to be rendered later.

Return type:

WTForm

ResearchNotes.entry.htmx_fill_template(iid: int) str[source]

Htmx function to fill the template into the create form.

Parameters:

iid (int) – ID of the instrument the entry belongs to.

Returns:

HTML to be replaced in the frontend page.

Return type:

str

ResearchNotes.entry.create(ids: List) str | werkzeug.wrappers.response.Response[source]

Create a new instrumentation journal entry.

Parameters:

ids (List of the sample and template id)

Return type:

str or Response

ResearchNotes.entry.update(eid: int) str | werkzeug.wrappers.response.Response[source]

Update an instrumentation journal entry.

Parameters:

eid (int) – Instrumentation journal entry ID

Returns:

Render update form or redirect to measurement view.

Return type:

str | Flask.Response

ResearchNotes.entry.entry_view(eid: int) str | werkzeug.wrappers.response.Response[source]

Display an instrumentation journal entry and all associated files.

Parameters:

eid (int) – Instrumentation journal entry ID

Returns:

Renders template of the measurement view

Return type:

str or Response

ResearchNotes.entry.delete_iv(token: str)[source]

Delete an instrumentation journal entry and redirect to “instrument_view”.

Parameters:

token (str) – Signed string that encodes the id of the journal entry to delete

Returns:

Redirect to “instrument_view”

Return type:

Flask.Response

ResearchNotes.entry.delete_lv(token: str)[source]

Delete an instrumentation journal entry and redirect to “log_view”.

Parameters:

token (str) – Signed string that encodes the id of the journal entry to delete

Returns:

Redirect to “log_view”

Return type:

Flask.Response

ResearchNotes.entry.delete_entry_data(entry: InstrumentationJournalEntry) None[source]

Delete all data associated with an instrumentation journal entry.

This includes all files and the database object itself. This is done “silently” i.e. without flash() so it can also be used by the function that deletes instruments to delete all data of the entries associated with that instrument.

entry: entry whose data is deleted

ResearchNotes.entry.get_entry(eid: int, check_permission: bool = True) InstrumentationJournalEntry[source]

Retrieve an instrumentation journal entry by ID, optionally verifying permission.

Parameters:
  • eid (int) – database id of the measurement.

  • check_permission (bool, optional) – If true, we check for permission. The default is True.

Returns:

measurement – Loaded Measurement database entry.

Return type:

ResearchNotes.Measurement

ResearchNotes.error module

Module for all error handling.

All error handling is defined here as well as made sure, we log them into the app.logger facility.

ResearchNotes.error.badrequest_error(error: Union[str, HTTPException]) Union[Tuple[str, int], Response][source]

Error handler for bad request.

Provide an error handler for code 400 HTTPExceptions (Bad request)

Parameters:

error (TYPE) – DESCRIPTION.

Returns:

  • str – View to error page

  • int – HTTP error code.

ResearchNotes.error.forbidden_error(error: Union[str, HTTPException]) Union[Tuple[str, int], Response][source]

Error for not authorized for certain action.

Parameters:

error (str) – Error message from function calling the handler.

Returns:

  • str – View to error page

  • int – HTTP error code.

ResearchNotes.error.not_found_error(error: Union[str, HTTPException]) Union[Tuple[str, int], Response][source]

Errorhandler for page not found.

Parameters:

error (str) – Error message from function calling the handler.

Returns:

  • str – View to error page

  • int – HTTP error code.

ResearchNotes.error.too_large(error: Union[str, HTTPException]) Tuple[str, int][source]

Error handler for file to large (does not work well with dropzone.js).

Parameters:

error (str) – Error message from function calling the handler.

Returns:

  • str – View to error page

  • int – HTTP error code.

ResearchNotes.error.i_am_a_teapot(error: Union[str, HTTPException]) Union[Tuple[str, int], Response][source]

Errorhandler for “I am a teapot” status.

Parameters:

error (str) – Error message from function calling the handler.

Returns:

  • str – View to error page

  • int – HTTP error code.

ResearchNotes.error.internal_error(error: Union[str, HTTPException]) Union[Tuple[str, int], Response][source]

Errorhandler for internal errors.

Tries to rollback database, if possible.

Parameters:

error (str) – Error message from function calling the handler.

Returns:

  • str – View to error page

  • int – HTTP error code.

ResearchNotes.error.handle_exception(error: Union[str, Exception]) Union[HTTPException, Tuple[str, int], Response][source]

Errorhandler for all non HTTPExceptions.

Parameters:

error (Exception) – All exceptions go here and if they are not of the type HTTPExceptions will be handed here.

Returns:

Returns view to our internal error page.

Return type:

View

ResearchNotes.files module

File module.

All file functionality should go here. Deals with uploads and delivery of uploaded files.

ResearchNotes.files.validate_image(stream)[source]

Determine image extension from an upload stream.

Parameters:

stream (TYPE) – DESCRIPTION.

Returns:

DESCRIPTION.

Return type:

TYPE

ResearchNotes.files.uploaddir_path(info: List, only_sub_dir: bool = False) str[source]

Provide a string with the complete path to the ESS, PPM or report directory.

Parameters:
  • info (List) – [“s”, sample.id,sample.identifier] [‘m’,measurement.id, measurement.sample_id, measurement.measurement_sample.identifier] [‘r’,report.id, report.sample_id, report.reports_sample.identifier] [‘i’,instrument.id, instrument.identifier]

  • only_sub_dir (bool, optional) – Only return the subdirectories without the UPLOAD_DIR prefix The default is False.

Returns:

path – String containing the path to the ESS, PMM, or report. For the use in static only the sub-dirs starting from the UPLOAD_DIR can be given.

Return type:

str

ResearchNotes.files.make_file_list(path: str) list[str][source]

Make a list of the files in the directory and sort after extension.

Parameters:

path (str) – Path to the files. Normally comes from files.uploaddir_path.

Returns:

List of files in the path to be shown (and handed to preview).

Return type:

list[str]

ResearchNotes.files.make_image_url_list(path: str, prefix: str, img_1st: str = None, zip_files=False) list[str][source]

Creates a list of all image files in a given path and returns a preview url for it. :Parameters: * prefix (str) – Static file prefix to be given to the send_preview function.

  • path (str) – The real path to the files

  • img_1st (str (Optional)) – Name of an image file toi be sorted to the top of the list. Default is None.

  • zip_files (bool) – If true, zip files and url for later iteration. Default is False

Returns:

List of url to be given e.g. to send_preview to show the image.

Return type:

list[str]

ResearchNotes.files.async_tif_covert(tif_file: str) None[source]

Make a jpg file for a uploaded tif file.

Parameters:

tif_file (str) – File name

Return type:

None

ResearchNotes.files.upload_files(info: List) Response[source]

Upload files from user to Sample/Measurement/Report directory.

Responses are changed to work with dropzone. So, make_response is used and not abort.

Parameters:

info (List) – List of information needed, e.g. kind of directory (ESS, PPM, report) and ids etc.

Returns:

Redirect to view uploading the file.

Return type:

Flask.Response

ResearchNotes.files.upload_json() Response[source]

Upload a JSON file containing the information to create a sample.

Re-importing the JSOn that the export fucntion wrote. We do little checking and assume that the is not any bad data in the JSON. But the identifier does through secure_file and long description is treated by bleach.

Responses are changed to work with dropzone. So, make_response is used and not abort.

ResearchNotes.files.send_upload(info: List) Response[source]

Send uploaded file to user.

Parameters:

info (List) – List of information needed, e.g. kind of directory (ESS, PPM, report) and ids etc.

Returns:

Send the file as attachment to user.

Return type:

Flask.Response

ResearchNotes.files.send_preview(filename: str) Response[source]

Send a file in the upload directory.

For sending files in the UPLOAD dir, we implemented a send_file function that checks, if the user is signed in. Later, we could also restrict access too files to directories that the user has access. As dirs and filenames are hard to guess, we do not do this at the current state.

Due to the behavior of send_from_directory, we create first the full path and then split it into filename and directory. By adding UPLOAD dir as default, no files from other directories can be sent (path strings and filename are joined by saFe-Join to avoid dir escapes or directory transversal).

Parameters:

filename (str) – File name to the file to be sent as preview. Can include a path.

Returns:

File to be sent as preview. Normally, this should be an image to be displayed either in image preview or markup text.

Return type:

Flask.Response

ResearchNotes.files.delete_upload(info: List) Response[source]

Delete uploaded file.

Parameters:

info (List) – List of information needed, e.g. kind of directory (ESS, PPM, report) and ids etc.

Returns:

Go back to original view.

Return type:

Flask.Response

ResearchNotes.files.download(info: List) Response[source]

Download all files in a Sample/Measurement/Report directory uploaded before.

Function is broken and leads to time-out for large directories

Parameters:

info (List) – First entry defines the type (sample,measurement or report). The following members of the list are sample id and identifier as well as measurement id and report id, respectively.

Returns:

Sends zip file from directory.

Return type:

Flask.Response

ResearchNotes.files.redirect_to_view(view_type: str, vid: int)[source]

Create a return url depending on the type of directory or view.

Parameters:
  • view_type (str) – Denote the type of view to return to

  • vid (int) – ID of the view item to return to

Return type:

Response

ResearchNotes.htmx module

ResearchNotes.instruments module

ResearchNotes.inventory module

ResearchNotes.locations module

Location management modul.

Everything for locations and sub-location management goes here.

ResearchNotes.locations.register_parent_location() str | werkzeug.wrappers.response.Response[source]

Register a new location.

Return type:

str|Response

ResearchNotes.locations.update_parent_location(pl_id: int) str | werkzeug.wrappers.response.Response[source]

Update a parent location name.

Return type:

str|Response

ResearchNotes.locations.htmx_delete_parent_location(token: str) str[source]

Delete a parent location.

On delete, we will move all the sub-locations to ‘Not defined’ leaving the rest untouched.

Parameters:

token (str) – Signed string that encodes the id of the location to delete

Returns:

Rendered location page.

Return type:

str

ResearchNotes.locations.register_location(pl_id: int) Union[str, Response][source]

Register a new location.

Return type:

str|Response

ResearchNotes.locations.update_location(lid: int) str | werkzeug.wrappers.response.Response[source]

Update a location name.

Parameters:

lid (int) – Location ID to change name for.

Return type:

str|Response

ResearchNotes.locations.htmx_move_sublocation(info: list[int]) str[source]

Move location to new parent location and update location list.

Parameters:

info (list[int]) – Sub-location and location ID

Returns:

Rendered location list

Return type:

str

ResearchNotes.locations.htmx_delete_location(token: str) str[source]

Delete a location where ess, or instrument are stored.

On delete, we will move all the ess or instruments connected with the location to the None of the parent location.

Parameters:

token (str) – Signed string that encodes the id of the location to delete

Returns:

Rendered location page.

Return type:

str

ResearchNotes.main module

ResearchNotes.measurement module

ResearchNotes.notification module

Notification modul.

If we do some real time notification, everything should go here. By now, we just did a first testing by implementing a test view to return a random dict and a test_view using brython to refresh a message every 10 sec.

ResearchNotes.notification.test() Dict[str, str][source]
ResearchNotes.notification.test_view() str[source]

ResearchNotes.preview module

ResearchNotes.report module

Report module.

All functions/views dealing with report. Defines the report blueprint

ResearchNotes.report.create(mid: int) Union[str, Response][source]

Create a report in a given PMM for the PMM id.

Parameters:

mid (int) – PPM ID for which the report is created.

Returns:

Render create report template or redirect to report view.

Return type:

str|Flask.Response

ResearchNotes.report.get_report(rid: int, check_author: bool = True) Reports[source]

Get report from database.

Retrieve report ID from database. Check, if user has the right to access the database entry first

Parameters:
  • rid (int) – Report ID in database.

  • check_author (TYPE, optional) – DESCRIPTION. The default is True.

Returns:

report – Report entry into database.

Return type:

ResearchNotes.Report

ResearchNotes.report.update(rid: int) Union[str, Response][source]

Update an existing report in the database.

First retrieve it, then put the old values into the Form. Finally, write new values to the database and update modified date.

Parameters:

rid (int) – Report ID.

Returns:

Render update form or redirect to report view.

Return type:

str|Flask.Response

ResearchNotes.report.report_view(rid: int) str[source]

Display report and associated files.

Parameters:

rid (int) – Report ID

Returns:

Renders report view template.

Return type:

str

ResearchNotes.report.delete(token: str) Response[source]

Delete report entry.

Unlike samples, we have don’t have to implement a cascade of deletions and cross-references since there are no “one report to many” database relationships.

Parameters:

token (str) – Signed string that encodes the id of the report to delete

Returns:

Redirect to measurement view (if _delete not does an abort).

Return type:

Flask.Response

ResearchNotes.rn_class module

class ResearchNotes.rn_class.RNFlask(name, **kwargs)[source]

Bases: Flask

ResearchNotes.samples module

ResearchNotes.search module

Implementation of full text search using Elasticsearch or Meilisearch.

The Elasticsearch API is still for python 7.17. There seems to be some change for version 8.0 on.

ResearchNotes.search.add_to_index(index: str, model) None[source]

Add entries to search index.

Add the fields marked in __searchable__ to the elasticsearch index.

Parameters:
  • index (str) – Index name

  • model (db.Model)

Return type:

None

ResearchNotes.search.remove_from_index(index: str, model) None[source]

Remove entry from index.

This seems not to work in our test case

Parameters:
  • index (str) – Index name

  • model (db.Model)

Return type:

None

ResearchNotes.search.delete_index(index: str) None[source]

Delete search index.

Parameters:

index (str) – Index name.

Return type:

None

ResearchNotes.search.create_index(index: str) None[source]

Create the search index.

Parameters:

index (str) – UID of the index to be created.

ResearchNotes.search.query_index(index: str, query: str) Tuple[List[int], int][source]

Search string in index.

Searches the query term inside the index. We get a despondency warning and have to redo the command. We have to read the search API of the elasticsearch module. We will have problems from version 8 on.

Parameters:
  • index (str) – Index name

  • query (str) – Search term (we might want to rename this).

Returns:

  • ids (List[int]) – Found document ids.

  • number of hits (int) – Number of found entries.

ResearchNotes.setup module

ResearchNotes.template module

ResearchNotes.test module

Platyground to find some stuff out

ResearchNotes.test.index() str[source]

ResearchNotes.type_management module

Module dealing with the entry types - might be merged to entry.py

ResearchNotes.type_management.create_etype(iid: int) str | werkzeug.wrappers.response.Response[source]

Register a new instrumentation journal entry type.

Parameters:

iid (int) – ID of the instrument that the journal entry type is associated with

Return type:

str|Response

ResearchNotes.type_management.update_etype(etid: int) Union[str, Response][source]

Update an existing instrumentation journal entry type.

Parameters:

etid (int) – EntryType ID to update.

Return type:

str|Response

ResearchNotes.type_management.delete_etype(token: str) Response[source]

Delete a location where samples are stored.

Parameters:

token (str) – Signed string that encodes the id of entry type to delete

Returns:

Redirect to instrument view

Return type:

Flask.Response

ResearchNotes.type_management.register_type() Union[str, Response][source]

Register a new measurement type.

Return type:

str|Response

ResearchNotes.type_management.update_type(mtype_id: int) Union[str, Response][source]

Update a measurement type name.

Parameters:

mtype_id (int) – MeasurementType ID to change name for.

Return type:

str|Response

ResearchNotes.type_management.delete_type(token: str) Response[source]

Delete a type of measurement.

Parameters:

token (str) – Signed string that encodes the id of the type of measurement to delete

Returns:

Redirect to admin settings page

Return type:

Flask.Response

ResearchNotes.type_management.register_itype() Union[str, Response][source]

Register a new measurement type.

Return type:

str|Response

ResearchNotes.type_management.update_itype(it_id: int) str | werkzeug.wrappers.response.Response[source]

Update an item type.

Return type:

str|Response

ResearchNotes.type_management.htmx_delete_itype(token: str) str[source]

Delete an item type.

Parameters:

token (str) – Signed string that encodes the id of the type of measurement to delete

Returns:

Render item type list

Return type:

str

ResearchNotes.url_security module

Module to deal with url security or other security related stuff.

Module for improving security against cross-site request forgery (CSRF) attacks. This is done by encoding the URLs with a security key (“SEC_SESSION_KEY” from the app_configuration module) and salting a string unique to que current login session.

ResearchNotes.url_security.token_encode(plain: Any, salt: str, secret_key: str) Union[str, bytes][source]

Encode obj with session salt.

Encodes a plain text string using a secret key and a salt unique to the current login session (same as the decoder)

Parameters:
  • plain (Any) – Plain text string

  • salt (Union[Iterable[Union[str, bytes]]) – Salt unique to the current login session, default = g.salt

  • secret_key (Union[Iterable[Union[str, bytes]]) – Secret key, default = current_app.config[“SEC_SESSION_KEY”]

Returns:

An encoded string

Return type:

str

ResearchNotes.url_security.token_decode(signed: str, salt: str, secret_key: str) Any[source]

Decode string with session salt.

Decodes a signed string using a secret key and a salt unique to the current login session (same as the encoder)

Parameters:
  • signed (str) – Encoded string

  • salt (str) – Salt unique to the current login session, default = g.salt

  • secret_key (str) – Secret key, default = current_app.config[“SEC_SESSION_KEY”]

Returns:

A decoded string

Return type:

Any

ResearchNotes.url_security.safe_url_for(token: Any, endpoint: str, secret_key: str, salt: str) str[source]

Save url generator.

Generates URLs in a similar manner to Flask’s built-in url_for() function, but it encodes its keyword arguments to make them harder to guess for an attacker.

Parameters:
  • token (Any) – Object to encode

  • endpoint (str) – Name of the view to be called. It has to take a str (token) as argument.

  • secret_key (Union[Iterable[Union[str, bytes]]) – Secret key for encoding. To be passed for token_encode.

  • salt (Union[Iterable[Union[str, bytes]]) – Salt for encoding. To be passed for token_encode.

Returns:

A safe URL for the given endpoint and token.

Return type:

str

Example

In the html you call save_url_for as filter

{{obj | save_url_view(view)}}

the view needs to have the signature:

@rout(view/string:token)

def view(token):

obj = token_decode(token,…)

ResearchNotes.util module

ResearchNotes.well_known module

Well_known module of the program.

Defines some .well_known URLs and redirects to some other views.

ResearchNotes.well_known.change_password() Response[source]

Redirects to password change view.