dsa-helpers 0.4.dev0__tar.gz → 0.4.dev2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {dsa_helpers-0.4.dev0/dsa_helpers.egg-info → dsa_helpers-0.4.dev2}/PKG-INFO +1 -1
- {dsa_helpers-0.4.dev0 → dsa_helpers-0.4.dev2}/dsa_helpers/dash/header.py +31 -21
- dsa_helpers-0.4.dev2/dsa_helpers/dash/header_callbacks.py +99 -0
- {dsa_helpers-0.4.dev0 → dsa_helpers-0.4.dev2}/dsa_helpers/mongo_utils.py +8 -10
- {dsa_helpers-0.4.dev0 → dsa_helpers-0.4.dev2/dsa_helpers.egg-info}/PKG-INFO +1 -1
- {dsa_helpers-0.4.dev0 → dsa_helpers-0.4.dev2}/pyproject.toml +1 -1
- dsa_helpers-0.4.dev2/tests/test.ipynb +79 -0
- dsa_helpers-0.4.dev0/dsa_helpers/dash/header_callbacks.py +0 -98
- dsa_helpers-0.4.dev0/tests/test.ipynb +0 -268
- {dsa_helpers-0.4.dev0 → dsa_helpers-0.4.dev2}/.gitignore +0 -0
- {dsa_helpers-0.4.dev0 → dsa_helpers-0.4.dev2}/LICENSE +0 -0
- {dsa_helpers-0.4.dev0 → dsa_helpers-0.4.dev2}/README.md +0 -0
- {dsa_helpers-0.4.dev0 → dsa_helpers-0.4.dev2}/app.py +0 -0
- {dsa_helpers-0.4.dev0 → dsa_helpers-0.4.dev2}/dsa_helpers/__init__.py +0 -0
- {dsa_helpers-0.4.dev0 → dsa_helpers-0.4.dev2}/dsa_helpers/dash/__init__.py +0 -0
- {dsa_helpers-0.4.dev0 → dsa_helpers-0.4.dev2}/dsa_helpers/girder_utils.py +0 -0
- {dsa_helpers-0.4.dev0 → dsa_helpers-0.4.dev2}/dsa_helpers/image_utils.py +0 -0
- {dsa_helpers-0.4.dev0 → dsa_helpers-0.4.dev2}/dsa_helpers/imread.py +0 -0
- {dsa_helpers-0.4.dev0 → dsa_helpers-0.4.dev2}/dsa_helpers/imwrite.py +0 -0
- {dsa_helpers-0.4.dev0 → dsa_helpers-0.4.dev2}/dsa_helpers/login.py +0 -0
- {dsa_helpers-0.4.dev0 → dsa_helpers-0.4.dev2}/dsa_helpers/ml/__init__.py +0 -0
- {dsa_helpers-0.4.dev0 → dsa_helpers-0.4.dev2}/dsa_helpers/ml/object_detection/__init__.py +0 -0
- {dsa_helpers-0.4.dev0 → dsa_helpers-0.4.dev2}/dsa_helpers/ml/object_detection/get_pearce_roi_images.py +0 -0
- {dsa_helpers-0.4.dev0 → dsa_helpers-0.4.dev2}/dsa_helpers/ml/object_detection/tile_image.py +0 -0
- {dsa_helpers-0.4.dev0 → dsa_helpers-0.4.dev2}/dsa_helpers/ml/object_detection/utils.py +0 -0
- {dsa_helpers-0.4.dev0 → dsa_helpers-0.4.dev2}/dsa_helpers.egg-info/SOURCES.txt +0 -0
- {dsa_helpers-0.4.dev0 → dsa_helpers-0.4.dev2}/dsa_helpers.egg-info/dependency_links.txt +0 -0
- {dsa_helpers-0.4.dev0 → dsa_helpers-0.4.dev2}/dsa_helpers.egg-info/requires.txt +0 -0
- {dsa_helpers-0.4.dev0 → dsa_helpers-0.4.dev2}/dsa_helpers.egg-info/top_level.txt +0 -0
- {dsa_helpers-0.4.dev0 → dsa_helpers-0.4.dev2}/readthedocs.yaml +0 -0
- {dsa_helpers-0.4.dev0 → dsa_helpers-0.4.dev2}/requirements.txt +0 -0
- {dsa_helpers-0.4.dev0 → dsa_helpers-0.4.dev2}/setup.cfg +0 -0
|
@@ -1,24 +1,37 @@
|
|
|
1
1
|
from dash import html, dcc
|
|
2
2
|
import dash_bootstrap_components as dbc
|
|
3
|
-
from . import
|
|
3
|
+
from .header_callbacks import get_callbacks
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
def get_header(
|
|
6
|
+
def get_header(
|
|
7
|
+
dsa_api_url: str,
|
|
8
|
+
title: str = "App",
|
|
9
|
+
store_id: str = "user-store",
|
|
10
|
+
config: dict | None = None,
|
|
11
|
+
) -> html.Div:
|
|
7
12
|
"""Get the Dash html component that contains the header of the application
|
|
8
13
|
with login capabilities.
|
|
9
14
|
|
|
10
15
|
Args:
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
16
|
+
dsa_api_url (str): The URL of the DSA API.
|
|
17
|
+
title (str, optional): The title of the application. Defaults to "App".
|
|
18
|
+
config (dict, optional): The configuration of the component. Defaults to None.
|
|
19
|
+
If None the default configuration is:
|
|
20
|
+
{
|
|
21
|
+
"backgroundColor": "#012169",
|
|
22
|
+
"titleColor": "#d9d9d6",
|
|
23
|
+
"fontColor": "#f2a900",
|
|
24
|
+
}
|
|
17
25
|
|
|
18
26
|
Returns:
|
|
19
27
|
html.Div: The header component.
|
|
20
28
|
|
|
21
29
|
"""
|
|
30
|
+
if config is None:
|
|
31
|
+
config = {}
|
|
32
|
+
|
|
33
|
+
get_callbacks(dsa_api_url, store_id)
|
|
34
|
+
|
|
22
35
|
login_modal = dbc.Modal(
|
|
23
36
|
[
|
|
24
37
|
dbc.ModalHeader("Log in"),
|
|
@@ -28,7 +41,7 @@ def get_header(title: str = "App", config: dict | None = None) -> html.Div:
|
|
|
28
41
|
"Login or email", style={"margin": 5, "fontWeight": "bold"}
|
|
29
42
|
),
|
|
30
43
|
dbc.Input(
|
|
31
|
-
id="login",
|
|
44
|
+
id=f"{store_id}=login",
|
|
32
45
|
type="text",
|
|
33
46
|
placeholder="Enter login",
|
|
34
47
|
style={"margin": 5},
|
|
@@ -38,7 +51,7 @@ def get_header(title: str = "App", config: dict | None = None) -> html.Div:
|
|
|
38
51
|
style={"margin": 5, "marginTop": 15, "fontWeight": "bold"},
|
|
39
52
|
),
|
|
40
53
|
dbc.Input(
|
|
41
|
-
id="password",
|
|
54
|
+
id=f"{store_id}=password",
|
|
42
55
|
type="password",
|
|
43
56
|
placeholder="Enter password",
|
|
44
57
|
style={"margin": 5},
|
|
@@ -46,7 +59,7 @@ def get_header(title: str = "App", config: dict | None = None) -> html.Div:
|
|
|
46
59
|
html.Div(
|
|
47
60
|
"Login failed.",
|
|
48
61
|
hidden=True,
|
|
49
|
-
id="login-failed",
|
|
62
|
+
id=f"{store_id}=login-failed",
|
|
50
63
|
style={"color": "red", "fontWeight": "bold", "margin": 10},
|
|
51
64
|
),
|
|
52
65
|
],
|
|
@@ -57,7 +70,7 @@ def get_header(title: str = "App", config: dict | None = None) -> html.Div:
|
|
|
57
70
|
dbc.Col(
|
|
58
71
|
dbc.Button(
|
|
59
72
|
"Close",
|
|
60
|
-
id="close-login-modal",
|
|
73
|
+
id=f"{store_id}=close-login-modal",
|
|
61
74
|
className="me-1",
|
|
62
75
|
color="light",
|
|
63
76
|
)
|
|
@@ -65,7 +78,7 @@ def get_header(title: str = "App", config: dict | None = None) -> html.Div:
|
|
|
65
78
|
dbc.Col(
|
|
66
79
|
dbc.Button(
|
|
67
80
|
"Login",
|
|
68
|
-
id="log-in-btn",
|
|
81
|
+
id=f"{store_id}=log-in-btn",
|
|
69
82
|
className="me-1",
|
|
70
83
|
color="primary",
|
|
71
84
|
)
|
|
@@ -75,7 +88,7 @@ def get_header(title: str = "App", config: dict | None = None) -> html.Div:
|
|
|
75
88
|
),
|
|
76
89
|
],
|
|
77
90
|
is_open=False,
|
|
78
|
-
id="login-modal",
|
|
91
|
+
id=f"{store_id}=login-modal",
|
|
79
92
|
)
|
|
80
93
|
|
|
81
94
|
logout_modal = dbc.Modal(
|
|
@@ -84,7 +97,7 @@ def get_header(title: str = "App", config: dict | None = None) -> html.Div:
|
|
|
84
97
|
[
|
|
85
98
|
dbc.Button(
|
|
86
99
|
"Log out",
|
|
87
|
-
id="logout-btn",
|
|
100
|
+
id=f"{store_id}=logout-btn",
|
|
88
101
|
color="danger",
|
|
89
102
|
className="me-1",
|
|
90
103
|
),
|
|
@@ -92,12 +105,9 @@ def get_header(title: str = "App", config: dict | None = None) -> html.Div:
|
|
|
92
105
|
)
|
|
93
106
|
],
|
|
94
107
|
is_open=False,
|
|
95
|
-
id="logout-modal",
|
|
108
|
+
id=f"{store_id}=logout-modal",
|
|
96
109
|
)
|
|
97
110
|
|
|
98
|
-
if config is None:
|
|
99
|
-
config = {}
|
|
100
|
-
|
|
101
111
|
return html.Div(
|
|
102
112
|
[
|
|
103
113
|
dbc.Row(
|
|
@@ -116,7 +126,7 @@ def get_header(title: str = "App", config: dict | None = None) -> html.Div:
|
|
|
116
126
|
dbc.Col(
|
|
117
127
|
dbc.Button(
|
|
118
128
|
"Log in",
|
|
119
|
-
id="login-btn",
|
|
129
|
+
id=f"{store_id}=login-btn",
|
|
120
130
|
color=config.get("backgroundColor", "#012169"),
|
|
121
131
|
style={
|
|
122
132
|
"color": config.get("fontColor", "#f2a900"),
|
|
@@ -132,7 +142,7 @@ def get_header(title: str = "App", config: dict | None = None) -> html.Div:
|
|
|
132
142
|
),
|
|
133
143
|
login_modal,
|
|
134
144
|
logout_modal,
|
|
135
|
-
dcc.Store(id=
|
|
145
|
+
dcc.Store(id=store_id, storage_type="local", data={}),
|
|
136
146
|
],
|
|
137
147
|
style={
|
|
138
148
|
"backgroundColor": config.get("backgroundColor", "#012169"),
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# Callbacks for the header component.
|
|
2
|
+
from dash import callback, Output, Input, State, no_update
|
|
3
|
+
from girder_client import GirderClient
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def get_callbacks(dsa_api_url: str, store_id: str):
|
|
7
|
+
"""Setup the callbacks to the DSA API url of interest and the proper store id."""
|
|
8
|
+
|
|
9
|
+
@callback(Output(f"{store_id}=login-btn", "children"), Input(store_id, "data"))
|
|
10
|
+
def check_user_store(data):
|
|
11
|
+
# Check if the user store has user info or if no one is logged in.
|
|
12
|
+
return data["user"] if len(data) else "Log in"
|
|
13
|
+
|
|
14
|
+
@callback(
|
|
15
|
+
[
|
|
16
|
+
Output(f"{store_id}=login-modal", "is_open", allow_duplicate=True),
|
|
17
|
+
Output(f"{store_id}=logout-modal", "is_open", allow_duplicate=True),
|
|
18
|
+
],
|
|
19
|
+
[
|
|
20
|
+
Input(f"{store_id}=login-btn", "n_clicks"),
|
|
21
|
+
State(f"{store_id}=login-btn", "children"),
|
|
22
|
+
],
|
|
23
|
+
prevent_initial_call=True,
|
|
24
|
+
)
|
|
25
|
+
def open_login_modal(n_clicks, children):
|
|
26
|
+
# Open login / logout modal.
|
|
27
|
+
if n_clicks:
|
|
28
|
+
if children == "Log in":
|
|
29
|
+
return True, False
|
|
30
|
+
else:
|
|
31
|
+
return False, True
|
|
32
|
+
|
|
33
|
+
return False, False
|
|
34
|
+
|
|
35
|
+
@callback(
|
|
36
|
+
[
|
|
37
|
+
Output(store_id, "data"),
|
|
38
|
+
Output(f"{store_id}=login-failed", "hidden", allow_duplicate=True),
|
|
39
|
+
Output(f"{store_id}=login-modal", "is_open", allow_duplicate=True),
|
|
40
|
+
Output(f"{store_id}=login", "value", allow_duplicate=True),
|
|
41
|
+
Output(f"{store_id}=password", "value", allow_duplicate=True),
|
|
42
|
+
],
|
|
43
|
+
[
|
|
44
|
+
Input(f"{store_id}=log-in-btn", "n_clicks"),
|
|
45
|
+
State(f"{store_id}=login", "value"),
|
|
46
|
+
State(f"{store_id}=password", "value"),
|
|
47
|
+
],
|
|
48
|
+
prevent_initial_call=True,
|
|
49
|
+
)
|
|
50
|
+
def login(n_clicks, login, password):
|
|
51
|
+
# Try to login.
|
|
52
|
+
gc = GirderClient(apiUrl=dsa_api_url)
|
|
53
|
+
|
|
54
|
+
try:
|
|
55
|
+
_ = gc.authenticate(username=login, password=password)
|
|
56
|
+
|
|
57
|
+
response = gc.get("token/session")
|
|
58
|
+
|
|
59
|
+
user = gc.get("user/me")["login"]
|
|
60
|
+
|
|
61
|
+
return {"user": user, "token": response["token"]}, True, False, "", ""
|
|
62
|
+
except:
|
|
63
|
+
return (
|
|
64
|
+
{},
|
|
65
|
+
False,
|
|
66
|
+
True,
|
|
67
|
+
no_update,
|
|
68
|
+
no_update,
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
@callback(
|
|
72
|
+
[
|
|
73
|
+
Output(f"{store_id}=login-modal", "is_open", allow_duplicate=True),
|
|
74
|
+
Output(f"{store_id}=login", "value", allow_duplicate=True),
|
|
75
|
+
Output(f"{store_id}=password", "value", allow_duplicate=True),
|
|
76
|
+
Output(f"{store_id}=login-failed", "hidden", allow_duplicate=True),
|
|
77
|
+
],
|
|
78
|
+
Input(f"{store_id}=close-login-modal", "n_clicks"),
|
|
79
|
+
prevent_initial_call=True,
|
|
80
|
+
)
|
|
81
|
+
def close_login_modal(n_clicks):
|
|
82
|
+
if n_clicks:
|
|
83
|
+
return False, "", "", True
|
|
84
|
+
|
|
85
|
+
return False, "", "", True
|
|
86
|
+
|
|
87
|
+
@callback(
|
|
88
|
+
[
|
|
89
|
+
Output(store_id, "data", allow_duplicate=True),
|
|
90
|
+
Output(f"{store_id}=logout-modal", "is_open", allow_duplicate=True),
|
|
91
|
+
],
|
|
92
|
+
Input(f"{store_id}=logout-btn", "n_clicks"),
|
|
93
|
+
prevent_initial_call=True,
|
|
94
|
+
)
|
|
95
|
+
def logout(n_clicks):
|
|
96
|
+
if n_clicks:
|
|
97
|
+
return {}, False
|
|
98
|
+
|
|
99
|
+
return no_update, False
|
|
@@ -13,7 +13,7 @@ def get_mongo_client(
|
|
|
13
13
|
username: str | None = None,
|
|
14
14
|
password: str | None = None,
|
|
15
15
|
port: int | None = None,
|
|
16
|
-
)
|
|
16
|
+
):
|
|
17
17
|
"""Get a mongo client by providing the key parts of the URL. By default
|
|
18
18
|
when the parameters are not passed, it sets them to default values first
|
|
19
19
|
by looking at key environment variables. If the environment variables are
|
|
@@ -36,7 +36,7 @@ def get_mongo_client(
|
|
|
36
36
|
missing it will default to 27017.
|
|
37
37
|
|
|
38
38
|
Returns:
|
|
39
|
-
|
|
39
|
+
The mongo client.
|
|
40
40
|
|
|
41
41
|
"""
|
|
42
42
|
if username is None:
|
|
@@ -67,7 +67,7 @@ def chunks(lst: list, n=500):
|
|
|
67
67
|
|
|
68
68
|
|
|
69
69
|
def add_many_to_collection(
|
|
70
|
-
mongo_collection
|
|
70
|
+
mongo_collection,
|
|
71
71
|
items: dict | list,
|
|
72
72
|
key: str = "_id",
|
|
73
73
|
) -> dict[str | dict]:
|
|
@@ -75,7 +75,7 @@ def add_many_to_collection(
|
|
|
75
75
|
user key.
|
|
76
76
|
|
|
77
77
|
Args:
|
|
78
|
-
mongo_collection
|
|
78
|
+
mongo_collection: The mongo collection to add to.
|
|
79
79
|
items (dict | list): The items to add to the collection.
|
|
80
80
|
key (str): The key to use to identify the items.
|
|
81
81
|
|
|
@@ -100,13 +100,11 @@ def add_many_to_collection(
|
|
|
100
100
|
return items
|
|
101
101
|
|
|
102
102
|
|
|
103
|
-
def get_img_from_db(
|
|
104
|
-
mongo_db: pymongo.database.Database, img_id: str
|
|
105
|
-
) -> Union[np.ndarray, None]:
|
|
103
|
+
def get_img_from_db(mongo_db, img_id: str) -> Union[np.ndarray, None]:
|
|
106
104
|
"""Get an image from the database by its location id.
|
|
107
105
|
|
|
108
106
|
Args:
|
|
109
|
-
mongo_db
|
|
107
|
+
mongo_db: The mongo database.
|
|
110
108
|
img_loc (str): The image id in mongo.
|
|
111
109
|
|
|
112
110
|
Returns:
|
|
@@ -131,13 +129,13 @@ def get_img_from_db(
|
|
|
131
129
|
|
|
132
130
|
|
|
133
131
|
def add_img_to_db(
|
|
134
|
-
mongo_db
|
|
132
|
+
mongo_db,
|
|
135
133
|
img: Image.Image | np.ndarray,
|
|
136
134
|
) -> str:
|
|
137
135
|
"""Add an image to the database.
|
|
138
136
|
|
|
139
137
|
Args:
|
|
140
|
-
mongo_db
|
|
138
|
+
mongo_db: The mongo database.
|
|
141
139
|
img (np.ndarray or PIL.Image.Image): The image.
|
|
142
140
|
|
|
143
141
|
Returns:
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
{
|
|
2
|
+
"cells": [
|
|
3
|
+
{
|
|
4
|
+
"cell_type": "markdown",
|
|
5
|
+
"metadata": {},
|
|
6
|
+
"source": [
|
|
7
|
+
"# Test Python Package Build"
|
|
8
|
+
]
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"cell_type": "code",
|
|
12
|
+
"execution_count": 1,
|
|
13
|
+
"metadata": {},
|
|
14
|
+
"outputs": [],
|
|
15
|
+
"source": [
|
|
16
|
+
"# Import all modules.\n",
|
|
17
|
+
"from dsa_helpers import *"
|
|
18
|
+
]
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"cell_type": "markdown",
|
|
22
|
+
"metadata": {},
|
|
23
|
+
"source": [
|
|
24
|
+
"#### Authenticate girder client."
|
|
25
|
+
]
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"cell_type": "code",
|
|
29
|
+
"execution_count": 3,
|
|
30
|
+
"metadata": {},
|
|
31
|
+
"outputs": [],
|
|
32
|
+
"source": [
|
|
33
|
+
"gc = girder_utils.login(\"\")"
|
|
34
|
+
]
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"cell_type": "markdown",
|
|
38
|
+
"metadata": {},
|
|
39
|
+
"source": [
|
|
40
|
+
"#### Get DSA items recursively"
|
|
41
|
+
]
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"cell_type": "code",
|
|
45
|
+
"execution_count": null,
|
|
46
|
+
"metadata": {},
|
|
47
|
+
"outputs": [],
|
|
48
|
+
"source": [
|
|
49
|
+
"# Get items from a folder.\n",
|
|
50
|
+
"items = girder_utils.get_items(gc, \"\")\n",
|
|
51
|
+
"print(f\"Got {len(items)} items from folder.\")\n",
|
|
52
|
+
"\n",
|
|
53
|
+
"items = girder_utils.get_items(gc, \"\")\n",
|
|
54
|
+
"print(f\"Got {len(items)} items from collection.\")"
|
|
55
|
+
]
|
|
56
|
+
}
|
|
57
|
+
],
|
|
58
|
+
"metadata": {
|
|
59
|
+
"kernelspec": {
|
|
60
|
+
"display_name": "env",
|
|
61
|
+
"language": "python",
|
|
62
|
+
"name": "python3"
|
|
63
|
+
},
|
|
64
|
+
"language_info": {
|
|
65
|
+
"codemirror_mode": {
|
|
66
|
+
"name": "ipython",
|
|
67
|
+
"version": 3
|
|
68
|
+
},
|
|
69
|
+
"file_extension": ".py",
|
|
70
|
+
"mimetype": "text/x-python",
|
|
71
|
+
"name": "python",
|
|
72
|
+
"nbconvert_exporter": "python",
|
|
73
|
+
"pygments_lexer": "ipython3",
|
|
74
|
+
"version": "3.12.3"
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
"nbformat": 4,
|
|
78
|
+
"nbformat_minor": 2
|
|
79
|
+
}
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
# Callbacks for the header component.
|
|
2
|
-
from dash import callback, Output, Input, State, no_update
|
|
3
|
-
from girder_client import GirderClient
|
|
4
|
-
from os import getenv
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
@callback(Output("login-btn", "children"), Input("user-store", "data"))
|
|
8
|
-
def check_user_store(data):
|
|
9
|
-
# Check if the user store has user info or if no one is logged in.
|
|
10
|
-
return data["user"] if len(data) else "Log in"
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
@callback(
|
|
14
|
-
[
|
|
15
|
-
Output("login-modal", "is_open", allow_duplicate=True),
|
|
16
|
-
Output("logout-modal", "is_open", allow_duplicate=True),
|
|
17
|
-
],
|
|
18
|
-
[Input("login-btn", "n_clicks"), State("login-btn", "children")],
|
|
19
|
-
prevent_initial_call=True,
|
|
20
|
-
)
|
|
21
|
-
def open_login_modal(n_clicks, children):
|
|
22
|
-
# Open login / logout modal.
|
|
23
|
-
if n_clicks:
|
|
24
|
-
if children == "Log in":
|
|
25
|
-
return True, False
|
|
26
|
-
else:
|
|
27
|
-
return False, True
|
|
28
|
-
|
|
29
|
-
return False, False
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
@callback(
|
|
33
|
-
[
|
|
34
|
-
Output("user-store", "data"),
|
|
35
|
-
Output("login-failed", "hidden", allow_duplicate=True),
|
|
36
|
-
Output("login-modal", "is_open", allow_duplicate=True),
|
|
37
|
-
Output("login", "value", allow_duplicate=True),
|
|
38
|
-
Output("password", "value", allow_duplicate=True),
|
|
39
|
-
],
|
|
40
|
-
[
|
|
41
|
-
Input("log-in-btn", "n_clicks"),
|
|
42
|
-
State("login", "value"),
|
|
43
|
-
State("password", "value"),
|
|
44
|
-
],
|
|
45
|
-
prevent_initial_call=True,
|
|
46
|
-
)
|
|
47
|
-
def login(n_clicks, login, password):
|
|
48
|
-
# Try to login.
|
|
49
|
-
gc = GirderClient(apiUrl=getenv("DSA_API_URL"))
|
|
50
|
-
|
|
51
|
-
try:
|
|
52
|
-
_ = gc.authenticate(username=login, password=password)
|
|
53
|
-
|
|
54
|
-
response = gc.get("token/session")
|
|
55
|
-
|
|
56
|
-
user = gc.get("user/me")["login"]
|
|
57
|
-
|
|
58
|
-
return {"user": user, "token": response["token"]}, True, False, "", ""
|
|
59
|
-
except:
|
|
60
|
-
return (
|
|
61
|
-
{},
|
|
62
|
-
False,
|
|
63
|
-
True,
|
|
64
|
-
no_update,
|
|
65
|
-
no_update,
|
|
66
|
-
)
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
@callback(
|
|
70
|
-
[
|
|
71
|
-
Output("login-modal", "is_open", allow_duplicate=True),
|
|
72
|
-
Output("login", "value", allow_duplicate=True),
|
|
73
|
-
Output("password", "value", allow_duplicate=True),
|
|
74
|
-
Output("login-failed", "hidden", allow_duplicate=True),
|
|
75
|
-
],
|
|
76
|
-
Input("close-login-modal", "n_clicks"),
|
|
77
|
-
prevent_initial_call=True,
|
|
78
|
-
)
|
|
79
|
-
def close_login_modal(n_clicks):
|
|
80
|
-
if n_clicks:
|
|
81
|
-
return False, "", "", True
|
|
82
|
-
|
|
83
|
-
return False, "", "", True
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
@callback(
|
|
87
|
-
[
|
|
88
|
-
Output("user-store", "data", allow_duplicate=True),
|
|
89
|
-
Output("logout-modal", "is_open", allow_duplicate=True),
|
|
90
|
-
],
|
|
91
|
-
Input("logout-btn", "n_clicks"),
|
|
92
|
-
prevent_initial_call=True,
|
|
93
|
-
)
|
|
94
|
-
def logout(n_clicks):
|
|
95
|
-
if n_clicks:
|
|
96
|
-
return {}, False
|
|
97
|
-
|
|
98
|
-
return no_update, False
|