dsa-helpers 0.3.dev0__tar.gz → 0.4__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 (47) hide show
  1. {dsa_helpers-0.3.dev0 → dsa_helpers-0.4}/.gitignore +4 -1
  2. dsa_helpers-0.4/PKG-INFO +50 -0
  3. dsa_helpers-0.4/README.md +21 -0
  4. dsa_helpers-0.4/app.py +14 -0
  5. {dsa_helpers-0.3.dev0 → dsa_helpers-0.4}/dsa_helpers/__init__.py +3 -2
  6. dsa_helpers-0.4/dsa_helpers/dash/__init__.py +1 -0
  7. dsa_helpers-0.4/dsa_helpers/dash/header.py +151 -0
  8. dsa_helpers-0.4/dsa_helpers/dash/header_callbacks.py +99 -0
  9. dsa_helpers-0.4/dsa_helpers/girder_utils.py +346 -0
  10. {dsa_helpers-0.3.dev0 → dsa_helpers-0.4}/dsa_helpers/login.py +3 -1
  11. dsa_helpers-0.4/dsa_helpers/ml/__init__.py +2 -0
  12. dsa_helpers-0.4/dsa_helpers/ml/datasets/SegFormerSegmentationDataset.py +33 -0
  13. dsa_helpers-0.4/dsa_helpers/ml/datasets/__init__.py +3 -0
  14. dsa_helpers-0.4/dsa_helpers/ml/datasets/utils.py +42 -0
  15. dsa_helpers-0.4/dsa_helpers/ml/metrics/__init__.py +3 -0
  16. dsa_helpers-0.4/dsa_helpers/ml/metrics/binary_dice_coefficient_metric.py +24 -0
  17. dsa_helpers-0.4/dsa_helpers/ml/object_detection/__init__.py +5 -0
  18. dsa_helpers-0.4/dsa_helpers/ml/object_detection/get_pearce_roi_images.py +136 -0
  19. dsa_helpers-0.4/dsa_helpers/ml/object_detection/tile_image.py +137 -0
  20. dsa_helpers-0.4/dsa_helpers/ml/object_detection/utils.py +104 -0
  21. dsa_helpers-0.4/dsa_helpers/ml/transforms/__init__.py +1 -0
  22. dsa_helpers-0.4/dsa_helpers/ml/transforms/segformer_transforms.py +23 -0
  23. dsa_helpers-0.4/dsa_helpers/mongo_utils.py +160 -0
  24. dsa_helpers-0.4/dsa_helpers/utils.py +28 -0
  25. dsa_helpers-0.4/dsa_helpers.egg-info/PKG-INFO +50 -0
  26. dsa_helpers-0.4/dsa_helpers.egg-info/SOURCES.txt +38 -0
  27. dsa_helpers-0.4/dsa_helpers.egg-info/requires.txt +15 -0
  28. {dsa_helpers-0.3.dev0 → dsa_helpers-0.4}/pyproject.toml +16 -6
  29. dsa_helpers-0.4/requirements.txt +15 -0
  30. dsa_helpers-0.4/tests/app/Dockerfile +18 -0
  31. dsa_helpers-0.4/tests/app/app.py +55 -0
  32. dsa_helpers-0.4/tests/docker-compose.yaml +31 -0
  33. dsa_helpers-0.4/tests/test.ipynb +268 -0
  34. dsa_helpers-0.3.dev0/PKG-INFO +0 -25
  35. dsa_helpers-0.3.dev0/README.md +0 -6
  36. dsa_helpers-0.3.dev0/dsa_helpers/girder_utils.py +0 -116
  37. dsa_helpers-0.3.dev0/dsa_helpers.egg-info/PKG-INFO +0 -25
  38. dsa_helpers-0.3.dev0/dsa_helpers.egg-info/SOURCES.txt +0 -16
  39. dsa_helpers-0.3.dev0/dsa_helpers.egg-info/requires.txt +0 -5
  40. dsa_helpers-0.3.dev0/requirements.txt +0 -5
  41. {dsa_helpers-0.3.dev0 → dsa_helpers-0.4}/LICENSE +0 -0
  42. {dsa_helpers-0.3.dev0 → dsa_helpers-0.4}/dsa_helpers/image_utils.py +0 -0
  43. {dsa_helpers-0.3.dev0 → dsa_helpers-0.4}/dsa_helpers/imread.py +0 -0
  44. {dsa_helpers-0.3.dev0 → dsa_helpers-0.4}/dsa_helpers/imwrite.py +0 -0
  45. {dsa_helpers-0.3.dev0 → dsa_helpers-0.4}/dsa_helpers.egg-info/dependency_links.txt +0 -0
  46. {dsa_helpers-0.3.dev0 → dsa_helpers-0.4}/dsa_helpers.egg-info/top_level.txt +0 -0
  47. {dsa_helpers-0.3.dev0 → dsa_helpers-0.4}/setup.cfg +0 -0
