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 = ({'.txt', '.pdf', '.jpeg', '.png', '.jpg', '.gif'},)
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() Union[str, 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)[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])[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.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 viw.

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

Module to have all htmx function that are not specific to a view or page and can be recycled for different things.

ResearchNotes.htmx.htmx_image_files(info: list) str[source]

Htmx function that renders and returns the modal dialog to show associated files.

Parameters:

info (list) – Info dict for the directory to show.

Returns:

Rendered content of the modal dialog.

Return type:

str

ResearchNotes.htmx.htmx_markdown_help() str[source]

Renders the Markdown help modal.

We read the markdown help from the markdown_help.txt file. This can/should contain a Markdown text that we want to show. We use our markdown|safe filter to display.

Returns:

Rendered content of the modal (markdown).

Return type:

str

ResearchNotes.htmx.htmx_redo_files(info: list) str[source]

Recreate file list in associated files area.

Parameters:

info (dict) – Information of the directory

Returns:

Rendered file list to be put into the html document body.

Return type:

str

ResearchNotes.htmx.htmx_delete_file(info: list) str[source]

Use htmx to delete an uploaded file.

Parameters:

info (list) – Information of the path for file

Returns:

Rendered new file list to be replaced in body.

Return type:

str

ResearchNotes.htmx.htmx_choose_parent_location(lid: int) str[source]

Make the Modal dialog that allows to choose the new parent location for a sub-location.

Parameters:

lid (int) – Location ID to move.

Returns:

Rendered dialog.

Return type:

str

ResearchNotes.htmx.htmx_choose_ess(tid: int)[source]

Provides the modal dialog to choose a sample for a measurement in the instrumentation and journal entry view.

Parameters:

tid (int) – Template ID to be used for the PPM.

ResearchNotes.htmx.htmx_upload_json()[source]

ResearchNotes.instruments module

Instrument submodule.

Everything regarding the instruments is done here.

ResearchNotes.instruments.index() str[source]

Index view for the instrument part.

Show five most recently updated owned instruments and shared instruments

Returns:

Render index template.

Return type:

str

ResearchNotes.instruments.template_index() str[source]

Index view for the instrument templates.

Show five most recently updated owned instruments and shared instruments

Returns:

Render index template.

Return type:

str

ResearchNotes.instruments.log_view(iid: int) str[source]

Shows all the log entries for an instrument.

Parameters:

iid (int) – Instrumentation identifier

Returns:

Log_view

Return type:

str|Response

ResearchNotes.instruments.make_create_form(tid: int, group_id: int, current_location_id: int | None = None, template=None)[source]

Fill the create form for new instrument fom.

Parameters:
  • tid (int) – Template ID to be used in the create form

  • group_id (int) – Group ID of user to select locations.

  • current_location_id (int |None) – Current location ID, if it should be excluded from choices.

  • template (Instrument) – Data record used to fill form. Default None

Returns:

The filled WTForm object to be rendered later.

Return type:

WTForm

ResearchNotes.instruments.htmx_fill_create_template() str[source]

Htmx rout that puts a new template data into the create form.

Returns:

Filled and rendered form to replace old form in page.

Return type:

str

ResearchNotes.instruments.create(tid: int) Union[str, Response][source]

Create new instrument entry.

Parameters:

tid (int) – Template to be used for create dialog (default is 0 - None used)

Returns:

Renders create instrument form or instrument view.

Return type:

str|Response

ResearchNotes.instruments.update(iid: int) Union[str, Response][source]

Update instrument information.

We also have to rename the instrument directory, if it already exits.

Parameters:

iid (Integer) – Instrument ID to update.

Returns:

Renders either form or redirects to the instrument entry.

Return type:

str|Flask.Response

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

Delete an instrument.

Delete all data related to an instrument, including all its files and all its journal entries (as well as the files of those entries)

Parameters:

token (str) – Encrypted ID of instrument to delete

Returns:

Redirects to instrument view

Return type:

Response

ResearchNotes.instruments.delete_instrument_data(instrument: Instrument) None[source]

Delete all data directly associated with an instrument.

This includes all files and the database object itself, but it does not include any data associated with the instrument’s journal entries.

Parameters:

instrument (Instrument.) – Instrument database record, whose data is deleted

Return type:

None

ResearchNotes.instruments.deactivate(iid: int) Response[source]

Deactivate an instrument.

Parameters:

iid (Integer) – Instrument ID to deactivate.

Returns:

Redirects to instrument view.

Return type:

Flask.Response

ResearchNotes.instruments.activate(iid: int) Response[source]

Activate an instrument.

Parameters:

iid (Integer) – Instrument ID to activate.

Returns:

Redirects to instrument view.

Return type:

Flask.Response

ResearchNotes.instruments.create_default_template_form(user_id: int, instrument: Instrument)[source]

Fills in the form to choose the default templates for an instrument.

Parameters:
  • user_id (int) – User ID of the active user

  • instrument (Instrument) – Record for instrument to choose the default templates for

Returns:

Filled WFTForm object that will be rendered in the html later

Return type:

WTForm

ResearchNotes.instruments.htmx_instrument_template(iid: int) str[source]

Htmx sniplet that will save the chosen default template and render the form.

Parameters:

iid (int) – ID of the instrument data record.

Returns:

Rendered html form to be swapped in the form.

Return type:

str

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

Show single instrument entry.

Parameters:

iid (int) – ID of Instrument to show.

Returns:

Flask view of the instrument.

Return type:

str|Flask.Response

ResearchNotes.instruments.unshare(ids) Response[source]

Unshare an instrument with a user (only possible for group member).

Parameters:

ids (list[int]) – Instrument ID and User ID to unshare.

Returns:

Flask redirect.

Return type:

Flask.Response

ResearchNotes.instruments.get_instrument(iid: int, authenticate: bool = True) Instrument[source]

Get instrument by ID and check permission to act on it.

Parameters:
  • iid (Integer) – Instrument ID.

  • authenticate (bool, optional) – Whether to check for permission or not. The default is True.

Returns:

instrument – Entry for Instrument in database.

Return type:

ResearchNotes.Instrument

ResearchNotes.inventory module

Inventory modul

The place to manage your items and inventory of the group. Allows to track, what is in stock and how is using it.

At special request of F. Barabosa.

ResearchNotes.inventory.index() str[source]

Render the index inventory view

ResearchNotes.inventory.itemtypes() str[source]

Render the overview of item types.

ResearchNotes.inventory.create_form(tid: int, group_id: int, current_location_id: int | None = None, template=None)[source]

Fill the create form for new item fom.

Parameters:
  • tid (int) – Template ID to be used in the create form

  • group_id (int) – Group ID of user to select locations.

  • current_location_id (int |None) – Current location ID, if it should be excluded from choices.

  • template (Item) – Data record used to fill form. Default None.

Returns:

The filled WTForm object to be rendered later.

Return type:

WTForm

ResearchNotes.inventory.htmx_fill_template() str[source]

Htmx sniplet that will fill the template into the form and send it back.

Returns:

Rendered HTML form (with template filled).

Return type:

str

ResearchNotes.inventory.create_item(tid: int) str | werkzeug.wrappers.response.Response[source]

Create a new item in the inventroy.

Parameters:

tid (int) – ID of the template to use.

Returns:

Either rendered form or Response (redirect to created item).

Return type:

str|Response

ResearchNotes.inventory.get_item(iid: int, check_author=True) Items[source]

Load item from database and check rights to access it.

Parameters:
  • iid (int) – Item ID

  • check_author (bool) – Check authorization to access. DEFAULT is True.

Returns:

Item entry to be accessed or abort

Return type:

Items

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

Update the information for an item in the inventory.

Parameters:

iid (int) – Item ID.

Returns:

Render template or redirect to item.

Return type:

str|response

ResearchNotes.inventory.item_view(iid: int) str[source]

Render the item view with all item information.

Parameters:

iid (int) – Item ID

Returns:

Rendered ITEM view.

Return type:

str

ResearchNotes.inventory.delete_item(token: str) Response[source]

View for deleting an item from inventory.

You need to be supervisor or StudentAdmin to call the view.

Parameters:

token (str) – Secure token encoding the itme ID.

Returns:

Redirect to inventory.index view.

Return type:

Response

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

Htmx function to check out an item from the inventory.

Parameters:

iid (int) – Item ID to check out.

Returns:

Render check out form and redirects to index view.

Return type:

str|Response

ResearchNotes.inventory.htmx_return_item_completly(iid: int) str[source]

Htmx function to return all checked out items by a user to be used by supervisor or admin.

Parameters:

iid (int) – Item ID.

Returns:

Rerendered item list to be displayed by htmx in item view.

Return type:

str

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

Htmx function to return items to inventory.

Parameters:

iid (int) – Item ID.

Returns:

Return form rendered by htmx into modal. Either part to render or redirect to page.

Return type:

str|Response

ResearchNotes.inventory.item_templates() str[source]

Top view for all itme templates.

Returns:

Rendered view of the item templates of the group.

Return type:

str

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

Main module of the program.

Basically just contains the index html view that it does not be defined in the __init__ part. Also, we can later put other views here that are not related to any sub-menu or other module.

ResearchNotes.main.index() str[source]

View showing the last samples and main page.

Returns:

Renders the index page.

Return type:

str

ResearchNotes.main.favicon() Response[source]

Fix favicon 403 error.

Returns the favicon for browser that ignore the template or if back bottom is hit. Otherwise, we will have a lot of 404 errors over the log filers, if someone hits the back bottom.

Returns:

Favicon file to be shown.

Return type:

Flask.Response

ResearchNotes.main.lab_book() Response[source]

Create a “lab book” of all entries of user and download as Markdown file.

The file will be created in the upload directory for the user specific name. We might need to do some cleaning form time to time.

Returns:

Markdown-file to download

Return type:

Response

ResearchNotes.main.search() Union[str, Response][source]

Display the result of the search.

Return type:

str|Response

ResearchNotes.measurement module

Measurements submodule.

Everything for the P/P/M part will go here.

ResearchNotes.measurement.create_form(tid: int, group_id: int)[source]

Fills the create form for a new measurement.

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

  • group_id (int) – Group_id of the user (containing all the measurement types to fill).

Returns:

The created form object to be used in the html template.

Return type:

WTForm object

ResearchNotes.measurement.htmx_fill_template() str[source]

Htmx sniplet that will fill the template into the form and send it back.

Returns:

Rendered HTML form (with template filled).

Return type:

str

ResearchNotes.measurement.create(ids: List) Union[str, Response][source]

Create a new measurement database entry.

Parameters:

ids (List of the sample and template id) – DESCRIPTION.

Returns:

DESCRIPTION.

Return type:

TYPE

ResearchNotes.measurement.get_measurement(mid: int, check_author: bool = True) Measurements[source]

Retrieve a given measurement from the database checking the permission of the user before.

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

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

Returns:

measurement – Loaded Measurement database entry.

Return type:

ResearchNotes.Measurement

ResearchNotes.measurement.update(mid: int) Union[str, Response][source]

Update a measurement entry of the database.

Therefore, we get the measurement and fill the form with the required entries.

Actually, the measurement typ gets lost.

Parameters:

mid (int) – Measurement ID in database.

Returns:

Render update form or redirect to measurement view.

Return type:

str|Flask.Response

ResearchNotes.measurement.measurement_view(mid: int) str[source]

Display a measurement and all associated files.

Parameters:

mid (int) – Measurement ID.

Returns:

Renders template of the measurement view.

Return type:

str

ResearchNotes.measurement.allmeasurements() str[source]

Show all measurements of created by user included for shared samples.

Returns:

Renders all measurement template.

Return type:

str

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

Delete measurement.

Like for the samples, we have to implement a cascade of deletions and cross-references. In this case, first we delete all reports associated with the measurement, then we delete the measurement itself.

Parameters:

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

Returns:

Redirects to the view of the sample that contained the measurement

Return type:

Flask.Response

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

E/S/S or sample submodule.

Everything regarding the samples, experiments or simulations is done here.

ResearchNotes.samples.index() str[source]

Index view for the E/S/S part.

Base function showing the last 5 updated samples, last 5 updated PPM and last 5 reports

Returns:

Render index template.

Return type:

str

ResearchNotes.samples.template_index() str[source]

Index view for the E/S/S and P/P/M templates.

Returns:

Render index template.

Return type:

str

ResearchNotes.samples.groupsamples() str[source]

Show all ESS of the group.

Returns:

Renders template of the group view.

Return type:

str

ResearchNotes.samples.allsamples() str[source]

Show all samples of user.

Returns:

Calls render_template for the all sample view (which returns a str).

Return type:

str

ResearchNotes.samples.allsharedsamples() str[source]

Show all samples shared with and by user.

Returns:

Render allsharedsamples template.

Return type:

str

ResearchNotes.samples.htmx_fill_template()[source]

htmx route that puts the chosen template into the form.

We get the content of the choose_form and load the according template. Then the main form is rendered again and htmx will put the newly rendered form into the main form.

We use a put command and therefore have not anymore to POST commands in the form. Also,the form is not reloaded anymore.

Returns:

Newly filled form that is put into the place of the old form.

Return type:

str

ResearchNotes.samples.create(tid: int) Union[str, Response][source]

Create new sample entry. One can choose a template from the top menu.

Returns:

Renders create sample template or redirects to sample_view view.

Return type:

str|Response

ResearchNotes.samples.get_sample(sid: int, check_author: bool = True) Samples[source]

Get sample id and check permission to act on sample.

Parameters:
  • sid (Integer) – Sample ID.

  • check_author (bol, optional) – Whether to check for permission or not. The default is True.

Returns:

sample – Entry for Sample in database.

Return type:

ResearchNotes.Sample

ResearchNotes.samples.update(sid: int) Union[str, Response][source]

Update sample information.

We also have to rename the sample directory, if it already exits.

Parameters:

sid (Integer) – Sample ID to update.

Returns:

Renders either form or redirects to the sample entry.

Return type:

str|Flask.Response

ResearchNotes.samples.make_share_list(user_id: int, sample_share_list: list[int]) dict[slice(<class 'str'>, list[tuple[int, str]], None)][source]

Create the list of user a sample can be shared out.

Parameters:
  • user_id (int) – User ID of current user (to be excluded in list)

  • sample_share_list (list[int]) – List of User IDs the sample is shared with.

Returns:

dict[str – Dict with list per group of possible users to share.

Return type:

list[tuple[int,str]]

ResearchNotes.samples.htmx_update_location(sid: int) Response[source]

Updates the sample location and renders the sample header again.

We will update the sample location and render the sample header again. We also send a trigger to render the ESS location form again.

Parameters:

sid (int) – Sample ID

Returns:

The rendered part of the header for the sample information.

Return type:

str

ResearchNotes.samples.htmx_sample_location_form(sid: int) str[source]

Htmx route that updates the location form after location change.

Parameters:

sid (int) – Sample ID which location needs updating.

Returns:

Rendered location form to be put into DOM.

Return type:

str

ResearchNotes.samples.sample_view(sid: int) Union[str, Response][source]

Show single sample entry.

Parameters:

sid (int) – Sample id to show.

Returns:

Flask view of the sample.

Return type:

str|Flask.Response

ResearchNotes.samples.removeshare(ids: List) Response[source]

Remove the share between sample and user (only possible for owner).

Parameters:

ids (list[int]) – List of sample and user id.

Returns:

Flask redirect.

Return type:

Flask.Response

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

Delete a sample.

We need to define cascade of deleting things in the right order. Hence, we will first delete all reports (and files associated), then all measurements and finally the sample (and all its files).

Parameters:

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

Returns:

Redirects to the index vies of the ESS module.

Return type:

Response

ResearchNotes.samples.sample_summery(sample: Samples) str[source]

Create a summery Markdown string for all information in the database.

Parameters:

sample (ResearchNotes.Samples) – Entry of sample to summarize

Returns:

  • str

  • Markdown formatted string of sample entry.

ResearchNotes.samples.summery(sid: int) Response[source]

Make a .md file of a sample entry.

Create a database dump of all entries for a given sample as well as attached measurements and reports. Everything is written into a markdown file, which can then be downloaded to create a backup of the information.

Parameters:

sid (int) – Sample id of sample to be exported.

Returns:

Redirect to sample view

Return type:

Flask.Response

ResearchNotes.samples.htmx_export_json(sid: int) Response[source]

Export a ESS record together with all PPMs and reports to a json file for later import.

Parameters:

sid (int) – ESS id

Returns:

send_file_from directory as attachment.

Return type:

Response

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

User and app configuration module.

Everything for setup, configuration and user handling is here. Big parts are only for the admin.

We do creation of groups are here as well (for supervisors and admins).

Some management stuff like mtype registration and location registration/management is done over the index page.

ResearchNotes.setup.resetpassword(token: str) str | werkzeug.wrappers.response.Response[source]

Reset the password of a user.

Parameters:

token (str) – Crypto token for user ID.

Returns:

Either the form or redirect to the config main page.

Return type:

str | Response

ResearchNotes.setup.index() str[source]

Overview of configuration - mainly for admins.

ResearchNotes.setup.user_info(uid) str[source]

Return view to show some user info and statistic.

Returns:

Returns flask view to user info.

Return type:

str

ResearchNotes.setup.changepasswd() Union[str, Response][source]

Change your password.

ResearchNotes.setup.app_info() str[source]

Return view to show some user info and statistic.

Returns:

Returns flask view to user info.

Return type:

View

ResearchNotes.setup.user_mangement() str[source]

User management view.

ResearchNotes.setup.group_mangement() str[source]

Group management view.

ResearchNotes.setup.register() Union[str, Response][source]

Register a new user.

Currently, only admin or supervisors can register or edit users.

Returns:

Returns view to ‘conf.index’ or for form.

Return type:

View

ResearchNotes.setup.update(uid) Union[str, Response][source]

Update a user record.

We get the user record from the database and fill the UserEdit form with it.

Needs admin rights.

Parameters:

uid (int) – User ID of user to update.

Returns:

Render the update page or redirect to user view.

Return type:

str|Response

ResearchNotes.setup.deactivate_user(token: str) Response[source]

Deactivates the user and shares all his samples with the Supervisor(s) of the group.

If no supervisor exists, we will share samples with user id 1, which is an admin.

Parameters:

token (str) – Token for User to deactivate.

Returns:

DESCRIPTION.

Return type:

Response

ResearchNotes.setup.register_group() Union[str, Response][source]

Register new research group.

ResearchNotes.setup.update_group(gid: int) Union[str, Response][source]

Update research group name.

Parameters:

gid (int) – ID ofd group to update.

Returns:

Render template or redirect to index.

Return type:

str|Response

ResearchNotes.setup.delete_group(token: str) Response[source]

Delete a group.

Does not delete the users within, only the group itself. hence, all ESS, PPM and report now belong to orphan group_id.

Parameters:

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

Returns:

Redirect to admin settings page

Return type:

Flask.Response

ResearchNotes.template module

All template related functions/views go here.

Templates are easy ways to create new E/S/S, P/P/M or report entries following a certain style (e.g. having pre-defined tables for data insertion etc.).

ResearchNotes.template.index() str[source]

Index page of the templates for ESSs or PMMs.

List all templates available for user.

Returns:

Renders index template.

Return type:

str

ResearchNotes.template.create_template_from_sample(s_id: int) Response[source]

Create a tem,plate from an existing database entry.

Either Sample or Measurement depending on what was given.

Parameters:

s_id (int) – Sample ID to be used as template.

Returns:

Redirects to template creation form using the information provided to prefill form.

Return type:

Flask.Response

ResearchNotes.template.use_sample_temp() Union[str, Response][source]

Use ESS template for creation of new ESS.

Returns:

Renders template selection form or redirects to the creation form.

Return type:

str,Flask Response

ResearchNotes.template.create_sample_template(tid: int) Union[str, Response][source]

Create new template entry, if not exists. If exits use it to edit it.

Parameters:

tid (int) – Information what kind of template to create and ids.

Returns:

Render template create form or redirect to template view.

Return type:

str/ Flask.Response

ResearchNotes.template.delete_sample_template(token: str) Response[source]

Delete a template from the template database.

Parameters:

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

Returns:

Redirect to template.index.

Return type:

Flask.Response

ResearchNotes.template.create_template_from_measurement(m_id: int) Response[source]

Create a template from an existing database entry.

Parameters:

m_id (int) – Measurement ID to create template from.

Returns:

Redirects to template creation form using the information provided to prefill form.

Return type:

Flask.Response

ResearchNotes.template.use_measurement_temp(s_id: int) Union[str, Response][source]

Use template for creation of new entity.

Function to let you choose the template to be used to create a PPM.

Parameters:

s_id (int) – Sample ID to base PPM template on (needed for redirect to PPM view back).

Returns:

Renders template selection form or redirects to the creation form.

Return type:

str,Flask Response

ResearchNotes.template.delete_measurement_template(token: str) Response[source]

Delete a template from the template database.

Parameters:

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

Returns:

Redirect to template.index.

Return type:

Flask.Response

ResearchNotes.template.create_measurement_template(tid: int) Union[str, Response][source]

Create new template entry, if not exists. If exits use it to edit it.

Parameters:

tid (int) – Information what kind of template to create and ids.

Returns:

Render template create form or redirect to template view.

Return type:

str/ Flask.Response

ResearchNotes.template.create_template_from_instrument(iid: int) Response[source]

Create a template from an existing database entry.

Parameters:

iid (int) – Instrument ID to be used as template.

Returns:

Redirects to template creation form using the information provided to prefill form.

Return type:

Flask.Response

ResearchNotes.template.delete_instrument_template(token: str) Response[source]

Delete an instrument template from the template database.

Parameters:

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

Returns:

Redirect to template.index.

Return type:

Flask.Response

ResearchNotes.template.create_instrument_template(tid: int) str | werkzeug.wrappers.response.Response[source]

Create new template entry if it doesn’t exist or updated if it does.

Parameters:

tid (int) – Information what kind of template to create and ids.

Returns:

Render template create form or redirect to template view.

Return type:

str/ Flask.Response

ResearchNotes.template.create_template_from_entry(eid: int) Response[source]

Create a template from an existing instrumentation journal entry

Parameters:

eid (int) – ID of Instrumentation Journal Entry to be used as template

Returns:

Redirects to template creation form using the information provided to prefill form

Return type:

Flask.Response

ResearchNotes.template.delete_entry_template(token: str) Response[source]

Delete an instrumentation journal entry template

Parameters:

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

Returns:

Redirect to template.index.

Return type:

Flask.Response

ResearchNotes.template.create_entry_template(tid: int) str | werkzeug.wrappers.response.Response[source]

Create new template entry; if it doesn’t exist or updated if it does.

Parameters:

tid (int) – Information what kind of template to create and ids.

Returns:

Render template create form or redirect to template view.

Return type:

str/ Flask.Response

ResearchNotes.template.create_template_from_item(iid: int) Response[source]

Create a template from an existing instrumentation journal entry

Parameters:

iid (int) – ID of Instrumentation Journal Entry to be used as template

Returns:

Redirects to template creation form using the information provided to prefill form

Return type:

Response

ResearchNotes.template.delete_item_template(token: str) Response[source]

Delete an item template from the template database.

Parameters:

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

Returns:

Redirect to template.index.

Return type:

Flask.Response

ResearchNotes.template.create_item_template(tid: int) str | werkzeug.wrappers.response.Response[source]

Create new item template; if it doesn’t exist or updated if it does.

Parameters:

tid (int) – Information what kind of template to create and ids.

Returns:

Render template create form or redirect to template view.

Return type:

str/ Flask.Response

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

All helpful utils go here. Mainly carrying for the markdown stuff.

  • Define um url converter for lists

  • Define Markdown filter and handling of flatpages

  • Define markdown template filter

class ResearchNotes.util.ListConverter(map: Map, *args: t.Any, **kwargs: t.Any)[source]

Bases: BaseConverter

Class for passing a list when calling a page.

Used to pass a lot of the parameters.

to_python(value: str) Any[source]

Convert the list into url parameters passed to the view.

Parameters:

value (str) – URL save string of list.

Returns:

Decoded list from input string.

Return type:

list

to_url(values: List) str[source]

Convert or list from url back to python list.

Parameters:

values (List) – Obj to be encoded.

Returns:

Encoded list in URL save str form.

Return type:

str

ResearchNotes.util.markdown_render(markdown_text: str) str[source]

Markdown-renderer for Flatpages plugin.

Defines a markdown render function to be used to show part of the text. Used by samples, measurements and reports html pages

Parameters:

markdown_text (String) – Input text in Markdown format.

Returns:

Renders the Markdown text into HTML with table extension enabled.

Return type:

str

ResearchNotes.util.fpages(path: str) str[source]

Call the static pages over flask-flatpages.

Parameters:

path (str) – path to flat page.

Returns:

Renders the static page in the page directory in the flatpages template.

Return type:

str

ResearchNotes.util.doc_url(label: str, base, end) str[source]

Define our own url handler for the wiki pages.

The function has to have this signature with in our case two unused keywords.

Parameters:
  • label (str) – Document label.

  • base (str) – Not use but required by func signature.

  • end (str) – Not use but required by func signature.

Returns:

Url for document view of a Wiki link depending on from where it comes.

Return type:

str

ResearchNotes.util.markdown_filter(markdown_text: str) str[source]

Define our markdown filter to show things.

These needs our defined url_doc handler

Filter is used in all moduls to show the markdown (ESS, PPM, reports and documents)

Parameters:

markdown_text (str) – Markdown text - normally coming from the database and containing the long description of the item.

Returns:

HTML rendered text from the markdown input. Cleaned by bleach as this is user provided input.

Return type:

str

ResearchNotes.util.suggest_passwd() str[source]

Suggested a strong password randomly picking 4 words from a word list with more than 7000 entries.

ResearchNotes.util.make_location_list(group_id: int, current_location_id: int | None) dict[slice(<class 'str'>, list[tuple[int, str]], None)][source]

Create a list of possible locations for Location choose select.

Parameters:
  • group_id (int) – Group ID of the active user.

  • sample_location_id (int) – ID of the current location.

Returns:

dict[str – The list of options to be put into the select form.

Return type:

list[tuple[int, str]]]

ResearchNotes.util.create_template_choose_form(table: Model, user_id: int) UseTemplate[source]

Creates the choose form and returns.

Parameters:
  • table (db.Model) – Tabel of the templates, we want to use.

  • user_id (int) – User ID whose templates we want to use

Returns:

Form – Form to be rendered.

Return type:

WTFForm

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.