diff --git a/.gitignore b/.gitignore index cc60ece..5a4b636 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,7 @@ pri-venv data/ env +*env/ *.hdf5 *.db @@ -22,5 +23,4 @@ env *.tiff *.tif -.env -config.py +.env \ No newline at end of file diff --git a/README.md b/README.md index 267c6ad..7002453 100644 --- a/README.md +++ b/README.md @@ -23,11 +23,12 @@ and pip install -r requirements-dev.txt ``` -2. Configure a connection to the Tiled server via a `.env` file with the following environment variables: +2. Set environment variables via a `.env` file to configure a connection to the Tiled server, differentiate between local testing and development mode and set a user and password for basic autherization: ``` -TILED_URI='https://mlex-segmentation.als.lbl.gov' -API_KEY= +TILED_URI='https://tiled-seg.als.lbl.gov' +TILED_API_KEY= +DASH_DEPLOYMENT_LOC='Local' MODE='dev' ``` @@ -42,12 +43,21 @@ python app.py Developers may also choose to set up a local Tiled server with access to minimal datasets (eg. in the case that the remote server is down). To start local tiled connection: -1. Add `SERVE_LOCALLY=True` flag to `.env` file (or to your environmental variables) +1. Add `TILED_DEPLOYMENT_LOC="Local"` flag to `.env` file (or to your environmental variables) 2. Start the app once, which will create `data/` directory and download 2 sample projects with 2 images each. -3. Open a second terminal and run `tiled serve directory --public data`. +3. Open a second terminal and run `/tiled_serve_dir.sh`. The app will now connect to the local tiled server. +### Deployment elsewhere + +For deployment elsewhere add a user name and password to the environment file and remove `DASH_DEPLOYMENT_LOC = "Local"`. This protect access to the application with basic authentication: + +``` +USER_NAME= +USER_PASSWORD= +``` + # Copyright MLExchange Copyright (c) 2023, The Regents of the University of California, through Lawrence Berkeley National Laboratory (subject to receipt of any required approvals from the U.S. Dept. of Energy). All rights reserved. diff --git a/app.py b/app.py index 4912483..7d017d8 100644 --- a/app.py +++ b/app.py @@ -1,3 +1,6 @@ +import os + +import dash_auth import dash_mantine_components as dmc from dash import Dash, dcc @@ -7,9 +10,21 @@ from components.control_bar import layout as control_bar_layout from components.image_viewer import layout as image_viewer_layout +USER_NAME = os.getenv("USER_NAME") +USER_PASSWORD = os.getenv("USER_PASSWORD") + +VALID_USER_NAME_PASSWORD_PAIRS = {USER_NAME: USER_PASSWORD} + app = Dash(__name__) server = app.server +# Set single user name password pair if deployment isn't +auth = ( + dash_auth.BasicAuth(app, VALID_USER_NAME_PASSWORD_PAIRS) + if os.getenv("DASH_DEPLOYMENT_LOC", "") != "Local" + else None +) + app.layout = dmc.MantineProvider( theme={"colorScheme": "light"}, children=[ diff --git a/callbacks/control_bar.py b/callbacks/control_bar.py index 709d1c7..fdec18b 100644 --- a/callbacks/control_bar.py +++ b/callbacks/control_bar.py @@ -32,8 +32,8 @@ from utils.plot_utils import generate_notification, generate_notification_bg_icon_col # TODO - temporary local file path and user for annotation saving and exporting -EXPORT_FILE_PATH = "data/exported_annotation_data.json" -USER_NAME = "user1" +EXPORT_FILE_PATH = os.getenv("EXPORT_FILE_PATH", "data/exported_annotation_data.json") +USER_NAME = os.getenv("USER_NAME", "user1") # Create an empty file if it doesn't exist if not os.path.exists(EXPORT_FILE_PATH): diff --git a/docker-compose.yml b/docker-compose.yml index 20be981..2df3d43 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -7,9 +7,10 @@ services: command: 'gunicorn -b 0.0.0.0:8075 --reload app:server' environment: TILED_URI: '${TILED_URI}' - API_KEY: '${API_KEY}' + TILED_API_KEY: '${TILED_API_KEY}' volumes: - ./app.py:/app/app.py + - ./constants.py:/app/constants.py - ./callbacks:/app/callbacks - ./components:/app/components - ./utils:/app/utils diff --git a/requirements.txt b/requirements.txt index 813ed1e..fbac106 100644 --- a/requirements.txt +++ b/requirements.txt @@ -31,4 +31,5 @@ svgpathtools matplotlib scipy dash-extensions==1.0.1 -dash-bootstrap-components==1.5.0 \ No newline at end of file +dash-bootstrap-components==1.5.0 +dash_auth==2.0.0 \ No newline at end of file diff --git a/tiled_serve_dir.sh b/tiled_serve_dir.sh new file mode 100755 index 0000000..9504a8c --- /dev/null +++ b/tiled_serve_dir.sh @@ -0,0 +1,4 @@ +#!/bin/bash +source .env +export TILED_SINGLE_USER_API_KEY=$TILED_API_KEY +tiled serve directory data \ No newline at end of file diff --git a/utils/data_utils.py b/utils/data_utils.py index 965293d..e745c84 100644 --- a/utils/data_utils.py +++ b/utils/data_utils.py @@ -126,17 +126,17 @@ def save_annotations_data(global_store, all_annotations, project_name): load_dotenv() TILED_URI = os.getenv("TILED_URI") -API_KEY = os.getenv("API_KEY") +TILED_API_KEY = os.getenv("TILED_API_KEY") -if os.getenv("SERVE_LOCALLY", False): - print("To run a Tiled server locally run `tiled serve directory --public data`.") +if os.getenv("TILED_DEPLOYMENT_LOC", "") == "Local": + print("To run a Tiled server locally run the bash script `./tiled_serve_dir.sh`.") print("This requires to additionally install the server components of Tiled with:") print('`pip install "tiled[server]"`') DEV_download_google_sample_data() client = from_uri("http://localhost:8000") data = client else: - client = from_uri(TILED_URI, api_key=API_KEY, timeout=httpx.Timeout(30.0)) + client = from_uri(TILED_URI, api_key=TILED_API_KEY, timeout=httpx.Timeout(30.0)) data = client["reconstruction"]