dsa-helpers 0.4.dev0__tar.gz → 0.4.dev1__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.
Files changed (32) hide show
  1. {dsa_helpers-0.4.dev0/dsa_helpers.egg-info → dsa_helpers-0.4.dev1}/PKG-INFO +1 -1
  2. {dsa_helpers-0.4.dev0 → dsa_helpers-0.4.dev1}/dsa_helpers/dash/header.py +31 -21
  3. dsa_helpers-0.4.dev1/dsa_helpers/dash/header_callbacks.py +99 -0
  4. {dsa_helpers-0.4.dev0 → dsa_helpers-0.4.dev1/dsa_helpers.egg-info}/PKG-INFO +1 -1
  5. {dsa_helpers-0.4.dev0 → dsa_helpers-0.4.dev1}/pyproject.toml +1 -1
  6. dsa_helpers-0.4.dev1/tests/test.ipynb +79 -0
  7. dsa_helpers-0.4.dev0/dsa_helpers/dash/header_callbacks.py +0 -98
  8. dsa_helpers-0.4.dev0/tests/test.ipynb +0 -268
  9. {dsa_helpers-0.4.dev0 → dsa_helpers-0.4.dev1}/.gitignore +0 -0
  10. {dsa_helpers-0.4.dev0 → dsa_helpers-0.4.dev1}/LICENSE +0 -0
  11. {dsa_helpers-0.4.dev0 → dsa_helpers-0.4.dev1}/README.md +0 -0
  12. {dsa_helpers-0.4.dev0 → dsa_helpers-0.4.dev1}/app.py +0 -0
  13. {dsa_helpers-0.4.dev0 → dsa_helpers-0.4.dev1}/dsa_helpers/__init__.py +0 -0
  14. {dsa_helpers-0.4.dev0 → dsa_helpers-0.4.dev1}/dsa_helpers/dash/__init__.py +0 -0
  15. {dsa_helpers-0.4.dev0 → dsa_helpers-0.4.dev1}/dsa_helpers/girder_utils.py +0 -0
  16. {dsa_helpers-0.4.dev0 → dsa_helpers-0.4.dev1}/dsa_helpers/image_utils.py +0 -0
  17. {dsa_helpers-0.4.dev0 → dsa_helpers-0.4.dev1}/dsa_helpers/imread.py +0 -0
  18. {dsa_helpers-0.4.dev0 → dsa_helpers-0.4.dev1}/dsa_helpers/imwrite.py +0 -0
  19. {dsa_helpers-0.4.dev0 → dsa_helpers-0.4.dev1}/dsa_helpers/login.py +0 -0
  20. {dsa_helpers-0.4.dev0 → dsa_helpers-0.4.dev1}/dsa_helpers/ml/__init__.py +0 -0
  21. {dsa_helpers-0.4.dev0 → dsa_helpers-0.4.dev1}/dsa_helpers/ml/object_detection/__init__.py +0 -0
  22. {dsa_helpers-0.4.dev0 → dsa_helpers-0.4.dev1}/dsa_helpers/ml/object_detection/get_pearce_roi_images.py +0 -0
  23. {dsa_helpers-0.4.dev0 → dsa_helpers-0.4.dev1}/dsa_helpers/ml/object_detection/tile_image.py +0 -0
  24. {dsa_helpers-0.4.dev0 → dsa_helpers-0.4.dev1}/dsa_helpers/ml/object_detection/utils.py +0 -0
  25. {dsa_helpers-0.4.dev0 → dsa_helpers-0.4.dev1}/dsa_helpers/mongo_utils.py +0 -0
  26. {dsa_helpers-0.4.dev0 → dsa_helpers-0.4.dev1}/dsa_helpers.egg-info/SOURCES.txt +0 -0
  27. {dsa_helpers-0.4.dev0 → dsa_helpers-0.4.dev1}/dsa_helpers.egg-info/dependency_links.txt +0 -0
  28. {dsa_helpers-0.4.dev0 → dsa_helpers-0.4.dev1}/dsa_helpers.egg-info/requires.txt +0 -0
  29. {dsa_helpers-0.4.dev0 → dsa_helpers-0.4.dev1}/dsa_helpers.egg-info/top_level.txt +0 -0
  30. {dsa_helpers-0.4.dev0 → dsa_helpers-0.4.dev1}/readthedocs.yaml +0 -0
  31. {dsa_helpers-0.4.dev0 → dsa_helpers-0.4.dev1}/requirements.txt +0 -0
  32. {dsa_helpers-0.4.dev0 → dsa_helpers-0.4.dev1}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dsa_helpers
3
- Version: 0.4.dev0
3
+ Version: 0.4.dev1
4
4
  Summary: Utility functions for working with the DSA girder client.
5
5
  Author-email: "Juan C. Vizcarra" <jvizcar@emory.edu>
6
6
  Maintainer-email: "Juan C. Vizcarra" <jvizcar@emory.edu>
@@ -1,24 +1,37 @@
1
1
  from dash import html, dcc
2
2
  import dash_bootstrap_components as dbc
3
- from . import header_callbacks
3
+ from .header_callbacks import get_callbacks
4
4
 
5
5
 
6
- def get_header(title: str = "App", config: dict | None = None) -> html.Div:
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
- title (str): The title of the application.
12
- config (dict): The configuration of the component.
13
-
14
- backgroundColor
15
- titleColor
16
- fontColor
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="user-store", storage_type="local", data={}),
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
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dsa_helpers
3
- Version: 0.4.dev0
3
+ Version: 0.4.dev1
4
4
  Summary: Utility functions for working with the DSA girder client.
5
5
  Author-email: "Juan C. Vizcarra" <jvizcar@emory.edu>
6
6
  Maintainer-email: "Juan C. Vizcarra" <jvizcar@emory.edu>
@@ -31,7 +31,7 @@ classifiers = [
31
31
  "License :: OSI Approved :: MIT License",
32
32
  ]
33
33
  keywords = ["dsa", "girder", "girder_client"]
34
- version = "v0.4dev0"
34
+ version = "v0.4dev1"
35
35
 
36
36
  [project.urls]
37
37
  Repository = "https://github.com/Gutman-Lab/dsa-python-utils"
@@ -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