Source code for crate_anon.common.constants

"""
crate_anon/common/constants.py

===============================================================================

    Copyright (C) 2015, University of Cambridge, Department of Psychiatry.
    Created by Rudolf Cardinal (rnc1001@cam.ac.uk).

    This file is part of CRATE.

    CRATE is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    CRATE is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with CRATE. If not, see <https://www.gnu.org/licenses/>.

===============================================================================

**Constants used throughout CRATE.**

"""

import os


# =============================================================================
# Plain constants
# =============================================================================

CRATE_DOCS_URL = "https://crateanon.readthedocs.io/"

DEMO_NLP_INPUT_TERMINATOR = "STOP"
DEMO_NLP_OUTPUT_TERMINATOR = "END_OF_NLP_OUTPUT_RECORD"

EXIT_FAILURE = 1
EXIT_SUCCESS = 0

JSON_INDENT = 4

JSON_SEPARATORS_COMPACT = (",", ":")
# ... see https://docs.python.org/3/library/json.html

LOWER_CASE_STRINGS_MEANING_TRUE = ["true", "1", "t", "y", "yes"]

# Is this program running on readthedocs.org?
ON_READTHEDOCS = os.environ.get("READTHEDOCS") == "True"


# =============================================================================
# Constant creation
# =============================================================================


