From 69be61d3b4593936222016cdcd08e4c9e91d2a27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wiebke=20K=C3=B6pp?= Date: Mon, 25 Sep 2023 11:54:04 -0700 Subject: [PATCH 1/8] Ignore differently named Python envs --- .gitignore | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index cc60ece6..5a4b6368 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 From 5edaa6e5774a286e218fc87d8ece365185fba4d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wiebke=20K=C3=B6pp?= Date: Mon, 25 Sep 2023 11:59:15 -0700 Subject: [PATCH 2/8] Rename env-key for Tiled access --- README.md | 2 +- docker-compose.yml | 2 +- utils/data_utils.py | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 267c6add..63c84fa2 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ pip install -r requirements-dev.txt ``` TILED_URI='https://mlex-segmentation.als.lbl.gov' -API_KEY= +TILED_API_KEY= MODE='dev' ``` diff --git a/docker-compose.yml b/docker-compose.yml index 20be981f..49ecc032 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -7,7 +7,7 @@ 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 - ./callbacks:/app/callbacks diff --git a/utils/data_utils.py b/utils/data_utils.py index 965293da..0a031369 100644 --- a/utils/data_utils.py +++ b/utils/data_utils.py @@ -126,7 +126,7 @@ 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`.") @@ -136,7 +136,7 @@ def save_annotations_data(global_store, all_annotations, project_name): 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"] From 64156fc60067a848ae7b8a32c918651adc138676 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wiebke=20K=C3=B6pp?= Date: Mon, 25 Sep 2023 18:02:37 -0700 Subject: [PATCH 3/8] Make `EXPORT_FILE_PATH` an environment variable --- callbacks/control_bar.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/callbacks/control_bar.py b/callbacks/control_bar.py index 94e7312e..6dc74acd 100644 --- a/callbacks/control_bar.py +++ b/callbacks/control_bar.py @@ -31,8 +31,8 @@ ) # 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") # Create an empty file if it doesn't exist if not os.path.exists(EXPORT_FILE_PATH): From 37cd758601fd4aba8f0aab1171860b7d03957457 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wiebke=20K=C3=B6pp?= Date: Mon, 25 Sep 2023 18:03:25 -0700 Subject: [PATCH 4/8] Add basic dash auth --- app.py | 10 ++++++++++ callbacks/control_bar.py | 2 +- requirements.txt | 3 ++- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/app.py b/app.py index 49124838..10c2ae01 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,16 @@ 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 +auth = dash_auth.BasicAuth(app, VALID_USER_NAME_PASSWORD_PAIRS) + app.layout = dmc.MantineProvider( theme={"colorScheme": "light"}, children=[ diff --git a/callbacks/control_bar.py b/callbacks/control_bar.py index 6dc74acd..f9f1f531 100644 --- a/callbacks/control_bar.py +++ b/callbacks/control_bar.py @@ -31,8 +31,8 @@ ) # TODO - temporary local file path and user for annotation saving and exporting -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/requirements.txt b/requirements.txt index 813ed1e4..fbac106e 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 From 8be41bc9470b195c7ddf9f4d6a5565cce3b49b11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wiebke=20K=C3=B6pp?= Date: Tue, 26 Sep 2023 06:53:41 -0700 Subject: [PATCH 5/8] Add constants file to docker-compose --- docker-compose.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/docker-compose.yml b/docker-compose.yml index 49ecc032..2df3d43a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -10,6 +10,7 @@ services: 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 From 31cfb262a167d3f89150f65fa36f8b8e47bb0e87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wiebke=20K=C3=B6pp?= Date: Tue, 26 Sep 2023 07:00:09 -0700 Subject: [PATCH 6/8] Update Readme with new Tiled URI and additional variables --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 63c84fa2..e09bd4b9 100644 --- a/README.md +++ b/README.md @@ -23,12 +23,14 @@ 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' +TILED_URI='https://tiled-seg.als.lbl.gov' TILED_API_KEY= MODE='dev' +USER_NAME= +USER_PASSWORD= ``` 3. Start a local server: From fdff0d57c0f5c19ff4f17f83e9298ebf78681a94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wiebke=20K=C3=B6pp?= Date: Fri, 29 Sep 2023 17:24:09 -0700 Subject: [PATCH 7/8] :passport_control: Disable authentication for local testing --- README.md | 12 ++++++++++-- app.py | 7 ++++++- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index e09bd4b9..233795b5 100644 --- a/README.md +++ b/README.md @@ -28,9 +28,8 @@ pip install -r requirements-dev.txt ``` TILED_URI='https://tiled-seg.als.lbl.gov' TILED_API_KEY= +DASH_DEPLOYMENT_LOC='Local' MODE='dev' -USER_NAME= -USER_PASSWORD= ``` 3. Start a local server: @@ -50,6 +49,15 @@ To start local tiled connection: 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 10c2ae01..7d017d81 100644 --- a/app.py +++ b/app.py @@ -18,7 +18,12 @@ app = Dash(__name__) server = app.server -auth = dash_auth.BasicAuth(app, VALID_USER_NAME_PASSWORD_PAIRS) +# 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"}, From 3b300baec2c6c39209f929fdca34fe6e0f8a63a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wiebke=20K=C3=B6pp?= Date: Fri, 29 Sep 2023 17:24:49 -0700 Subject: [PATCH 8/8] Use a script to startup local Tiled server with an api key --- README.md | 4 ++-- tiled_serve_dir.sh | 4 ++++ utils/data_utils.py | 4 ++-- 3 files changed, 8 insertions(+), 4 deletions(-) create mode 100755 tiled_serve_dir.sh diff --git a/README.md b/README.md index 233795b5..7002453f 100644 --- a/README.md +++ b/README.md @@ -43,9 +43,9 @@ 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. diff --git a/tiled_serve_dir.sh b/tiled_serve_dir.sh new file mode 100755 index 00000000..9504a8cc --- /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 0a031369..e745c843 100644 --- a/utils/data_utils.py +++ b/utils/data_utils.py @@ -128,8 +128,8 @@ def save_annotations_data(global_store, all_annotations, project_name): TILED_URI = os.getenv("TILED_URI") 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()