figpack 0.2.2__py3-none-any.whl → 0.2.3__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.

Potentially problematic release.


This version of figpack might be problematic. Click here for more details.

figpack/__init__.py CHANGED
@@ -2,4 +2,4 @@
2
2
  figpack - A Python package for creating shareable, interactive visualizations in the browser
3
3
  """
4
4
 
5
- __version__ = "0.2.2"
5
+ __version__ = "0.2.3"
@@ -38,6 +38,19 @@ def _is_in_notebook() -> bool:
38
38
  return False
39
39
 
40
40
 
41
+ def _is_in_colab():
42
+ try:
43
+ import google.colab # type: ignore
44
+
45
+ return True
46
+ except ImportError:
47
+ return False
48
+
49
+
50
+ def _is_in_jupyterhub():
51
+ return "JUPYTERHUB_USER" in os.environ
52
+
53
+
41
54
  def _display_inline_iframe(url: str, height: int) -> None:
42
55
  """
43
56
  Display an iframe inline in a Jupyter notebook.
@@ -75,6 +88,7 @@ def _show_view(
75
88
  port: Union[int, None] = None,
76
89
  allow_origin: Union[str, None] = None,
77
90
  upload: bool = False,
91
+ ephemeral: bool = False,
78
92
  title: Union[str, None] = None,
79
93
  description: Union[str, None] = None,
80
94
  inline: Union[bool, None] = None,
@@ -91,16 +105,17 @@ def _show_view(
91
105
  with tempfile.TemporaryDirectory(prefix="figpack_upload_") as tmpdir:
92
106
  prepare_figure_bundle(view, tmpdir, title=title, description=description)
93
107
 
94
- # Check for required environment variable
108
+ # Check for API key - required for regular uploads, optional for ephemeral
95
109
  api_key = os.environ.get("FIGPACK_API_KEY")
96
- if not api_key:
110
+ if not ephemeral and not api_key:
97
111
  raise EnvironmentError(
98
112
  "FIGPACK_API_KEY environment variable must be set to upload views."
99
113
  )
100
114
 
101
115
  # Upload the bundle
102
- print("Starting upload...")
103
- figure_url = _upload_bundle(tmpdir, api_key, title=title)
116
+ figure_url = _upload_bundle(
117
+ tmpdir, api_key, title=title, ephemeral=ephemeral
118
+ )
104
119
 
105
120
  if use_inline:
106
121
  # For uploaded figures, display the remote URL inline and continue
@@ -133,33 +133,45 @@ def _create_or_get_figure(
133
133
  total_files: int = None,
134
134
  total_size: int = None,
135
135
  title: str = None,
136
+ ephemeral: bool = False,
136
137
  ) -> dict:
137
138
  """
138
139
  Create a new figure or get existing figure information
139
140
 
140
141
  Args:
141
142
  figure_hash: The hash of the figure
142
- api_key: The API key for authentication
143
+ api_key: The API key for authentication (required for non-ephemeral)
143
144
  total_files: Optional total number of files
144
145
  total_size: Optional total size of files
145
146
  title: Optional title for the figure
147
+ ephemeral: Whether to create an ephemeral figure
146
148
 
147
149
  Returns:
148
150
  dict: Figure information from the API
149
151
  """
152
+ # Validate API key requirement
153
+ if not ephemeral and api_key is None:
154
+ raise ValueError("API key is required for non-ephemeral figures")
155
+
150
156
  payload = {
151
157
  "figureHash": figure_hash,
152
- "apiKey": api_key,
153
158
  "figpackVersion": __version__,
154
159
  }
155
160
 
161
+ # API key is optional for ephemeral figures
162
+ if api_key is not None:
163
+ payload["apiKey"] = api_key
164
+
156
165
  if total_files is not None:
157
166
  payload["totalFiles"] = total_files
158
167
  if total_size is not None:
159
168
  payload["totalSize"] = total_size
160
169
  if title is not None:
161
170
  payload["title"] = title
171
+ if ephemeral:
172
+ payload["ephemeral"] = True
162
173
 
174
+ # Use the same endpoint for both regular and ephemeral figures
163
175
  response = requests.post(f"{FIGPACK_API_BASE_URL}/api/figures/create", json=payload)
164
176
 
165
177
  if not response.ok:
@@ -212,16 +224,16 @@ def _finalize_figure(figure_url: str, api_key: str) -> dict:
212
224
  return response_data
213
225
 
214
226
 
215
- def _upload_bundle(tmpdir: str, api_key: str, title: str = None) -> str:
227
+ def _upload_bundle(
228
+ tmpdir: str, api_key: str, title: str = None, ephemeral: bool = False
229
+ ) -> str:
216
230
  """
217
231
  Upload the prepared bundle to the cloud using the new database-driven approach
218
232
  """
219
233
  tmpdir_path = pathlib.Path(tmpdir)
220
234
 
221
235
  # Compute deterministic figure ID based on file contents
222
- print("Computing deterministic figure ID...")
223
236
  figure_hash = _compute_deterministic_figure_hash(tmpdir_path)
224
- print(f"Figure hash: {figure_hash}")
225
237
 
226
238
  # Collect all files to upload
227
239
  all_files = []
@@ -239,17 +251,15 @@ def _upload_bundle(tmpdir: str, api_key: str, title: str = None) -> str:
239
251
 
240
252
  # Find available figure ID and create/get figure in database with metadata
241
253
  result = _create_or_get_figure(
242
- figure_hash, api_key, total_files, total_size, title=title
254
+ figure_hash, api_key, total_files, total_size, title=title, ephemeral=ephemeral
243
255
  )
244
256
  figure_info = result.get("figure", {})
245
257
  figure_url = figure_info.get("figureUrl")
246
258
 
247
259
  if figure_info["status"] == "completed":
248
- print(f"Figure already exists at: {figure_url}")
260
+ print(f"Figure already exists. No upload needed.")
249
261
  return figure_url
250
262
 
251
- print(f"Using figure URL: {figure_url}")
252
-
253
263
  files_to_upload = all_files
254
264
  total_files_to_upload = len(files_to_upload)
255
265
 
@@ -18,7 +18,8 @@ class FigpackView:
18
18
  port: Union[int, None] = None,
19
19
  open_in_browser: bool = False,
20
20
  allow_origin: Union[str, None] = None,
21
- upload: bool = False,
21
+ upload: Union[bool, None] = None,
22
+ ephemeral: Union[bool, None] = None,
22
23
  _dev: bool = False,
23
24
  title: Union[str, None] = None,
24
25
  description: Union[str, None] = None,
@@ -33,13 +34,37 @@ class FigpackView:
33
34
  open_in_browser: Whether to open in browser automatically
34
35
  allow_origin: CORS allow origin header
35
36
  upload: Whether to upload the figure
37
+ ephemeral: Whether to upload as ephemeral figure (None=auto-detect, True=force ephemeral, False=force regular)
36
38
  _dev: Development mode flag
37
39
  title: Title for the browser tab and figure
38
40
  description: Description text (markdown supported) for the figure
39
41
  inline: Whether to display inline in notebook (None=auto-detect, True=force inline, False=force browser)
40
42
  inline_height: Height in pixels for inline iframe display (default: 600)
41
43
  """
42
- from ._show_view import _show_view
44
+ from ._show_view import (
45
+ _show_view,
46
+ _is_in_notebook,
47
+ _is_in_colab,
48
+ _is_in_jupyterhub,
49
+ )
50
+
51
+ if ephemeral is None and upload is None:
52
+ # If we haven't specified both, then let's check if we're in a notebook in a non-local environment
53
+ if _is_in_notebook():
54
+ if _is_in_colab():
55
+ # if we are in a notebook and in colab, we should show as uploaded ephemeral
56
+ print("Detected Google Colab notebook environment.")
57
+ upload = True
58
+ ephemeral = True
59
+ if _is_in_jupyterhub():
60
+ # if we are in a notebook and in jupyterhub, we should show as uploaded ephemeral
61
+ print("Detected JupyterHub notebook environment.")
62
+ upload = True
63
+ ephemeral = True
64
+
65
+ # Validate ephemeral parameter
66
+ if ephemeral and not upload:
67
+ raise ValueError("ephemeral=True requires upload=True to be set")
43
68
 
44
69
  if _dev:
45
70
  if port is None:
@@ -61,6 +86,7 @@ class FigpackView:
61
86
  open_in_browser=open_in_browser,
62
87
  allow_origin=allow_origin,
63
88
  upload=upload,
89
+ ephemeral=ephemeral,
64
90
  title=title,
65
91
  description=description,
66
92
  inline=inline,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: figpack
3
- Version: 0.2.2
3
+ Version: 0.2.3
4
4
  Summary: A Python package for creating shareable, interactive visualizations in the browser
5
5
  Author-email: Jeremy Magland <jmagland@flatironinstitute.org>
6
6
  License: Apache-2.0
@@ -1,12 +1,12 @@
1
- figpack/__init__.py,sha256=BlI-Bj-E91wj4Sbs7MKpLjKuVrld9nLGeiNTSjNHoGw,124
1
+ figpack/__init__.py,sha256=qKVa2XgXzmxB506Y98CMOKvDXy8y-xdiDmkDLGJ3YE8,124
2
2
  figpack/cli.py,sha256=DYV-DxzWnQTMNywW-ZzhlTEFOEIt11rAKdobdBmRQFk,12051
3
3
  figpack/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
4
  figpack/core/_bundle_utils.py,sha256=73E6FinAvrt1QATGncIqyg6JLeiWVmlGF8NOcFyeYSs,1913
5
5
  figpack/core/_server_manager.py,sha256=8uxJftMgJ7EcVXtLo_VQuaiCZIyqgE89yDfCXKEgyeQ,10922
6
- figpack/core/_show_view.py,sha256=muuz0jMptAz7Z63kHlQzaBstKDwYWx4aM912xUD7Vrs,4892
7
- figpack/core/_upload_bundle.py,sha256=5nVNfHJewhu0oPPrBDkf9pzYj4T7ZyQFyZBgpK2v4qQ,12960
6
+ figpack/core/_show_view.py,sha256=WeHbQ1qdq5Lr54XTuNqmCIrwR4jbPWu8dT7Sm_UNcsk,5194
7
+ figpack/core/_upload_bundle.py,sha256=8D3M778E7nvkl9xnyrFOBlFhOOhywdiwLzOSPCMm4KE,13351
8
8
  figpack/core/config.py,sha256=6EU9CMvzGk9308Xlx8iJ2cIHJV6pqhXyiZGkK2snA4g,108
9
- figpack/core/figpack_view.py,sha256=85wb_oom0MSOk7eV8Xm96lOKYo0ggYyQJ_NC4F79qn8,2474
9
+ figpack/core/figpack_view.py,sha256=q-Xxk9X4dnLy_kGX0POC7FLB6qwmBfqrWD6uelPJZVE,3708
10
10
  figpack/figpack-gui-dist/index.html,sha256=HU8Dv1EzISPzQjibGxDA6tAz7VpzjL6o-HXOPKv4s4E,486
11
11
  figpack/figpack-gui-dist/assets/index-Cmae55E4.css,sha256=Yg0apcYehJwQvSQIUH13S7tsfqWQDevpJsAho0dDf0g,5499
12
12
  figpack/figpack-gui-dist/assets/index-DUR9Dmwh.js,sha256=iHbhpBXkfKoDzn-ZDxh2_uktWyzSTwes9gzgdBEM7PU,1590964
@@ -39,9 +39,9 @@ figpack/views/TabLayout.py,sha256=5g3nmL95PfqgI0naqZXHMwLVo2ebDlGX01Hy9044bUw,18
39
39
  figpack/views/TabLayoutItem.py,sha256=xmHA0JsW_6naJze4_mQuP_Fy0Nm17p2N7w_AsmVRp8k,880
40
40
  figpack/views/TimeseriesGraph.py,sha256=OAaCjO8fo86u_gO_frNfRGxng3tczxGDGKcJEvZo3rE,7469
41
41
  figpack/views/__init__.py,sha256=8y4KdRtrdDF0-xtQQkj4k_d8Ajk44Q7myztl3StdZcU,407
42
- figpack-0.2.2.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
43
- figpack-0.2.2.dist-info/METADATA,sha256=vbtrTDAXwFUDxLwYY_7DsjhXY6gHjMvl3r_5UH8Ectk,5886
44
- figpack-0.2.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
45
- figpack-0.2.2.dist-info/entry_points.txt,sha256=l6d3siH2LxXa8qJGbjAqpIZtI5AkMSyDeoRDCzdrUto,45
46
- figpack-0.2.2.dist-info/top_level.txt,sha256=lMKGaC5xWmAYBx9Ac1iMokm42KFnJFjmkP2ldyvOo-c,8
47
- figpack-0.2.2.dist-info/RECORD,,
42
+ figpack-0.2.3.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
43
+ figpack-0.2.3.dist-info/METADATA,sha256=m_CybGYmcQYpRliR1ZkHMP7sM7qbSTR89sVKBzZvTOI,5886
44
+ figpack-0.2.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
45
+ figpack-0.2.3.dist-info/entry_points.txt,sha256=l6d3siH2LxXa8qJGbjAqpIZtI5AkMSyDeoRDCzdrUto,45
46
+ figpack-0.2.3.dist-info/top_level.txt,sha256=lMKGaC5xWmAYBx9Ac1iMokm42KFnJFjmkP2ldyvOo-c,8
47
+ figpack-0.2.3.dist-info/RECORD,,