Models¶
Module contents¶
Submodules¶
dashboard.models.emails module¶
Email notifications sent from models.py
Email functions used by models are likely to be submitted to the scheduler and so special care should be taken to ensure their input arguments are always JSON serializable types (see here for info on serializable types: https://docs.python.org/3/library/json.html#json.JSONEncoder).
Additionally, because these functions are needed within models.py, you can’t query the database within an email function without risking circular import issues. Any info needed to generate the email should therefore be provided as an argument when the function is called.
- dashboard.models.emails.account_activation_email(oauth_uname, user_email, num_studies)¶
Notify a user that their dashboard access has been approved.
- Parameters:
oauth_uname (
str
) – The OAuth provider account name that the new user will access the dashboard through.user_email (
str
) – The email account associated with the user.num_studies (int) – The number of studies this user has been granted access to.
- dashboard.models.emails.account_rejection_email(user_id, user_email)¶
Notify a potential user that they will not be granted dashboard access.
- Parameters:
user_id (int) – The id for the database record storing the user’s info.
user_email (
str
) – The email address to notify.
- dashboard.models.emails.account_request_email(name)¶
Notify admins that a new user is requesting dashboard access.
- Parameters:
name (
str
) – The real name of the user requesting an account
- dashboard.models.emails.qc_notification_email(user_name, dest_email, study, current_tp, remain_tp=None)¶
Notify QCers that there is a new session to review.
- Parameters:
user_name (
str
) – A user’s real name.dest_email (
str
) – Email address to contact.study (
str
) – The name of the study that has received data.current_tp (
str
) – The name of the timepoint that needs review.remain_tp (
list
ofstr
) – A list of names of timepoints from this study that are still awaiting quality control.
dashboard.models.models module¶
Database models + relations
- class dashboard.models.models.AccountRequest(user_id)¶
Bases:
TableMixin
,Model
- approve()¶
- query: t.ClassVar[Query]¶
A SQLAlchemy query for a model. Equivalent to
db.session.query(Model)
. Can be customized per-model by overridingquery_class
.Warning
The query interface is considered legacy in SQLAlchemy. Prefer using
session.execute(select())
instead.
- reject()¶
- user¶
- user_id¶
- class dashboard.models.models.AltStudyCode(**kwargs)¶
Bases:
Model
- code¶
- query: t.ClassVar[Query]¶
A SQLAlchemy query for a model. Equivalent to
db.session.query(Model)
. Can be customized per-model by overridingquery_class
.Warning
The query interface is considered legacy in SQLAlchemy. Prefer using
session.execute(select())
instead.
- property site¶
- site_id¶
- property study¶
- study_id¶
- study_site¶
- property uses_redcap¶
- class dashboard.models.models.Analysis(**kwargs)¶
Bases:
Model
- analysis_comments¶
- description¶
- id¶
- name¶
- query: t.ClassVar[Query]¶
A SQLAlchemy query for a model. Equivalent to
db.session.query(Model)
. Can be customized per-model by overridingquery_class
.Warning
The query interface is considered legacy in SQLAlchemy. Prefer using
session.execute(select())
instead.
- software¶
- class dashboard.models.models.AnalysisComment(**kwargs)¶
Bases:
Model
- analysis¶
- analysis_id¶
- comment¶
- excluded¶
- id¶
- query: t.ClassVar[Query]¶
A SQLAlchemy query for a model. Equivalent to
db.session.query(Model)
. Can be customized per-model by overridingquery_class
.Warning
The query interface is considered legacy in SQLAlchemy. Prefer using
session.execute(select())
instead.
- scan¶
- scan_id¶
- user¶
- user_id¶
- class dashboard.models.models.AnonymousUser¶
Bases:
PermissionMixin
,AnonymousUserMixin
- account_active = False¶
- dashboard_admin = False¶
- first_name = 'Guest'¶
- get_disabled_sites()¶
- get_sites()¶
- get_studies()¶
- id = -1¶
- class dashboard.models.models.EmptySession(name, num, user_id, comment)¶
Bases:
Model
This table exists solely so QCers can dismiss errors about empty sessions and comment on any follow up they’ve performed.
- comment¶
- date_added¶
- name¶
- num¶
- query: t.ClassVar[Query]¶
A SQLAlchemy query for a model. Equivalent to
db.session.query(Model)
. Can be customized per-model by overridingquery_class
.Warning
The query interface is considered legacy in SQLAlchemy. Prefer using
session.execute(select())
instead.
- reviewer¶
- session¶
- user_id¶
- class dashboard.models.models.ExpectedScan(study, site, scantype, count=0, pha_count=0)¶
Bases:
TableMixin
,Model
- count¶
- pha_count¶
- scantype¶
- scantype_id¶
- site_id¶
- standards¶
- study_id¶
- class dashboard.models.models.GoldStandard(study, gs_json)¶
Bases:
Model
- expected_scan¶
- id¶
- json_contents¶
- json_created¶
- json_path¶
- query: t.ClassVar[Query]¶
A SQLAlchemy query for a model. Equivalent to
db.session.query(Model)
. Can be customized per-model by overridingquery_class
.Warning
The query interface is considered legacy in SQLAlchemy. Prefer using
session.execute(select())
instead.
- scans = ObjectAssociationProxyInstance(AssociationProxy('scan_gold_standard', 'scan'))¶
- site¶
- study¶
- tag¶
- class dashboard.models.models.IncidentalFinding(user_id, timepoint_id, description)¶
Bases:
Model
- description¶
- id¶
- query: t.ClassVar[Query]¶
A SQLAlchemy query for a model. Equivalent to
db.session.query(Model)
. Can be customized per-model by overridingquery_class
.Warning
The query interface is considered legacy in SQLAlchemy. Prefer using
session.execute(select())
instead.
- session¶
- timepoint_id¶
- timestamp¶
- user¶
- user_id¶
- class dashboard.models.models.MetricValue(**kwargs)¶
Bases:
Model
- id¶
- metrictype¶
- metrictype_id¶
- query: t.ClassVar[Query]¶
A SQLAlchemy query for a model. Equivalent to
db.session.query(Model)
. Can be customized per-model by overridingquery_class
.Warning
The query interface is considered legacy in SQLAlchemy. Prefer using
session.execute(select())
instead.
- scan¶
- scan_id¶
- property value¶
Returns the value field from the database. The value is stored as a string. If the value contains ‘::’ character this will convert it to a list, otherwise it will attempt to cast to Float. Failing that the value is returned as a string.
- class dashboard.models.models.Metrictype(**kwargs)¶
Bases:
Model
- id¶
- metric_values¶
- name¶
- query: t.ClassVar[Query]¶
A SQLAlchemy query for a model. Equivalent to
db.session.query(Model)
. Can be customized per-model by overridingquery_class
.Warning
The query interface is considered legacy in SQLAlchemy. Prefer using
session.execute(select())
instead.
- scantype¶
- scantype_id¶
- class dashboard.models.models.PermissionMixin¶
Bases:
object
Adds methods needed for user authentication.
- does_qc(study, site=None)¶
- abstract get_disabled_sites()¶
- abstract get_sites()¶
- abstract get_studies()¶
- has_study_access(study, site=None)¶
- is_kimel_contact(study, site=None)¶
- is_primary_contact(study, site=None)¶
- is_study_RA(study, site=None)¶
- is_study_admin(study, site=None)¶
- class dashboard.models.models.PipelineScope(**kwargs)¶
Bases:
Model
- query: t.ClassVar[Query]¶
A SQLAlchemy query for a model. Equivalent to
db.session.query(Model)
. Can be customized per-model by overridingquery_class
.Warning
The query interface is considered legacy in SQLAlchemy. Prefer using
session.execute(select())
instead.
- scope¶
- class dashboard.models.models.RedcapConfig(project, instrument, url, version=None)¶
Bases:
TableMixin
,Model
- comment_field¶
- completed_field¶
- property completed_value¶
- date_field¶
- event_ids¶
- get_config(project=None, instrument=None, url=None, version=None, create=False)¶
- id¶
- instrument¶
- project¶
- records¶
- redcap_version¶
- session_id_field¶
- token¶
- url¶
- user_id_field¶
- class dashboard.models.models.RedcapRecord(record, config_id, date, redcap_version=None)¶
Bases:
Model
- comment¶
- config¶
- date¶
- event_id¶
- form_config¶
- id¶
- property instrument¶
- property project¶
- query: t.ClassVar[Query]¶
A SQLAlchemy query for a model. Equivalent to
db.session.query(Model)
. Can be customized per-model by overridingquery_class
.Warning
The query interface is considered legacy in SQLAlchemy. Prefer using
session.execute(select())
instead.
- record¶
- property redcap_version¶
- sessions¶
- property url¶
- user¶
- class dashboard.models.models.Scan(name, timepoint, repeat, series, tag, description=None, source_id=None)¶
Bases:
TableMixin
,Model
- property active_gold_standard¶
- add_bids(name)¶
- add_checklist_entry(signing_user, comment=None, sign_off=None)¶
- add_error(error_message)¶
- add_json(json_file, timestamp=None)¶
- analysis_comments¶
- bids_name¶
- blacklisted()¶
- conv_errors¶
- description¶
- flagged()¶
- get_checklist_entry()¶
- get_comment()¶
- get_header_diffs()¶
- get_study(study_id=None)¶
- property gold_standards¶
- header_diffs¶
- id¶
- is_linked()¶
- is_new()¶
- is_outdated_header_diffs()¶
Reports whether an update to the header diffs is needed.
- json_contents¶
- json_created¶
- json_path¶
- length¶
- links¶
- list_children()¶
- metric_values¶
- name¶
- qc_review¶
- property qc_type¶
- repeat¶
- scantype¶
- series¶
- session¶
- signed_off()¶
- source_data¶
- source_id¶
- tag¶
- timepoint¶
- update_header_diffs(standard=None, ignore=None, tolerance=None)¶
- class dashboard.models.models.ScanChecklist(scan_id, user_id, comment=None, approved=False)¶
Bases:
TableMixin
,Model
- approved¶
- comment¶
- id¶
- scan¶
- scan_id¶
- property timestamp¶
- update_entry(user_id, comment=None, status=None)¶
- user¶
- user_id¶
- class dashboard.models.models.ScanGoldStandard(scan_id, gold_standard_id, diffs, gold_version, scan_version, timestamp=None)¶
Bases:
Model
- date_added¶
- diffs¶
- gold_standard¶
- gold_standard_id¶
- gold_version¶
- query: t.ClassVar[Query]¶
A SQLAlchemy query for a model. Equivalent to
db.session.query(Model)
. Can be customized per-model by overridingquery_class
.Warning
The query interface is considered legacy in SQLAlchemy. Prefer using
session.execute(select())
instead.
- scan¶
- scan_id¶
- scan_version¶
- property timestamp¶
- class dashboard.models.models.Scantype(tag)¶
Bases:
TableMixin
,Model
- expected_scans¶
- metrictypes¶
- pha_type¶
- qc_type¶
- scans¶
- studies¶
- tag¶
- class dashboard.models.models.Session(name, num, date=None, signed_off=False, reviewer_id=None, review_date=None)¶
Bases:
TableMixin
,Model
- add_redcap(record_num, date, project=None, url=None, instrument=None, config=None, rc_user=None, comment=None, event_id=None, redcap_version=None)¶
- add_scan(name, series, tag, description=None, source_id=None)¶
- add_task(file_path, name=None)¶
- date¶
- delete()¶
This will also delete anything referencing the current session (i.e. any scans, redcap comments, blacklist entries or dismissed ‘missing scans’ errors)
- delete_scan(name)¶
- empty_session¶
- expects_notes(study=None)¶
- get_blacklist_entries()¶
Returns all ScanChecklist entries for all blacklisted scans in this session.
- get_expected_scans(study_id=None)¶
- get_study(study_id=None)¶
- is_new()¶
- is_qcd()¶
- kcni_name¶
- missing_scans()¶
- name¶
- num¶
- redcap_record¶
- review_date¶
- reviewer¶
- reviewer_id¶
- scans¶
- sign_off(user_id)¶
- signed_off¶
- property site¶
- task_files¶
- tech_notes¶
- timepoint¶
- class dashboard.models.models.SessionRedcap(name, num, record_id=None)¶
Bases:
Model
- name¶
- num¶
- query: t.ClassVar[Query]¶
A SQLAlchemy query for a model. Equivalent to
db.session.query(Model)
. Can be customized per-model by overridingquery_class
.Warning
The query interface is considered legacy in SQLAlchemy. Prefer using
session.execute(select())
instead.
- record¶
- record_id¶
- session¶
Shares an existing redcap record with another session that represents an alternate ID for the original participant
- class dashboard.models.models.Site(site_name, description=None)¶
Bases:
TableMixin
,Model
- description¶
- name¶
- studies¶
- timepoints¶
- class dashboard.models.models.Study(study_id, full_name=None, description=None, read_me=None, is_open=None)¶
Bases:
TableMixin
,Model
- add_gold_standard(gs_file)¶
- add_pipeline(pipeline_key, view, name, scope)¶
- add_timepoint(timepoint)¶
- choose_staff_contact()¶
- delete()¶
- delete_scantype(site_id, scantype)¶
- delete_site(site)¶
- description¶
- email_qc¶
- get_QCers()¶
- get_RAs(site=None, unique=False)¶
Get a list of all RAs for the study, or all RAs for a given site.
The ‘unique’ flag can be used to ensure RAs are only in the list once if they happen to be an RA for multiple sites. Pretty much only useful for printing the list.
- get_blacklisted_scans()¶
- get_flagged_scans()¶
- get_missing_redcap()¶
Returns a list of all non-phantoms for the current study that are expecting a redcap survey but dont yet have one.
- get_missing_scans()¶
Returns a list of session names + repeat numbers for sessions in this study that have a scan completed survey but no scan data yet. Excludes session IDs that have explicitly been marked as never expecting data
- get_new_sessions()¶
- get_pipelines(scope=None)¶
- get_primary_contacts()¶
- get_qced_scans()¶
- get_sessions_using_redcap()¶
Returns a query that will find all sessions in the current study that expect a redcap survey (whether or not we’ve already received one for them)
Doing this manually rather than letting SQLAlchemy handle it behind the scenes because it was firing off one query per session every time a study page loaded. So it’s way uglier, but way faster. Sorry :(
- get_staff_contacts()¶
- get_tag_counts(site, pha=False)¶
Return the number of scans expected for each tag.
- Parameters:
site (str) – The name of a site for this study.
pha (bool, optional) – Whether to look up the number expected for phantoms.
- id¶
- is_open¶
- name¶
- num_timepoints(type='')¶
- outstanding_issues()¶
- read_me¶
- scantypes¶
- select_next(user_list)¶
Selects the next user from a study. This can be used to choose the next QC-er to assign, or the next staff member to assign to an issue, etc.
Current strategy is to pick a random person. This may be changed in the future.
- sites¶
- standards¶
- timepoints¶
- update_scantype(site_id, scantype, num=None, pha_num=None, create=False)¶
Update the number of scans expected for each site / tag combination.
- Parameters:
site_id (str or Site) – The site to configure.
scantype (str or Scantype) – The scan type to configure.
num (int, optional) – The number of scans expected with this tag for human subjects at this site. Only updates if value given. Defaults to None.
pha_only (int, optional) – The number of scans with this tag expected for phantoms at this site. Only updates if value given. Defaults to None.
create (bool, optional) – Whether to add a new record for the study/site/tag combination if one doesnt exist.
- Raises:
InvalidDataException – If a site is given that isn’t configured for this study, if the scan type does not exist, or if an error occurs during database update.
- update_site(site_id, redcap=None, notes=None, code=None, xnat_archive=None, xnat_convention='KCNI', xnat_credentials=None, xnat_url=None, create=False)¶
Update a site configured for this study (or configure a new one).
- Parameters:
site_id (str or Site) – The ID of a site associated with this study or its record from the database.
redcap (bool, optional) – True if redcap scan completed records are used by this site. Updates only if value provided. Defaults to None.
notes (bool, optional) – True if tech notes are provided by this site. Updates only if value provided. Defaults to None.
code (str, optional) – The study code used for IDs for this study and site combination. Updates only if value provided. Defaults to None.
xnat_archive (str, optional) – The name of the archive on XNAT where data for this site is stored. Updates only if value provided. Defaults to None.
xnat_convention (str, optional) – The naming convention used on the XNAT server for this site. Defaults to ‘KCNI’.
xnat_credentials (str, optional) – The full path to the credentials file to read when accessing this site’s XNAT archive. Defaults to None.
xnat_url (str, optional) – The URL to use when accessing this site’s XNAT archive. Defaults to None.
create (bool, optional) – Whether to create the site and add it to this study if it isnt already associated. Defaults to False.
- Raises:
InvalidDataException – If the site doesnt exist or isn’t associated with this study (and create wasnt given) or if the update fails.
- users¶
- class dashboard.models.models.StudyPipeline(**kwargs)¶
Bases:
TableMixin
,Model
Define QC pipelines enabled for a study.
- name¶
- pipeline_id¶
- scope¶
- study_id¶
- view¶
- class dashboard.models.models.StudySite(study_id, site_id, uses_redcap=False, uses_notes=None, code=None)¶
Bases:
TableMixin
,Model
- alt_codes¶
- code¶
- download_script¶
- expected_scans¶
- post_download_script¶
- site¶
- site_id¶
- study¶
- study_id¶
- users¶
- uses_notes¶
- uses_redcap¶
- xnat_archive¶
- xnat_convention¶
- xnat_credentials¶
- xnat_url¶
- class dashboard.models.models.StudyUser(study_id, user_id, site_id=None, admin=False, is_primary_contact=False, is_kimel_contact=False, is_study_RA=False, does_qc=False)¶
Bases:
Model
- does_qc¶
- id¶
- is_admin¶
- kimel_contact¶
- primary_contact¶
- query: t.ClassVar[Query]¶
A SQLAlchemy query for a model. Equivalent to
db.session.query(Model)
. Can be customized per-model by overridingquery_class
.Warning
The query interface is considered legacy in SQLAlchemy. Prefer using
session.execute(select())
instead.
- site_id¶
- study¶
- study_RA¶
- study_id¶
- user¶
- user_id¶
- class dashboard.models.models.TableMixin¶
Bases:
object
Adds simple methods commonly needed for tables.
- delete()¶
- save()¶
- class dashboard.models.models.TaskFile(timepoint, repeat, file_path, file_name=None)¶
Bases:
Model
- file_name¶
- file_path¶
- id¶
- query: t.ClassVar[Query]¶
A SQLAlchemy query for a model. Equivalent to
db.session.query(Model)
. Can be customized per-model by overridingquery_class
.Warning
The query interface is considered legacy in SQLAlchemy. Prefer using
session.execute(select())
instead.
- repeat¶
- session¶
- timepoint¶
- class dashboard.models.models.Timepoint(name, site, is_phantom=False)¶
Bases:
TableMixin
,Model
- accessible_study(user)¶
Returns a study that the timepoint belongs to and the user has access to if one exists.
- add_bids(name, session)¶
- add_comment(user_id, text)¶
- add_session(num, date=None)¶
- belongs_to(study)¶
Returns true if the data in this Timepoint is considered part of the given study
- bids_name¶
- bids_session¶
- comments¶
- delete()¶
This will cascade and also delete any records that reference the current timepoint, so be careful :)
- delete_comment(comment_id)¶
- dismiss_redcap_error(session_num)¶
- expects_notes(study=None)¶
- expects_redcap(study=None)¶
- get_blacklist_entries()¶
Returns any ScanChecklist entries for blacklisted scans for every session belonging to this timepoint.
- get_comment(comment_id)¶
- get_study(study_id=None)¶
Most timepoints only ever have one study and this will just return the first one found. If ‘id’ is given it will either return the study object or raise an exception if this timepoint doesnt belong to that study
- ignore_missing_scans(session_num, user_id, comment)¶
- incidental_findings¶
- is_phantom¶
- is_qcd()¶
- kcni_name¶
- missing_scans()¶
- name¶
- needs_redcap_survey(study_id)¶
- report_incidental_finding(user_id, comment)¶
- property reviewer¶
Returns the name of the first session’s qc reviewer as this timepoint’s reviewer
- sessions¶
- site¶
- site_id¶
- studies¶
- update_comment(user_id, comment_id, new_text)¶
- class dashboard.models.models.TimepointComment(timepoint_id, user_id, comment)¶
Bases:
Model
- comment¶
- id¶
- modified¶
- query: t.ClassVar[Query]¶
A SQLAlchemy query for a model. Equivalent to
db.session.query(Model)
. Can be customized per-model by overridingquery_class
.Warning
The query interface is considered legacy in SQLAlchemy. Prefer using
session.execute(select())
instead.
- timepoint¶
- timepoint_id¶
- property timestamp¶
- update(new_text)¶
- user¶
- user_id¶
- class dashboard.models.models.User(first, last, username=None, provider='github', email=None, position=None, institution=None, phone=None, ext=None, alt_phone=None, alt_ext=None, picture=None, dashboard_admin=False, account_active=False)¶
Bases:
PermissionMixin
,UserMixin
,TableMixin
,Model
- property account_provider¶
- add_studies(study_ids)¶
Enable study access for this user.
This will add a StudyUser record with the default permissions for each given study. Restrict access to specific sites by mapping the study ID to a list of allowed site names. An empty list means ‘grant the user access to all sites’.
For example:
- study_ids = {‘OPT’: [‘UT1’, ‘UT2’],
‘PRELAPSE’: []}
This would grant the user access to two sites (UT1, UT2) in OPT and all sites in PRELAPSE.
- Parameters:
study_ids (
dict
) – A dictionary of study IDs to grant user access to. Each study ID key should map to a list of sites to enable. Use the empty list to indicate global study access.- Raises:
InvalidDataException – If the format of arg study_ids is incorrect or one or more records cannot be added.
- alt_ext¶
- alt_phone¶
- analysis_comments¶
- dashboard_admin¶
- email¶
- ext¶
- first_name¶
- get_disabled_sites()¶
Get a dict of study IDs mapped to sites this user cant access
- Returns:
A dictionary mapping each study ID to a list of its sites that this user does not have access to. Studies where the user has full access will be omitted entirely.
- Return type:
dict
- get_sites()¶
Get a list of sites the user has even partial access to.
Caution: If using this to determine data access you must still restrict by study.
- Returns:
A list of string site names.
- Return type:
list
- get_studies()¶
Get a list of studies that user has even partial access to
- Returns:
A list of Study objects, one for each study where the user has at least partial (site based) access.
- Return type:
list
- id¶
- incidental_findings¶
- institution¶
- is_active¶
- last_name¶
- num_requests()¶
Returns a count of all pending user requests that need to be reviewed
- pending_approval¶
- phone¶
- picture¶
- position¶
- remove_studies(study_ids)¶
Disable study access for this user.
This removes any StudyUser records that match the given study IDs. Access to specific sites within a study can be disabled by mapping the study ID to a list of site names. An empty list means ‘disable user access to this study completely’.
For example:
- study_ids = {‘OPT’: [‘UT1’],
‘PRELAPSE’: []}
This would remove user access to site ‘UT1’ for OPT and totally disable user access to PRELAPSE
- Parameters:
study_ids (
dict
) – A dictionary of study IDs to disable access to. Each ID should map to a list of sites to disable. The empty list indicates complete access restriction- Raises:
InvalidDataException – If the format of arg study_ids is incorrect or one or more records cannot be removed.
- request_account(request_form)¶
- scan_comments¶
- sessions_reviewed¶
- studies¶
- timepoint_comments¶
- update_avatar(url=None)¶
- update_username(new_name, provider='github')¶
- property username¶
dashboard.models.utils module¶
Functions and classes for use in dashboard.models
- class dashboard.models.utils.DictListCollection(key)¶
Bases:
KeyFuncDict
Allows a relationship to be organized into a dictionary of lists
- list_mod()¶
Allows sqlalchemy manage changes to the contents of the lists
- dashboard.models.utils.async_xnat_update(xnat_url, user, password, xnat_archive, exp_name, series_num, comment, quality)¶
Push usability data into XNAT.
This will update XNAT in a separate thread to reduce waiting time for the user. Because it will run in another thread, database objects cannot be passed in as arguments.
- Parameters:
xnat_url (str) – The full URL to use for the XNAT server.
user (str) – The user to log in as.
password (str) – The password to log in with.
xnat_archvie (str) – The name of the XNAT archive that contains the experiment.
exp_name (str) – The name of the experiment on XNAT.
series_num (int) – The series number of the file to update.
comment (str) – The user’s QC comment.
quality (str) – The quality label to apply based on whether data has been flagged, blacklisted or approved.
- dashboard.models.utils.file_timestamp(file_path)¶
- dashboard.models.utils.get_software_version(json_contents)¶
- dashboard.models.utils.get_xnat_credentials(site_settings, app_config)¶
Retrieve the xnat username and password for a given study/site.
- Parameters:
site_settings (
dashboard.models.StudySite
) – A StudySite recordapp_config (
dict
) – Configuration of the current app instance, as retrieved from current_app.config
- dashboard.models.utils.read_json(json_file)¶
- dashboard.models.utils.schedule_email(email_func, input_args, input_kwargs=None)¶
Send an email from the server side.
If an automated email is fired from code that may be run on the client side then it should be wrapped by this function. This will add a scheduler job that fires instantly to ensure it executes server side (or just send it if it’s already server side).
NOTE: We’re using scheduler.add_job directly and not dashboard.monitors.add_monitor because monitors often need classes from the models and using add_monitor would introduce circular dependencies.
- dashboard.models.utils.update_xnat_usability(scan, app_config)¶
Update XNAT usability data for a scan.
- Parameters:
scan (
dashboard.models.Scan
) – The series to push QC data for.app_config (
dict
) – Configuration of the current app instance, as retrieved from current_app.config