@@ -5,4 +5,7 @@ pyenv/
5
5
  # Do not push the version file.
6
6
  dsa_utils/_version.py
7
7
 
8
- *.pyc
8
+ *.pyc
9
+ *.egg-info
10
+ dist/
11
+ .env
@@ -0,0 +1,50 @@
1
+ Metadata-Version: 2.1
2
+ Name: dsa_helpers
3
+ Version: 0.4
4
+ Summary: Utility functions for working with the DSA girder client.
5
+ Author-email: "Juan C. Vizcarra" <jvizcar@emory.edu>
6
+ Maintainer-email: "Juan C. Vizcarra" <jvizcar@emory.edu>
7
+ Project-URL: Repository, https://github.com/Gutman-Lab/dsa-python-utils
8
+ Keywords: dsa,girder,girder_client
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Requires-Python: >=3.9
12
+ Description-Content-Type: text/markdown
13
+ License-File: LICENSE
14
+ Requires-Dist: girder-client
15
+ Requires-Dist: numpy
16
+ Requires-Dist: setuptools
17
+ Requires-Dist: opencv-python
18
+ Requires-Dist: pandas
19
+ Requires-Dist: pymongo
20
+ Requires-Dist: pillow
21
+ Requires-Dist: dash
22
+ Requires-Dist: dash_bootstrap_components
23
+ Requires-Dist: shapely
24
+ Requires-Dist: geopandas
25
+ Requires-Dist: torch
26
+ Requires-Dist: datasets
27
+ Requires-Dist: transformers
28
+ Requires-Dist: torchvision
29
+
30
+ # Digital Slide Archive (DSA) Helpers
31
+ Digital Slide Archive Python utility library.
32
+
33
+ This library is available for installation through [Python Package Index (PyPI)](https://pypi.org/).
34
+
35
+ This library was tested using Python version 3.11.8 and uses the dependencies described in requirements.txt.
36
+
37
+ This Python PyPI package is found [here](https://pypi.org/project/dsa-helpers/).
38
+
39
+ ## Instructions for Development
40
+ 1. Install requirements for building and distributing package:
41
+ ```
42
+ $ python3 -m pip install --upgrade build # for building package
43
+ $ python3 -m pip install --upgrade twine # for uploading to PyPI
44
+ ```
45
+ 2. When ready to build:
46
+ - Modify "pyproject.toml" file, change the "version" key to a different value than a version already pushed.
47
+ - Run ```$ python3 -m build```. This will create a dist directory and put your new wheel and tar distribution files there.
48
+ 3. To install locally for development: ```$ pip3 install dist/dsa_helpers-*.whl```, choosing the wheel version you want to test.
49
+ 4. Upload to PyPI using twine: ```python3 -m twine upload --repository pypi dist/*```
50
+ * You can specify specific files to upload, the line above pushes everything in dist directory.
@@ -0,0 +1,21 @@
1
+ # Digital Slide Archive (DSA) Helpers
2
+ Digital Slide Archive Python utility library.
3
+
4
+ This library is available for installation through [Python Package Index (PyPI)](https://pypi.org/).
5
+
6
+ This library was tested using Python version 3.11.8 and uses the dependencies described in requirements.txt.
7
+
8
+ This Python PyPI package is found [here](https://pypi.org/project/dsa-helpers/).
9
+
10
+ ## Instructions for Development
11
+ 1. Install requirements for building and distributing package:
12
+ ```
13
+ $ python3 -m pip install --upgrade build # for building package
14
+ $ python3 -m pip install --upgrade twine # for uploading to PyPI
15
+ ```
16
+ 2. When ready to build:
17
+ - Modify "pyproject.toml" file, change the "version" key to a different value than a version already pushed.
18
+ - Run ```$ python3 -m build```. This will create a dist directory and put your new wheel and tar distribution files there.
19
+ 3. To install locally for development: ```$ pip3 install dist/dsa_helpers-*.whl```, choosing the wheel version you want to test.
20
+ 4. Upload to PyPI using twine: ```python3 -m twine upload --repository pypi dist/*```
21
+ * You can specify specific files to upload, the line above pushes everything in dist directory.
dsa_helpers-0.4/app.py ADDED
@@ -0,0 +1,14 @@
1
+ # A test application.
2
+ from dash import Dash, html
3
+ import dash_bootstrap_components as dbc
4
+ from dsa_helpers.dash.header import get_header
5
+ import os
6
+
7
+ os.environ["DSA_API_URL"] = "https://megabrain.neurology.emory.edu/api/v1"
8
+
9
+ app = Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])
10
+
11
+ app.layout = html.Div([get_header("Test")])
12
+
13
+ if __name__ == "__main__":
14
+ app.run_server(debug=True)
@@ -1,7 +1,8 @@
1
1
  # Shadow imports.
2
- from .login import login
3
2
  from .imread import imread
4
3
  from .imwrite import imwrite
5
4
 
6
5
  # Modules that should be available.
7
- from . import girder_utils, image_utils
6
+ # from . import girder_utils, image_utils, dash
7
+
8
+ __all__ = ["girder_utils", "image_utils", "dash", "ml"]
@@ -0,0 +1 @@
1
+ from . import header
@@ -0,0 +1,151 @@
1
+ from dash import html, dcc
2
+ import dash_bootstrap_components as dbc
3
+ from .header_callbacks import get_callbacks
4
+
5
+
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:
12
+ """Get the Dash html component that contains the header of the application
13
+ with login capabilities.
14
+
15
+ Args:
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
+ }
25
+
26
+ Returns:
27
+ html.Div: The header component.
28
+
29
+ """
30
+ if config is None:
31
+ config = {}
32
+
33
+ get_callbacks(dsa_api_url, store_id)
34
+
35
+ login_modal = dbc.Modal(
36
+ [
37
+ dbc.ModalHeader("Log in"),
38
+ dbc.ModalBody(
39
+ [
40
+ html.Div(
41
+ "Login or email", style={"margin": 5, "fontWeight": "bold"}
42
+ ),
43
+ dbc.Input(
44
+ id=f"{store_id}=login",
45
+ type="text",
46
+ placeholder="Enter login",
47
+ style={"margin": 5},
48
+ ),
49
+ html.Div(
50
+ "Password",
51
+ style={"margin": 5, "marginTop": 15, "fontWeight": "bold"},
52
+ ),
53
+ dbc.Input(
54
+ id=f"{store_id}=password",
55
+ type="password",
56
+ placeholder="Enter password",
57
+ style={"margin": 5},
58
+ ),
59
+ html.Div(
60
+ "Login failed.",
61
+ hidden=True,
62
+ id=f"{store_id}=login-failed",
63
+ style={"color": "red", "fontWeight": "bold", "margin": 10},
64
+ ),
65
+ ],
66
+ ),
67
+ dbc.ModalFooter(
68
+ dbc.Row(
69
+ [
70
+ dbc.Col(
71
+ dbc.Button(
72
+ "Close",
73
+ id=f"{store_id}=close-login-modal",
74
+ className="me-1",
75
+ color="light",
76
+ )
77
+ ),
78
+ dbc.Col(
79
+ dbc.Button(
80
+ "Login",
81
+ id=f"{store_id}=log-in-btn",
82
+ className="me-1",
83
+ color="primary",
84
+ )
85
+ ),
86
+ ],
87
+ )
88
+ ),
89
+ ],
90
+ is_open=False,
91
+ id=f"{store_id}=login-modal",
92
+ )
93
+
94
+ logout_modal = dbc.Modal(
95
+ [
96
+ dbc.ModalFooter(
97
+ [
98
+ dbc.Button(
99
+ "Log out",
100
+ id=f"{store_id}=logout-btn",
101
+ color="danger",
102
+ className="me-1",
103
+ ),
104
+ ]
105
+ )
106
+ ],
107
+ is_open=False,
108
+ id=f"{store_id}=logout-modal",
109
+ )
110
+
111
+ return html.Div(
112
+ [
113
+ dbc.Row(
114
+ [
115
+ dbc.Col(
116
+ html.H1(
117
+ title,
118
+ style={
119
+ "fontWeight": "bold",
120
+ "color": config.get("titleColor", "#d9d9d6"),
121
+ "marginLeft": 5,
122
+ },
123
+ ),
124
+ width="auto",
125
+ ),
126
+ dbc.Col(
127
+ dbc.Button(
128
+ "Log in",
129
+ id=f"{store_id}=login-btn",
130
+ color=config.get("backgroundColor", "#012169"),
131
+ style={
132
+ "color": config.get("fontColor", "#f2a900"),
133
+ "fontSize": "1.2rem",
134
+ },
135
+ className="me-1",
136
+ ),
137
+ width="auto",
138
+ ),
139
+ ],
140
+ justify="between",
141
+ align="center",
142
+ ),
143
+ login_modal,
144
+ logout_modal,
145
+ dcc.Store(id=store_id, storage_type="local", data={}),
146
+ ],
147
+ style={
148
+ "backgroundColor": config.get("backgroundColor", "#012169"),
149
+ "padding": 5,
150
+ },
151
+ )
@@ -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