[docs]def mebibytes(mb: int) -> int: """ Takes a parameter in mebibytes (1024^2 bytes) and returns the number of bytes. """ return mb * 1024 * 1024
# ============================================================================= # Directories within CRATE # =============================================================================
[docs]class CratePath: """ Directories within the CRATE Python package. """ CRATE_ANON_DIR = os.path.abspath( os.path.join( os.path.dirname( os.path.abspath(__file__) ), # this directory, common os.pardir, # parent, crate_anon ) ) CRATEWEB_DIR = os.path.join(CRATE_ANON_DIR, "crateweb") STATIC_SRC_DIR = os.path.join(CRATEWEB_DIR, "static") NLP_MANAGER_DIR = os.path.join(CRATE_ANON_DIR, "nlp_manager") JAVA_CLASSES_DIR = os.path.join(NLP_MANAGER_DIR, "compiled_nlp_classes") NLPRP_DIR = os.path.join(CRATE_ANON_DIR, "nlprp")
# ============================================================================= # DockerConstants # =============================================================================
[docs]class DockerConstants: """ Constants for the Docker environment. """ # Directories DOCKER_CRATE_ROOT_DIR = "/crate" CONFIG_DIR = os.path.join(DOCKER_CRATE_ROOT_DIR, "cfg") TMP_DIR = os.path.join(DOCKER_CRATE_ROOT_DIR, "tmp") VENV_DIR = os.path.join(DOCKER_CRATE_ROOT_DIR, "venv") HOST = "0.0.0.0"
# ... not "localhost" or "127.0.0.1"; see # https://nickjanetakis.com/blog/docker-tip-54-fixing-connection-reset-by-peer-or-similar-errors # noqa # ============================================================================= # Environment variables # =============================================================================
[docs]class EnvVar: """ Environment variable names. """ CRATE_GATE_PLUGIN_FILE = "CRATE_GATE_PLUGIN_FILE" # ... environment variable whose presence shows that we are generating # docs. GATE_HOME = "GATE_HOME" GENERATING_CRATE_DOCS = "GENERATING_CRATE_DOCS" JAVA_HOME = "JAVA_HOME" KCL_KCONNECT_DIR = "KCL_KCONNECT_DIR" KCL_LEWY_BODY_DIAGNOSIS_DIR = "KCL_LEWY_BODY_DIAGNOSIS_DIR" KCL_PHARMACOTHERAPY_DIR = "KCL_PHARMACOTHERAPY_DIR" MEDEX_HOME = "MEDEX_HOME" PATH = "PATH" RUNNING_TESTS = "RUNNING_TESTS" RUN_WITHOUT_CONFIG = "CRATE_RUN_WITHOUT_LOCAL_SETTINGS"
# ============================================================================= # CRATE top-level commands # =============================================================================
[docs]class CrateCommand: """ Top-level commands within CRATE, recorded here to ensure consistency. However, see also crate/installer/installer.py, which duplicates some (because the full Python environment is not then available). """ # Preprocessing FETCH_WORDLISTS = "crate_fetch_wordlists" POSTCODES = "crate_postcodes" PREPROCESS_PCMIS = "crate_preprocess_pcmis" PREPROCESS_RIO = "crate_preprocess_rio" PREPROCESS_SYSTMONE = "crate_preprocess_systmone" # Linkage BULK_HASH = "crate_bulk_hash" FUZZY_ID_MATCH = "crate_fuzzy_id_match" # Anonymisation ANON_CHECK_TEXT_EXTRACTOR = "crate_anon_check_text_extractor" ANON_DEMO_CONFIG = "crate_anon_demo_config" ANON_DRAFT_DD = "crate_anon_draft_dd" ANON_SHOW_COUNTS = "crate_anon_show_counts" ANON_SUMMARIZE_DD = "crate_anon_summarize_dd" ANONYMISE = "crate_anonymise" ANONYMISE_MULTIPROCESS = "crate_anonymise_multiprocess" MAKE_DEMO_DATABASE = "crate_make_demo_database" RESEARCHER_REPORT = "crate_researcher_report" SUBSET_DB = "crate_subset_db" TEST_ANONYMISATION = "crate_test_anonymisation" TEST_EXTRACT_TEXT = "crate_test_extract_text" # NLP NLP = "crate_nlp" NLP_BUILD_GATE_JAVA_INTERFACE = "crate_nlp_build_gate_java_interface" NLP_BUILD_MEDEX_ITSELF = "crate_nlp_build_medex_itself" NLP_BUILD_MEDEX_JAVA_INTERFACE = "crate_nlp_build_medex_java_interface" NLP_MULTIPROCESS = "crate_nlp_multiprocess" NLP_PREPARE_YMLS_FOR_BIOYODIE = "crate_nlp_prepare_ymls_for_bioyodie" RUN_CRATE_NLP_DEMO = "crate_run_crate_nlp_demo" RUN_GATE_ANNIE_DEMO = "crate_run_gate_annie_demo" RUN_GATE_KCL_KCONNECT_DEMO = "crate_run_gate_kcl_kconnect_demo" RUN_GATE_KCL_LEWY_DEMO = "crate_run_gate_kcl_lewy_demo" RUN_GATE_KCL_PHARMACOTHERAPY_DEMO = ( "crate_run_gate_kcl_pharmacotherapy_demo" ) SHOW_CRATE_GATE_PIPELINE_OPTIONS = "crate_show_crate_gate_pipeline_options" SHOW_CRATE_MEDEX_PIPELINE_OPTIONS = ( "crate_show_crate_medex_pipeline_options" ) # Web site CELERY_STATUS = "crate_celery_status" DJANGO_MANAGE = "crate_django_manage" EMAIL_RDBM = "crate_email_rdbm" GENERATE_NEW_DJANGO_SECRET_KEY = "crate_generate_new_django_secret_key" LAUNCH_CELERY = "crate_launch_celery" LAUNCH_FLOWER = "crate_launch_flower" PRINT_DEMO_CRATEWEB_CONFIG = "crate_print_demo_crateweb_config" WINDOWS_SERVICE = "crate_windows_service" LAUNCH_CHERRYPY_SERVER = "crate_launch_cherrypy_server" LAUNCH_DJANGO_SERVER = "crate_launch_django_server" # NLP web server NLP_WEBSERVER_GENERATE_ENCRYPTION_KEY = ( "crate_nlp_webserver_generate_encryption_key" ) NLP_WEBSERVER_INITIALIZE_DB = "crate_nlp_webserver_initialize_db" NLP_WEBSERVER_LAUNCH_CELERY = "crate_nlp_webserver_launch_celery" NLP_WEBSERVER_LAUNCH_FLOWER = "crate_nlp_webserver_launch_flower" NLP_WEBSERVER_LAUNCH_GUNICORN = "crate_nlp_webserver_launch_gunicorn" NLP_WEBSERVER_MANAGE_USERS = "crate_nlp_webserver_manage_users" NLP_WEBSERVER_PRINT_DEMO = "crate_nlp_webserver_print_demo" NLP_WEBSERVER_PSERVE = "crate_nlp_webserver_pserve"
# ============================================================================= # HelpUrl # =============================================================================
[docs]class HelpUrl: """ Makes help URLs, for an approximation to context-sensitive help within the web site. Note that in Django's template syntax, .. code-block:: none {{ HelpUrl.main }} gets translated to .. code-block:: python HelpUrl.main() i.e. further brackets are unnecessary (and an error). See: - https://docs.djangoproject.com/en/2.2/topics/templates/#variables ... "If a variable resolves to a callable, the template system will call it with no arguments and use its result instead of the callable." """
[docs] @staticmethod def make_url( location: str, language: str = "en", version: str = "latest" ) -> str: """ Make a CRATE help URL. Args: location: location within docs language: language (default ``en``) version: version (default ``latest``) """ return f"{CRATE_DOCS_URL}{language}/{version}/{location}"
@classmethod def main(cls) -> str: return cls.make_url("") @classmethod def website(cls) -> str: return cls.make_url("website_using/index.html") @classmethod def find_text_anywhere(cls) -> str: return cls.make_url( "website_using/clinician_privileged.html#clinician-privileged-find-text-anywhere" # noqa: E501 ) @classmethod def clinician_lookup_rid(cls) -> str: return cls.make_url( "website_using/clinician_privileged.html#look-up-research-id-from-patient-id" # noqa: E501 ) @classmethod def clinician_submit_contact_request(cls) -> str: return cls.make_url( "website_using/clinician_privileged.html#submit-patient-contact-request" # noqa: E501 ) @classmethod def querybuilder(cls) -> str: return cls.make_url( "website_using/research_queries.html#query-builder" ) @classmethod def sql(cls) -> str: return cls.make_url( "website_using/research_queries.html#research-query-sql" ) @classmethod def highlighting(cls) -> str: return cls.make_url( "website_using/research_queries.html#highlighting-text-in-results" ) @classmethod def results(cls) -> str: return cls.make_url( "website_using/research_queries.html#results-table-view" ) @classmethod def patient_explorer(cls) -> str: return cls.make_url("website_using/patient_explorer.html") @classmethod def sqlhelper_find_text_anywhere(cls) -> str: return cls.make_url( "website_using/sql_helpers.html#find-text-anywhere" ) @classmethod def sqlhelper_find_drugs_anywhere(cls) -> str: return cls.make_url( "website_using/sql_helpers.html#find-drugs-of-a-given-type-anywhere" # noqa: E501 ) @classmethod def sitewide_queries(cls) -> str: return cls.make_url("website_using/site_queries.html") @classmethod def research_db_structure(cls) -> str: return cls.make_url("website_using/database_structure.html") @classmethod def submit_contact_request(cls) -> str: return cls.make_url( "website_using/contact_patients.html#submit-a-contact-request" ) @classmethod def rdbm(cls) -> str: return cls.make_url("website_using/rdbm_admin.html") @classmethod def developer(cls) -> str: return cls.make_url("website_using/developer_admin.html") @classmethod def user_settings(cls) -> str: return cls.make_url( "website_using/clinician_researcher_overview.html#your-settings" ) @classmethod def about_crate(cls) -> str: return cls.make_url( "website_using/clinician_researcher_overview.html#about-crate" ) @classmethod def archive(cls) -> str: return cls.make_url("website_using/archive.html")
# ============================================================================= # More plain constants # ============================================================================= # Will we run without a config file? RUNNING_WITHOUT_CONFIG = ON_READTHEDOCS or ( EnvVar.RUN_WITHOUT_CONFIG in os.environ and os.environ[EnvVar.RUN_WITHOUT_CONFIG].lower() in LOWER_CASE_STRINGS_MEANING_TRUE )