From 9f3a406d464f7808bc044a3d530e4be0b79e23b9 Mon Sep 17 00:00:00 2001 From: lrdossan Date: Wed, 27 Nov 2024 15:36:11 +0100 Subject: [PATCH] Update on entire docs: - Added landing page for REST API and handled route package structure - Alphabetically ordered form inputs and fixed documentation on REST API - Added new logo in documentation UI and added section for REST API in documentation --- .../mkdocs/docs/assets/caimira_full_logo.png | Bin 0 -> 26592 bytes caimira/docs/mkdocs/docs/code/rest_api.md | 14 +- caimira/docs/mkdocs/docs/index.md | 2 +- caimira/docs/mkdocs/docs/root/installation.md | 370 +++++++++++------- caimira/docs/mkdocs/mkdocs.yml | 2 +- caimira/src/caimira/api/app.py | 9 +- .../src/caimira/api/routes/base_handler.py | 13 + .../src/caimira/api/routes/landing_routes.py | 11 + .../src/caimira/api/routes/report_routes.py | 18 +- caimira/src/caimira/api/routes/routes.py | 8 + .../validators/co2/co2_validator.py | 12 +- .../caimira/calculator/validators/defaults.py | 42 +- .../validators/virus/virus_validator.py | 64 ++- cern_caimira/tests/test_report_generator.py | 1 - 14 files changed, 331 insertions(+), 235 deletions(-) create mode 100644 caimira/docs/mkdocs/docs/assets/caimira_full_logo.png create mode 100644 caimira/src/caimira/api/routes/base_handler.py create mode 100644 caimira/src/caimira/api/routes/landing_routes.py create mode 100644 caimira/src/caimira/api/routes/routes.py diff --git a/caimira/docs/mkdocs/docs/assets/caimira_full_logo.png b/caimira/docs/mkdocs/docs/assets/caimira_full_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..002529eb53befd27b478f96afbd0e3ddb36e7579 GIT binary patch literal 26592 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 @^{lf|ruxS$3oe_MYAGlrcI;C(du%ff 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 KtY{@z&;NgY - [![CAiMIRA logo](assets/caimira_logo.png){ width="100" }](https://caimira.web.cern.ch/) + [![CAiMIRA logo](assets/caimira_full_logo.png){ width="50%" }](https://caimira.web.cern.ch/) # Contents: diff --git a/caimira/docs/mkdocs/docs/root/installation.md b/caimira/docs/mkdocs/docs/root/installation.md index 8a14ec85..e41215b5 100644 --- a/caimira/docs/mkdocs/docs/root/installation.md +++ b/caimira/docs/mkdocs/docs/root/installation.md @@ -1,190 +1,226 @@ -## Docker +This installation guide provides instructions for both quickly running CAiMIRA with the Calculator App using a pre-built Docker image, as well as instructions on how to set up a development environment for advanced use cases. It is therefore structured to accommodate a variety of users, from those seeking a simple, quick-start solution, to developers requiring a detailed setup for customization and development. -### Using the pre-built image +**Guide Overview**: -The easiest way to run a version of CAiMIRA Calculator is to use docker. A pre-built -image of CAiMIRA is made available at [https://gitlab.cern.ch/caimira/caimira/container_registry](https://gitlab.cern.ch/caimira/caimira/container_registry). -In order to run CAiMIRA locally with docker, run the following: +1. **[Quick Start](#quick-start)**: Designed for users aiming to run CAiMIRA with minimal setup. The Quick Guide section outlines the fastest approach to using CAiMIRA through a pre-built Docker image. +2. **[Development Installation](#development-installation)**: Intended for developers or those requiring advanced customization. This section includes detailed steps for setting up the environment, running the backend REST API, and contributing to the project. + +## Quick Start + +The easiest way to run a version of CAiMIRA with its Calculator App is to use Docker. A pre-built image of CAiMIRA is made available at [this](https://gitlab.cern.ch/caimira/caimira/container_registry) GitLab container registry. + +### Prerequisites + +Before proceeding, ensure the following prerequisites are met: + +1. **Docker Installed**: + + Install Docker on the system. Instructions for installation can be found at [Docker's official website](https://www.docker.com/products/docker-desktop/). + + Verify the installation by opening a terminal and running: + + docker --version + +2. **Network Access**: + + Ensure the machine has internet access to pull the CAiMIRA image from the container registry. + +### Running the pre-built Image + +In order to run CAiMIRA locally with Docker, run the following instruction in a terminal: docker run -it -p 8080:8080 -e APP_NAME='calculator-app' gitlab-registry.cern.ch/caimira/caimira/calculator-app -This will start a local version of CAiMIRA, which can be visited at [http://localhost:8080/](http://localhost:8080/). +This will start a local version of CAiMIRA, which can be visited by loading this URL in your browser [http://localhost:8080/](http://localhost:8080/). -### Building the whole environment +## Development Installation -To build the whole environment for local development, from the root directory of the project, run: +This section provides comprehensive instructions for setting up the CAiMIRA environment in development mode. The guide is tailored for contributors and advanced users who want to build the project from source, customize its features, or contribute to its codebase1. -``` -docker build -f app-config/api-app/Dockerfile -t api-app . -docker build -f app-config/calculator-app/Dockerfile -t calculator-app . -docker build ./app-config/auth-service -t auth-service -``` - -If you are using a computer with ARM CPU (Mac M1/2/3), then add the arg `--platform linux/arm64` to the docker build cmd. - -If you need to debug the Docker build, add the args `--no-cache --progress=plain` to see a more verbose output in your terminal. - -Get the client secret from the CERN Application portal for the `caimira-test` app. See [CERN-SSO-integration](deployment.md#cern-sso-integration) for more info. -``` -read CLIENT_SECRET -``` - -Define some env vars (copy/paste): -``` -export COOKIE_SECRET=$(openssl rand -hex 50) -export OIDC_SERVER=https://auth.cern.ch/auth -export OIDC_REALM=CERN -export CLIENT_ID=caimira-test -export CLIENT_SECRET=$CLIENT_SECRET -``` - -Run docker compose: -``` -cd app-config -CURRENT_UID=$(id -u):$(id -g) docker compose up -``` - -Then visit [http://localhost:8080/](http://localhost:8080/). - -## Development mode - -CAiMIRA is mirrored to Github if you wish to collaborate on development and can be found at: [https://github.com/CERN/caimira](https://github.com/CERN/caimira) - -### Folder structure +Developers can follow the steps below to build and run the CAiMIRA backend and frontend applications, set up APIs, run tests, and generate the documentation. Additionally, this section includes instructions for running legacy expert applications, profiling the system, and testing specific features. The project contains two different Python packages: -- `caimira`: Contains all the backend logic and the calculator model. It is the package published in PyPI. -- `cern_caimira`: Imports and uses the backend package (`caimira`) and includes CERN-specific UI implementation. +- `caimira`: Contains the backend logic and the APIs logic. This package is published in [PyPI](https://pypi.org/project/caimira/). +- `cern_caimira`: Imports and uses the backend package (`caimira`) and includes the CAiMIRA-native UI features. The folder layout follows best practices as described [here](https://ianhopkinson.org.uk/2022/02/understanding-setup-py-setup-cfg-and-pyproject-toml-in-python/). -### Installing and running CAiMIRA +!!! info + 1 The project's main repository is hosted on [GitLab](https://gitlab.cern.ch/caimira/caimira). Even though the repository is public, contributions to GitLab are restricted to users with a valid CERN SSO. + + For external contributions and collaboration, a mirror is maintained on [GitHub](https://github.com/CERN/caimira). -Installing CAiMIRA in editable mode and running the Calculator App. +### Prerequisites -#### Installing +Before proceeding with the development installation of CAiMIRA, ensure that your system meets the following prerequisites: -In order to install the CAiMIRA's backend logic, create your own `virtualenv` and, from the root directory of the project, run: +1. **Python Environment**: -``` -cd caimira -pip install -e . -``` + - Python `3.9` or later. + - `pip`, `setuptools` must but installed and up-to-date. You can update them by opening a terminal and running: -In order to install the CERN-specific UI version, that links to the previously installed backend, activate your `virtualenv` and, from the root directory of the project, run: + python -m pip install --upgrade pip setuptools -``` -cd cern_caimira -pip install -e . -``` + !!! note + It's recommended to use `pyenv` or similar tools to manage Python versions. For details on how to install and use `pyenv`, see [here](https://github.com/pyenv/pyenv). While not mandatory, it is also recommended to create a virtual environment (`virtualenv`) to avoid conflicts between different package versions. For more information on setting up a virtual environment, see [here](https://virtualenv.pypa.io/en/latest/). -#### Running +2. **Git**: -This example describes how to run the calculator with the CERN-specific UI. In the root directory of the project: + - Ensure that Git is installed for cloning the repository. You can download it [here](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git). Verify installation by opening a terminal and running: -``` -python -m cern_caimira.apps.calculator -``` + git --version -To run with a specific template theme created: +3. **Docker**: -``` -python -m cern_caimira.apps.calculator --theme=cern_caimira/src/cern_caimira/apps/templates/{theme} -``` + - While not strictly required for local development, Docker is useful for creating isolated environments and running CAiMIRA in production-like settings. Further details can be found in the [Setting up full environment](#setting-up-the-full-environment) section. -To run the entire app in a different `APPLICATION_ROOT` path: +4. **Development Tools**: -``` -python -m cern_caimira.apps.calculator --app_root=/myroot -``` + - A code editor such as [VSCode](https://code.visualstudio.com/), or an IDE like [PyCharm](https://www.jetbrains.com/pycharm/). -To run the calculator on a different URL path: +5. **Repository Setup**: -``` -python -m cern_caimira.apps.calculator --prefix=/mycalc -``` + - Clone the CAiMIRA repository from the GitLab or GitHub mirror by opening a terminal and running: + + git clone https://gitlab.cern.ch/caimira/caimira.git + cd caimira + + !!! note + The directory in which you run the previous commands will be the root directory of your project. + +### Installing and running + +This section provides instructions for setting up, running, and testing CAiMIRA in a local development environment. It covers the installation of the backend logic, interaction with user interfaces, and utilization of the API app. Additionally, instructions for legacy applications (expert apps), testing procedures, and tools for profiling and documentation generation are provided. + +##### Prerequisites: + +After following what is described in the main [prerequisites](#prerequisites) section, ensure the following dependencies are correctly installed: + +1. **CAiMIRA repository**: Can be cloned from the official GitLab repository [here](https://gitlab.cern.ch/caimira/caimira). +2. **Python `3.9` or later**: Required for running the CAiMIRA backend and UI. + +#### CAiMIRA + +CAiMIRA can be installed locally for development and usage in editable mode. This allows full access to both the backend logic, as well as the CAiMIRA-native UI. The following sections provide step-by-step instructions for installing and running CAiMIRA on a local environment. + +##### Installing: + +In order to install the CAiMIRA's backend logic, from the root directory of the project, run: + + cd caimira + pip install -e . + +In order to install the CAiMIRA-native UI version, that links to the previously installed backend, from the root directory of the project, run: + + cd cern_caimira + pip install -e . + +##### Running: + +The calculator can be started with the CAiMIRA-native UI using the following command in the project root directory: + + python -m cern_caimira.apps.calculator + +Additional options allow customization, such as specifying themes, application roots, or URL paths. For example: + +- **Run with a specific template theme**: + + Within a given UI framework, you can choose different "themes" changing some frontend logic, style and text. To run with a specific template theme created: + + python -m cern_caimira.apps.calculator --theme=cern_caimira/src/cern_caimira/apps/templates/{theme} + +- **Run the app with a different `APPLICATION_ROOT` path**: + + The base path of the web application on the server. It determines where the app is "rooted" in relation to the server's URL structure. To run with a specific application root: + + python -m cern_caimira.apps.calculator --app_root=/myroot + +- **Run the Calculator App on a different `CAIMIRA_CALCULATOR_PREFIX` URL path**: + + The base path of the CAiMIRA calculator. It determines the URL path within the Calculator App itself. To run with a specific prefix: + + python -m cern_caimira.apps.calculator --prefix=/mycalc Each of these commands will start a local version of CAiMIRA, which can be visited at [http://localhost:8080/](http://localhost:8080/). -#### REST API +##### Expert-Apps: -To use the REST API, from the root directory of the project: +The CAiMIRA Expert App and CO2 App are legacy tools designed to provide dynamic interaction with the CAiMIRA model parameters. -1. Run the backend API: +!!! warning - ``` - python -m caimira.api.app - ``` + The `ExpertApplication` and `CO2Application` are no longer actively maintained but will remain in the codebase for legacy purposes. + Please note that the functionality of these applications might be compromised due to deprecation issues. -2. The Tornado server will run on port `8081`. - -To test the API functionality, you can send a `POST` request to `http://localhost:8081/virus_report` with the required inputs in the request body. For an example of the required inputs, see [the baseline raw form data](https://gitlab.cern.ch/caimira/caimira/blob/master/caimira/src/caimira/calculator/validators/virus/virus_validator.py#L565). - -The response format will be: - -```json -{ - "status": "success", - "message": "Results generated successfully", - "report_data": { - ... - }, - ... -} -``` - -For further details please refer to the [REST API documentation page](../code/rest_api.md). - -#### Running the Expert-Apps - -The CAiMIRA Expert App and the CO2 App are tools to dynamically interact with various parameters of the CAiMIRA model. - -##### Disclaimer - -The `ExpertApplication` and `CO2Application` are no longer actively maintained but will remain in the codebase for legacy purposes. -Please note that the functionality of these applications might be compromised due to deprecation issues. - -##### Running the Applications +###### Running the Applications These applications only work within Jupyter notebooks. Attempting to run them outside of a Jupyter environment may result in errors or degraded functionality. -Make sure you have the needed dependencies installed: +1. **Install dependencies**: -``` -pip install notebook jupyterlab -``` + Install Jupyter Notebook and JupyterLab to use the applications: -Running with Visual Studio Code (VSCode): + pip install notebook jupyterlab -1. Ensure you have the following extensions installed in VSCode: `Jupyter` and `Python`. +2. **Run with Visual Studio Code**: -2. Open VSCode and navigate to the directory containing the notebook. + - Ensure you have the following extensions installed in VSCode: `Jupyter` and `Python`. -3. Open the notebook (e.g. `caimira/apps/expert/caimira.ipynb`) and run the cells by clicking the `run` button next to each cell. + - Open VSCode and navigate to the directory containing the notebook. + - Open the notebook (e.g. `caimira/apps/expert/caimira.ipynb`) and run the cells by clicking the `run` button next to each cell. -### Installing and running tests +##### API app -The project contains test files that separately test the functionality of the `caimira` backend and `cern_caimira` UI. +CAiMIRA includes a REST API for programmatic interaction with its models. The following steps describe how to run and test the API locally. -To test the `caimira` package, from the root repository of the project: +1. **Run the backend API**: + + python -m caimira.api.app -``` -cd caimira -pip install -e .[test] -python -m pytest -``` + The Tornado server will be accessible on port `8081`. -To test the `cern_caimira` package, from the root repository of the project: +2. **Test the API**: -``` -cd cern_caimira -pip install -e .[test] -python -m pytest -``` + Send a `POST` request to `http://localhost:8081/virus_report` with the required inputs in the body. Example request formats can be found in the [Virus Validator Code](https://gitlab.cern.ch/caimira/caimira/blob/master/caimira/src/caimira/calculator/validators/virus/virus_validator.py#L565). -### Running the profiler +3. **Example Response**: + A successful response will return data in the following format: + + !!! success + { + "status": "success", + "message": "Results generated successfully", + "report_data": { + ... + }, + ... + } + + For further details please refer to the [REST API documentation page](../code/rest_api.md). + +#### Tests + +CAiMIRA includes a suite of tests to validate the functionality of both its backend (`caimira` package) and UI components (`cern_caimira` package). + +1. **Testing the backend (`caimira` package)**: + + Install test dependencies and run the tests. From the root directory run: + + cd caimira + pip install -e .[test] + python -m pytest + +2. **Testing the UI (`cern_caimira` package)**: + + Install test dependencies and run the tests. From the root directory run: + + cd cern_caimira + pip install -e .[test] + python -m pytest + +#### Profiler CAiMIRA includes a profiler designed to identify performance bottlenecks. The profiler is enabled when the environment variable `CAIMIRA_PROFILER_ENABLED` is set to 1. @@ -194,25 +230,25 @@ Keep the profiler page open. Then, in another window, navigate to any page in CA The sessions are stored in a local file in the `/tmp` folder. To share it across multiple web nodes, a shared storage should be added to all web nodes. The folder can be customized via the environment variable `CAIMIRA_PROFILER_CACHE_DIR`. -### Compiling and viewing the docs +#### Docs -To compile and view CAiMIRA's documentation, follow these steps: +CAiMIRA includes comprehensive documentation, which can be compiled and viewed locally: -1. Install CAiMIRA with Documentation Dependencies +1. **Install CAiMIRA with documentation dependencies**: First, ensure CAiMIRA is installed along with the `doc` dependencies: cd caimira pip install -e .[doc] -2. Generate Code Documentation in Markdown +2. **Generate code documentation in markdown**: Use `sphinx` with `sphinx_markdown_builder` to generate the documentation in `Markdown` format: cd docs/sphinx sphinx-build -b markdown . _build/markdown -3. Customize and Organize Documentation +3. **Customize and organize documentation**: Run the `style_docs.py` script to apply custom styles, move required files, and generate a UML diagram: @@ -220,7 +256,7 @@ To compile and view CAiMIRA's documentation, follow these steps: && mv sphinx/_build/markdown/index.md mkdocs/docs/code/models.md \ && pyreverse -o png -p UML-CAiMIRA --output-directory mkdocs/docs ../src/caimira/calculator/models/models.py -4. Start the documentation server +4. **Start the documentation server**: To view the documentation locally, use MkDocs to serve it: @@ -228,3 +264,55 @@ To compile and view CAiMIRA's documentation, follow these steps: python -m mkdocs serve --dev-addr=0.0.0.0:8080 The documentation can now be accessed at [http://0.0.0.0:8080/](http://0.0.0.0:8080/). + +### Setting up the full environment + +This section outlines the steps to build and run the full CAiMIRA environment locally using Docker. It provides instructions for creating the necessary Docker images, configuring authentication, and running the application with Docker Compose. + +#### Prerequisites + +After following what is described in the main [prerequisites](#prerequisites) section, ensure the following tools are installed and properly configured: + +1. **CAiMIRA repository**: Can be cloned from the official GitLab repository [here](https://gitlab.cern.ch/caimira/caimira). +2. **Docker**: Download from the [Docker's official website](https://www.docker.com/products/docker-desktop/). +3. **Docker Compose**: Instructions on [DockerDocks official page](https://docs.docker.com/compose/install/). + +#### Build and run + +To build and run the environment, the following steps can be performed from the root directory of the project: + +1. **Build Docker Images**: + + To build the full environment for local development, from the root directory of the project, run: + + docker build -f app-config/api-app/Dockerfile -t api-app . + docker build -f app-config/calculator-app/Dockerfile -t calculator-app . + docker build ./app-config/auth-service -t auth-service + + For systems with ARM CPUs (e.g. Mac M1/M2/M3), the argument `--platform linux/arm64` should be appended to each `docker build` command. + For more verbose output during the Docker build process, additional arguments `no-cache --progress=plain` can be include to each command. + +2. **Obtain the Client Secret**: + + The client secret for the `caimira-test` application must be retrieved from the CERN Application Portal. Further details can be found in the[CERN-SSO-integration](deployment.md#cern-sso-integration) documentation. + + read CLIENT_SECRET + +3. **Set Environment Variables**: + + Required environment variables can be defined as follows (copy/paste): + + export COOKIE_SECRET=$(openssl rand -hex 50) + export OIDC_SERVER=https://auth.cern.ch/auth + export OIDC_REALM=CERN + export CLIENT_ID=caimira-test + export CLIENT_SECRET=$CLIENT_SECRET + +4. **Run the Application**: + + Start the application using Docker Compose running in the root directory: + + cd app-config + CURRENT_UID=$(id -u):$(id -g) docker compose up + + Then visit [http://localhost:8080/](http://localhost:8080/). diff --git a/caimira/docs/mkdocs/mkdocs.yml b/caimira/docs/mkdocs/mkdocs.yml index 0ff9de5f..4a9240c1 100644 --- a/caimira/docs/mkdocs/mkdocs.yml +++ b/caimira/docs/mkdocs/mkdocs.yml @@ -31,7 +31,7 @@ markdown_extensions: - pymdownx.arithmatex: generic: true - toc: - toc_depth: '1-3' + toc_depth: '1-4' - admonition - pymdownx.details - attr_list diff --git a/caimira/src/caimira/api/app.py b/caimira/src/caimira/api/app.py index fcb7d4bd..5a5aec32 100644 --- a/caimira/src/caimira/api/app.py +++ b/caimira/src/caimira/api/app.py @@ -7,22 +7,17 @@ import tornado.ioloop import tornado.web import tornado.log import logging - -from caimira.api.routes.report_routes import VirusReportHandler, CO2ReportHandler +from caimira.api.routes.routes import routes logging.basicConfig(format="%(message)s", level=logging.INFO) class Application(tornado.web.Application): def __init__(self, debug): - handlers = [ - (r"/co2_report", CO2ReportHandler), - (r"/virus_report", VirusReportHandler), - ] settings = dict( debug=debug, ) - super().__init__(handlers, **settings) + super().__init__(routes, **settings) if __name__ == "__main__": diff --git a/caimira/src/caimira/api/routes/base_handler.py b/caimira/src/caimira/api/routes/base_handler.py new file mode 100644 index 00000000..f9044964 --- /dev/null +++ b/caimira/src/caimira/api/routes/base_handler.py @@ -0,0 +1,13 @@ +import tornado.web + + +class BaseRequestHandler(tornado.web.RequestHandler): + def set_default_headers(self): + self.set_header("Access-Control-Allow-Origin", "*") + self.set_header("Access-Control-Allow-Headers", "x-requested-with") + self.set_header("Access-Control-Allow-Methods", "POST, GET, OPTIONS") + + def write_error(self, status_code, **kwargs): + self.set_status(status_code) + self.write({"message": kwargs.get('exc_info')[1].__str__()}) + \ No newline at end of file diff --git a/caimira/src/caimira/api/routes/landing_routes.py b/caimira/src/caimira/api/routes/landing_routes.py new file mode 100644 index 00000000..19fda565 --- /dev/null +++ b/caimira/src/caimira/api/routes/landing_routes.py @@ -0,0 +1,11 @@ +from caimira.api.routes.base_handler import BaseRequestHandler + +from caimira import __version__ + + +class LandingPageHandler(BaseRequestHandler): + def get(self): + self.write("

Welcome to the CAiMIRA REST API

") + self.write(f"

Code Version: {__version__}

") + self.write("

Official GitLab: https://gitlab.cern.ch/caimira/caimira

") + self.write("

Documentation: https://caimira.docs.cern.ch/

") diff --git a/caimira/src/caimira/api/routes/report_routes.py b/caimira/src/caimira/api/routes/report_routes.py index aa38b297..61ae80b6 100644 --- a/caimira/src/caimira/api/routes/report_routes.py +++ b/caimira/src/caimira/api/routes/report_routes.py @@ -1,24 +1,12 @@ import json import traceback -import tornado.web import sys - +from caimira.api.routes.base_handler import BaseRequestHandler from caimira.api.controller.virus_report_controller import submit_virus_form from caimira.api.controller.co2_report_controller import submit_CO2_form -class BaseReportHandler(tornado.web.RequestHandler): - def set_default_headers(self): - self.set_header("Access-Control-Allow-Origin", "*") - self.set_header("Access-Control-Allow-Headers", "x-requested-with") - self.set_header("Access-Control-Allow-Methods", "POST, GET, OPTIONS") - - def write_error(self, status_code, **kwargs): - self.set_status(status_code) - self.write({"message": kwargs.get('exc_info')[1].__str__()}) - - -class VirusReportHandler(BaseReportHandler): +class VirusReportHandler(BaseRequestHandler): def post(self): try: form_data = json.loads(self.request.body) @@ -43,7 +31,7 @@ class VirusReportHandler(BaseReportHandler): self.write_error(status_code=400, exc_info=sys.exc_info()) -class CO2ReportHandler(BaseReportHandler): +class CO2ReportHandler(BaseRequestHandler): def post(self): try: form_data = json.loads(self.request.body) diff --git a/caimira/src/caimira/api/routes/routes.py b/caimira/src/caimira/api/routes/routes.py new file mode 100644 index 00000000..9334c4f6 --- /dev/null +++ b/caimira/src/caimira/api/routes/routes.py @@ -0,0 +1,8 @@ +from caimira.api.routes.landing_routes import LandingPageHandler +from caimira.api.routes.report_routes import VirusReportHandler, CO2ReportHandler + +routes = [ + (r"/", LandingPageHandler), + (r"/co2_report", CO2ReportHandler), + (r"/virus_report", VirusReportHandler), +] diff --git a/caimira/src/caimira/calculator/validators/co2/co2_validator.py b/caimira/src/caimira/calculator/validators/co2/co2_validator.py index 43ea6b7a..7b9185ab 100644 --- a/caimira/src/caimira/calculator/validators/co2/co2_validator.py +++ b/caimira/src/caimira/calculator/validators/co2/co2_validator.py @@ -24,11 +24,12 @@ class CO2FormData(FormData): fitting_ventilation_states: list room_capacity: typing.Optional[int] - #: The default values for undefined fields. Note that the defaults here - #: and the defaults in the html form must not be contradictory. + # The default values for undefined fields. Note that the defaults here + # and the defaults in any html form must not be contradictory. _DEFAULTS: typing.ClassVar[typing.Dict[str, typing.Any]] = { 'CO2_data': '{}', - 'fitting_ventilation_states': '[]', + 'dynamic_infected_occupancy': '[]', + 'dynamic_exposed_occupancy': '[]', 'exposed_coffee_break_option': 'coffee_break_0', 'exposed_coffee_duration': 5, 'exposed_finish': '17:30', @@ -36,6 +37,7 @@ class CO2FormData(FormData): 'exposed_lunch_option': True, 'exposed_lunch_start': '12:30', 'exposed_start': '08:30', + 'fitting_ventilation_states': '[]', 'infected_coffee_break_option': 'coffee_break_0', 'infected_coffee_duration': 5, 'infected_dont_have_breaks_with_exposed': False, @@ -44,14 +46,12 @@ class CO2FormData(FormData): 'infected_lunch_option': True, 'infected_lunch_start': '12:30', 'infected_people': 1, - 'dynamic_infected_occupancy': '[]', 'infected_start': '08:30', + 'occupancy_format': 'static', 'room_capacity': None, 'room_volume': NO_DEFAULT, 'specific_breaks': '{}', 'total_people': NO_DEFAULT, - 'dynamic_exposed_occupancy': '[]', - 'occupancy_format': 'static', } def __init__(self, **kwargs): diff --git a/caimira/src/caimira/calculator/validators/defaults.py b/caimira/src/caimira/calculator/validators/defaults.py index bd14db38..604617c0 100644 --- a/caimira/src/caimira/calculator/validators/defaults.py +++ b/caimira/src/caimira/calculator/validators/defaults.py @@ -7,16 +7,18 @@ NO_DEFAULT = object() #: The default values for undefined fields. Note that the defaults here #: and the defaults in the html form must not be contradictory. DEFAULTS = { + 'CO2_fitting_result': '{}', 'activity_type': 'office', 'air_changes': 0., 'air_supply': 0., 'arve_sensors_option': False, - 'specific_breaks': '{}', - 'precise_activity': '{}', + 'ascertainment_bias': 'confidence_low', 'calculator_version': NO_DEFAULT, 'ceiling_height': 0., 'conditional_probability_viral_loads': False, - 'CO2_fitting_result': '{}', + 'dynamic_exposed_occupancy': '[]', + 'dynamic_infected_occupancy': '[]', + 'event_month': 'January', 'exposed_coffee_break_option': 'coffee_break_0', 'exposed_coffee_duration': 5, 'exposed_finish': '17:30', @@ -24,8 +26,10 @@ DEFAULTS = { 'exposed_lunch_option': True, 'exposed_lunch_start': '12:30', 'exposed_start': '08:30', - 'event_month': 'January', + 'exposure_option': 'p_deterministic_exposure', 'floor_area': 0., + 'geographic_cases': 0, + 'geographic_population': 0, 'hepa_amount': 0., 'hepa_option': False, 'humidity': '', @@ -37,45 +41,41 @@ DEFAULTS = { 'infected_lunch_option': True, 'infected_lunch_start': '12:30', 'infected_people': 1, - 'dynamic_infected_occupancy': NO_DEFAULT, 'infected_start': '08:30', 'inside_temp': NO_DEFAULT, 'location_latitude': NO_DEFAULT, 'location_longitude': NO_DEFAULT, 'location_name': NO_DEFAULT, - 'geographic_population': 0, - 'geographic_cases': 0, - 'ascertainment_bias': 'confidence_low', - 'exposure_option': 'p_deterministic_exposure', 'mask_type': 'Type I', 'mask_wearing_option': 'mask_off', 'mechanical_ventilation_type': 'not-applicable', 'occupancy_format': 'static', 'opening_distance': 0., + 'precise_activity': '{}', 'room_heating_option': False, 'room_number': NO_DEFAULT, 'room_volume': 0., + 'sensor_in_use': '', + 'short_range_interactions': '[]', + 'short_range_occupants': 0, + 'short_range_option': 'short_range_no', 'simulation_name': NO_DEFAULT, + 'specific_breaks': '{}', 'total_people': NO_DEFAULT, - 'dynamic_exposed_occupancy': NO_DEFAULT, - 'vaccine_option': False, 'vaccine_booster_option': False, - 'vaccine_type': 'AZD1222_(AstraZeneca)', 'vaccine_booster_type': 'AZD1222_(AstraZeneca)', + 'vaccine_option': False, + 'vaccine_type': 'AZD1222_(AstraZeneca)', 'ventilation_type': 'no_ventilation', 'virus_type': 'SARS_CoV_2', 'volume_type': NO_DEFAULT, - 'window_type': 'window_sliding', 'window_height': 0., + 'window_opening_regime': 'windows_open_permanently', + 'window_type': 'window_sliding', 'window_width': 0., 'windows_duration': 10., 'windows_frequency': 60., - 'windows_number': 0, - 'window_opening_regime': 'windows_open_permanently', - 'sensor_in_use': '', - 'short_range_option': 'short_range_no', - 'short_range_interactions': NO_DEFAULT, - 'short_range_occupants': 0, + 'windows_number': 0 } # ------------------ Activities ---------------------- @@ -98,8 +98,8 @@ VACCINE_BOOSTER_TYPE = ['AZD1222_(AstraZeneca)', 'Ad26.COV2.S_(Janssen)', 'BNT16 VACCINE_TYPE = ['Ad26.COV2.S_(Janssen)', 'Any_mRNA_-_heterologous', 'AZD1222_(AstraZeneca)', 'AZD1222_(AstraZeneca)_and_any_mRNA_-_heterologous', 'AZD1222_(AstraZeneca)_and_BNT162b2_(Pfizer)', 'BBIBP-CorV_(Beijing_CNBG)', 'BNT162b2_(Pfizer)', 'BNT162b2_(Pfizer)_and_mRNA-1273_(Moderna)', 'CoronaVac_(Sinovac)', 'CoronaVac_(Sinovac)_and_AZD1222_(AstraZeneca)', 'Covishield', 'mRNA-1273_(Moderna)', 'Sputnik_V_(Gamaleya)', 'CoronaVac_(Sinovac)_and_BNT162b2_(Pfizer)'] -VENTILATION_TYPES = {'natural_ventilation', 'mechanical_ventilation', - 'no_ventilation', 'from_fitting'} +VENTILATION_TYPES = {'from_fitting', 'natural_ventilation', + 'mechanical_ventilation', 'no_ventilation'} VOLUME_TYPES = {'room_volume_explicit', 'room_volume_from_dimensions'} WINDOWS_OPENING_REGIMES = {'windows_open_permanently', 'windows_open_periodically', 'not-applicable'} diff --git a/caimira/src/caimira/calculator/validators/virus/virus_validator.py b/caimira/src/caimira/calculator/validators/virus/virus_validator.py index ca491b7f..80eec891 100644 --- a/caimira/src/caimira/calculator/validators/virus/virus_validator.py +++ b/caimira/src/caimira/calculator/validators/virus/virus_validator.py @@ -22,53 +22,53 @@ minutes_since_midnight = typing.NewType('minutes_since_midnight', int) @dataclasses.dataclass class VirusFormData(FormData): + ascertainment_bias: str activity_type: str air_changes: float air_supply: float arve_sensors_option: bool - precise_activity: dict + calculator_version: str ceiling_height: float - conditional_probability_viral_loads: bool CO2_fitting_result: dict + conditional_probability_viral_loads: bool + event_month: str + exposure_option: str floor_area: float + geographic_cases: int + geographic_population: int hepa_amount: float hepa_option: bool humidity: str inside_temp: float - location_name: str location_latitude: float location_longitude: float - geographic_population: int - geographic_cases: int - ascertainment_bias: str - exposure_option: str + location_name: str mask_type: str mask_wearing_option: str mechanical_ventilation_type: str - calculator_version: str opening_distance: float - event_month: str + precise_activity: dict room_heating_option: bool room_number: str + sensor_in_use: str + short_range_interactions: list + short_range_occupants: int + short_range_option: str simulation_name: str - vaccine_option: bool vaccine_booster_option: bool - vaccine_type: str vaccine_booster_type: str + vaccine_option: bool + vaccine_type: str ventilation_type: str virus_type: str volume_type: str - windows_duration: float - windows_frequency: float window_height: float + window_opening_regime: str window_type: str window_width: float + windows_duration: float + windows_frequency: float windows_number: int - window_opening_regime: str - sensor_in_use: str - short_range_option: str - short_range_interactions: list - short_range_occupants: int _DEFAULTS: typing.ClassVar[typing.Dict[str, typing.Any]] = DEFAULTS @@ -77,21 +77,18 @@ class VirusFormData(FormData): self.validate_population_parameters() validation_tuples = [('activity_type', self.data_registry.population_scenario_activity.keys()), - ('mechanical_ventilation_type', - MECHANICAL_VENTILATION_TYPES), - ('mask_type', list(mask_distributions( - self.data_registry).keys())), + ('ascertainment_bias', CONFIDENCE_LEVEL_OPTIONS), + ('event_month', MONTH_NAMES), + ('mechanical_ventilation_type', MECHANICAL_VENTILATION_TYPES), + ('mask_type', list(mask_distributions(self.data_registry).keys())), ('mask_wearing_option', MASK_WEARING_OPTIONS), + ('vaccine_type', VACCINE_TYPE), + ('vaccine_booster_type', VACCINE_BOOSTER_TYPE), ('ventilation_type', VENTILATION_TYPES), - ('virus_type', list(virus_distributions( - self.data_registry).keys())), + ('virus_type', list(virus_distributions(self.data_registry).keys())), ('volume_type', VOLUME_TYPES), ('window_opening_regime', WINDOWS_OPENING_REGIMES), - ('window_type', WINDOWS_TYPES), - ('event_month', MONTH_NAMES), - ('ascertainment_bias', CONFIDENCE_LEVEL_OPTIONS), - ('vaccine_type', VACCINE_TYPE), - ('vaccine_booster_type', VACCINE_BOOSTER_TYPE),] + ('window_type', WINDOWS_TYPES)] for attr_name, valid_set in validation_tuples: if getattr(self, attr_name) not in valid_set: @@ -569,6 +566,7 @@ def baseline_raw_form_data() -> typing.Dict[str, typing.Union[str, float]]: 'air_changes': '', 'air_supply': '', 'ascertainment_bias': 'confidence_low', + 'calculator_version': calculator_version, 'ceiling_height': '', 'conditional_probability_viral_loads': '0', 'dynamic_exposed_occupancy': '[]', @@ -603,9 +601,8 @@ def baseline_raw_form_data() -> typing.Dict[str, typing.Union[str, float]]: 'mask_type': 'Type I', 'mask_wearing_option': 'mask_off', 'mechanical_ventilation_type': '', - 'calculator_version': calculator_version, - 'opening_distance': '0.2', 'occupancy_format': 'static', + 'opening_distance': '0.2', 'room_heating_option': '0', 'room_number': '123', 'room_volume': '75', @@ -622,12 +619,11 @@ def baseline_raw_form_data() -> typing.Dict[str, typing.Union[str, float]]: 'volume_type': 'room_volume_explicit', 'window_height': '2', 'window_opening_regime': 'windows_open_permanently', + 'window_type': 'window_sliding', + 'window_width': '2', 'windows_duration': '10', 'windows_frequency': '60', 'windows_number': '1', - 'window_type': 'window_sliding', - 'window_width': '2', } - cast_class_fields(VirusFormData) diff --git a/cern_caimira/tests/test_report_generator.py b/cern_caimira/tests/test_report_generator.py index f15833a2..138f2a2b 100644 --- a/cern_caimira/tests/test_report_generator.py +++ b/cern_caimira/tests/test_report_generator.py @@ -116,7 +116,6 @@ def test_expected_new_cases(baseline_form_with_sr: VirusFormData): sr_lr_prob_inf = report_data['prob_inf']/100 # Long-range contributions alone - scenario_sample_times = report_data['times'] alternative_scenarios = rep_gen.manufacture_alternative_scenarios(baseline_form_with_sr) alternative_statistics = rep_gen.comparison_report( baseline_form_with_sr, report_data, alternative_scenarios, executor_factory=executor_factory,