terra_ui_components 0.0.129__py3-none-any.whl → 0.0.135__py3-none-any.whl

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.
@@ -13,4 +13,5 @@ from .plot_toolbar import TerraPlotToolbar
13
13
  from .data_access import TerraDataAccess
14
14
  from .slider import TerraSlider
15
15
  from .input import TerraInput
16
- __all__ = ["TerraBaseWidget", "TerraDateRangeSlider", "TerraTimeSeries", "TerraLogin", "TerraDialog", "TerraDatePicker", "TerraDataRods", "TerraAccordion", "TerraDataSubsetter", "TerraDataSubsetterHistory", "TerraTimeAverageMap", "TerraPlotToolbar", "TerraDataAccess", "TerraSlider", "TerraInput"]
16
+ from .earthdata_login import TerraEarthdataLogin
17
+ __all__ = ["TerraBaseWidget", "TerraDateRangeSlider", "TerraTimeSeries", "TerraLogin", "TerraDialog", "TerraDatePicker", "TerraDataRods", "TerraAccordion", "TerraDataSubsetter", "TerraDataSubsetterHistory", "TerraTimeAverageMap", "TerraPlotToolbar", "TerraDataAccess", "TerraSlider", "TerraInput", "TerraEarthdataLogin"]
@@ -16,12 +16,12 @@ class TerraBaseWidget(anywidget.AnyWidget):
16
16
  return f"""
17
17
  const terraStyles = document.createElement('link')
18
18
  terraStyles.rel = 'stylesheet'
19
- terraStyles.href = 'https://cdn.jsdelivr.net/npm/@nasa-terra/components@0.0.129/cdn/themes/horizon.css'
19
+ terraStyles.href = 'https://cdn.jsdelivr.net/npm/@nasa-terra/components@0.0.135/cdn/themes/horizon.css'
20
20
  //terraStyles.href = "http://localhost:4000/dist/themes/horizon.css"
21
21
  document.head.appendChild(terraStyles)
22
22
 
23
23
  const terraAutoloader = document.createElement('script')
24
- terraAutoloader.src = "https://cdn.jsdelivr.net/npm/@nasa-terra/components@0.0.129/cdn/terra-ui-components-autoloader.js"
24
+ terraAutoloader.src = "https://cdn.jsdelivr.net/npm/@nasa-terra/components@0.0.135/cdn/terra-ui-components-autoloader.js"
25
25
  //terraAutoloader.src = "http://localhost:4000/dist/terra-ui-components-autoloader.js"
26
26
  terraAutoloader.type = 'module'
27
27
  document.head.appendChild(terraAutoloader)
@@ -0,0 +1,3 @@
1
+ from .earthdata_login import TerraEarthdataLogin
2
+
3
+ __all__ = ["TerraEarthdataLogin"]
@@ -0,0 +1,177 @@
1
+ import importlib.metadata
2
+ import traitlets
3
+ from ..base import TerraBaseWidget
4
+ import earthaccess
5
+ from earthaccess.auth import netrc_path
6
+ from earthaccess.exceptions import LoginStrategyUnavailable
7
+ import os
8
+ from tinynetrc import Netrc
9
+
10
+ try:
11
+ __version__ = importlib.metadata.version("terra_earthdata_login")
12
+ except importlib.metadata.PackageNotFoundError:
13
+ __version__ = "unknown"
14
+
15
+
16
+ class TerraEarthdataLogin(TerraBaseWidget):
17
+ _esm = TerraBaseWidget.get_autoloader() + """
18
+ function render({ model, el }) {
19
+ const cell = el.closest('.lm-Widget');
20
+ if (cell && cell.classList.contains('jp-mod-outputsScrolled')) {
21
+ cell.classList.remove('jp-mod-outputsScrolled');
22
+ }
23
+
24
+ // create an instance of the component
25
+ let component = document.createElement('terra-earthdata-login')
26
+
27
+ /**
28
+ * Set initial property values
29
+ * NOTE: In reality, we won't need to have the ability to set EVERY property in a Jupyter Notebook, feel free to remove the ones that don't make sense
30
+ *
31
+ * model.get() pulls from the Jupyter notebooks state. We'll use the state to set the initial value for each property
32
+ */
33
+ component.loggedInMessage = model.get('loggedInMessage')
34
+ component.loggedOutMessage = model.get('loggedOutMessage')
35
+ component.loadingMessage = model.get('loadingMessage')
36
+ component.username = model.get('username')
37
+ component.password = model.get('password')
38
+ component.autoLogin = model.get('autoLogin')
39
+
40
+ /**
41
+ * add the component to the cell
42
+ * it should now be visible in the notebook!
43
+ */
44
+ el.appendChild(component)
45
+
46
+
47
+ /**
48
+ * Set up property change handlers
49
+ * This way if someone in the Jupyter Notebook changes the property externally, we reflect the change
50
+ * back to the component.
51
+ *
52
+ * If this isn't here, the component can't be changed after it's initial render
53
+ */
54
+ model.on('change:loggedInMessage', () => {
55
+ component.loggedInMessage = model.get('loggedInMessage')
56
+ })
57
+ model.on('change:loggedOutMessage', () => {
58
+ component.loggedOutMessage = model.get('loggedOutMessage')
59
+ })
60
+ model.on('change:loadingMessage', () => {
61
+ component.loadingMessage = model.get('loadingMessage')
62
+ })
63
+ model.on('change:username', () => {
64
+ component.username = model.get('username')
65
+ })
66
+ model.on('change:password', () => {
67
+ component.password = model.get('password')
68
+ })
69
+ model.on('change:autoLogin', () => {
70
+ component.autoLogin = model.get('autoLogin')
71
+ })
72
+ model.on('change:credentialsError', () => {
73
+ console.log('credentialsError: ', model.get('credentialsError'))
74
+ })
75
+
76
+ // listen for terra-login event and update the bearer token in the model
77
+ component.addEventListener('terra-login', (e) => {
78
+ model.set('bearerToken', e.detail.token)
79
+ model.save_changes()
80
+ })
81
+ }
82
+
83
+ export default { render };
84
+ """
85
+
86
+ # Component properties
87
+ # While we have properties in the component, we also need to tell Python about them as well.
88
+ # Again, you don't technically need all these. If Jupyter Notebooks don't need access to them, you can remove them from here
89
+ loggedInMessage = traitlets.Unicode('').tag(sync=True)
90
+ loggedOutMessage = traitlets.Unicode('').tag(sync=True)
91
+ loadingMessage = traitlets.Unicode('').tag(sync=True)
92
+ bearerToken = traitlets.Unicode('').tag(sync=True)
93
+ username = traitlets.Unicode().tag(sync=True)
94
+ password = traitlets.Unicode().tag(sync=True)
95
+ credentialsError = traitlets.Unicode('').tag(sync=True)
96
+ autoLogin = traitlets.Bool(True).tag(sync=True)
97
+
98
+ @traitlets.default('username')
99
+ def _default_username(self):
100
+ """
101
+ Get the default username from the .netrc file or environment variable
102
+ """
103
+ username, password = self._get_default_credentials()
104
+ if username is not None:
105
+ return username
106
+ return ''
107
+
108
+ @traitlets.default('password')
109
+ def _default_password(self):
110
+ """
111
+ Get the default password from the .netrc file or environment variable
112
+ """
113
+ username, password = self._get_default_credentials()
114
+ if password is not None:
115
+ return password
116
+ return ''
117
+
118
+ @traitlets.observe("bearerToken")
119
+ def _observe_bearer_token(self, change):
120
+ """
121
+ Whenever the bearer token changes, we want to login to earthaccess with the new token
122
+ """
123
+ if change["new"]:
124
+ os.environ["EARTHDATA_TOKEN"] = change["new"]
125
+ earthaccess.login(strategy='environment')
126
+
127
+ def _get_default_credentials(self):
128
+ """
129
+ Get the default credentials from the .netrc file
130
+ """
131
+ try:
132
+ return self._get_default_credentials_from_netrc()
133
+ except Exception as e:
134
+ self.credentialsError = str(e)
135
+ return self._get_default_credentials_from_environment()
136
+
137
+ def _get_default_credentials_from_netrc(self):
138
+ """
139
+ Get the default credentials from the .netrc file
140
+ """
141
+ netrc_loc = netrc_path()
142
+
143
+ try:
144
+ my_netrc = Netrc(str(netrc_loc))
145
+ except FileNotFoundError as err:
146
+ raise LoginStrategyUnavailable(
147
+ f"No .netrc found at {netrc_loc}") from err
148
+ except NetrcParseError as err:
149
+ raise LoginStrategyUnavailable(
150
+ f"Unable to parse .netrc file {netrc_loc}"
151
+ ) from err
152
+
153
+ creds = my_netrc['urs.earthdata.nasa.gov']
154
+ if creds is None:
155
+ raise LoginStrategyUnavailable(
156
+ f"Earthdata Login hostname urs.earthdata.nasa.gov not found in .netrc file {netrc_loc}"
157
+ )
158
+
159
+ username = creds["login"]
160
+ password = creds["password"]
161
+
162
+ if username is None:
163
+ raise LoginStrategyUnavailable(
164
+ f"Username not found in .netrc file {netrc_loc}"
165
+ )
166
+ if password is None:
167
+ raise LoginStrategyUnavailable(
168
+ f"Password not found in .netrc file {netrc_loc}"
169
+ )
170
+
171
+ return username, password
172
+
173
+ def _get_default_credentials_from_environment(self):
174
+ """
175
+ Get the default credentials from the environment variable
176
+ """
177
+ return os.environ.get('EARTHDATA_USERNAME', ''), os.environ.get('EARTHDATA_PASSWORD', '')
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: terra_ui_components
3
- Version: 0.0.129
3
+ Version: 0.0.135
4
4
  Summary: NASA Terra UI Components Library
5
5
  License-File: LICENSE.md
6
6
  Requires-Python: >=3.8
@@ -61,6 +61,7 @@ Then run the following:
61
61
  - `uv venv` - create a virtual environment (only have to do this the first time)
62
62
  - `source .venv/bin/activate` - activate it
63
63
  - `uv pip install -e ".[dev]"` - install dependencies (see pyproject.toml)
64
+ - open base.py and point dependencies to localhost (do not commit these changes) TODO: fix this so we auto-detect local development
64
65
  - `npm run start:python` - spins up Jupyter lab and should open the browser for you
65
66
 
66
67
  For an example of how to use the components in a Jupyter Notebook, open the `/notebooks/playground.ipynb` notebook in Jupyter Lab.
@@ -1,6 +1,6 @@
1
1
  terra_ui_components/README.md,sha256=lBRXP8aio8W0AqDiXL9hkgGlPKfPTELiXZflujVT6BY,198
2
- terra_ui_components/__init__.py,sha256=wrNVE-uJ_UEvl8bkdbaqYN_c7dAZ_IEi5j0r5IMWbAo,908
3
- terra_ui_components/base.py,sha256=4Mx8xTqP07qg0VN-bP1RkzL3aj8Ol6ZtW4QPV1PyPEY,1224
2
+ terra_ui_components/__init__.py,sha256=2048zaqJKHd_FSTxfZAvGdR_sZSgo15mog3ko6pFw10,980
3
+ terra_ui_components/base.py,sha256=7eIWyBZe8_RGqm8NH2auca12--TFlbw3b-9Vw6IgTeE,1224
4
4
  terra_ui_components/accordion/__init__.py,sha256=xruOtrVmmzFKacs2B_lKpEnDh2PbBq-HUKCdceRNboU,67
5
5
  terra_ui_components/accordion/accordion.py,sha256=3duUmiJ5DTMYfzMJmra8pt0CXXcOkcbY-aAb7-PVCIs,1789
6
6
  terra_ui_components/browse_variables/__init__.py,sha256=JfrTDLSbAecttohBx_OuEC1qT-LoqGO4egStvlJY1Os,86
@@ -19,6 +19,8 @@ terra_ui_components/date_range_slider/__init__.py,sha256=8rFfB6ilThf7fvuGsFZ8w4n
19
19
  terra_ui_components/date_range_slider/date_range_slider.py,sha256=kE3vMFV-CZ45n8F48qE0Vrs3taPClxSrZRy8ffOEbp0,3511
20
20
  terra_ui_components/dialog/__init__.py,sha256=6H2fOO3FawjPtowliaCxyneITsS4MXZy1YJYWgVKFCY,58
21
21
  terra_ui_components/dialog/dialog.py,sha256=GRKktKwUpkSAE7gl8-ivZ5O18iK9oHEb2m7vKjxJIR0,1780
22
+ terra_ui_components/earthdata_login/__init__.py,sha256=GvxmPtvxZZfx34Z-y89x6hmx-n2wbrsAK_9lk0l8QV0,83
23
+ terra_ui_components/earthdata_login/earthdata_login.py,sha256=O5NssydZKYRR90M3GsQj11lWpoEIUb2DiPpuRqkSpjw,6597
22
24
  terra_ui_components/input/__init__.py,sha256=UIEQqNyGMwv-BkeGqVjD_A_nXhiS5Tpv6WxBD7aZibk,55
23
25
  terra_ui_components/input/input.py,sha256=JTsFjXMO9jifhisaQ2fLz7OFsTxrv_4U4AIMIXbxewU,1777
24
26
  terra_ui_components/login/__init__.py,sha256=R9Rn-D770XK5bIsVdQ4EwiafuISYUxYpq15zxJeyk-A,55
@@ -33,7 +35,7 @@ terra_ui_components/time_series/__init__.py,sha256=uXQun39vOajxJjfOIPC4W-909Sb8Q
33
35
  terra_ui_components/time_series/time_series.py,sha256=M29nbYf-wmsxyu7WgeQu-pejF598zXuBd9MwAEIW704,3833
34
36
  terra_ui_components/variable_keyword_search/__init__.py,sha256=yjNToGluREKDD4UbkIOROSdlCC4jO6sgHA741OEwVdk,107
35
37
  terra_ui_components/variable_keyword_search/variable_keyword_search.py,sha256=D_jT-FAu0fubKsC0ttK_XF80ExehLnwLyvSLpVVik_o,3677
36
- terra_ui_components-0.0.129.dist-info/METADATA,sha256=jPQLGDJKKT4f68qJRobazf86WsAL0xwkqjTPmTGjOSo,3091
37
- terra_ui_components-0.0.129.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
38
- terra_ui_components-0.0.129.dist-info/licenses/LICENSE.md,sha256=rJ_6y_yHe29CU6SBs8DtutDAGaw1BqO1FBWzNvSgwFQ,1065
39
- terra_ui_components-0.0.129.dist-info/RECORD,,
38
+ terra_ui_components-0.0.135.dist-info/METADATA,sha256=__dC3QOl2y-jWbeakju2-wULbVGj_EllY5id8i7QkKs,3225
39
+ terra_ui_components-0.0.135.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
40
+ terra_ui_components-0.0.135.dist-info/licenses/LICENSE.md,sha256=rJ_6y_yHe29CU6SBs8DtutDAGaw1BqO1FBWzNvSgwFQ,1065
41
+ terra_ui_components-0.0.135.dist-info/RECORD,,