2
2
import abc
3
3
import base64
4
4
import zipfile
5
+ import warnings
6
+
5
7
from uuid import uuid4
6
8
from typing import List , Optional , Type , Union
7
9
10
+ try :
11
+ # Python 3.8+
12
+ # pylint: disable=ungrouped-imports
13
+ from typing import TypedDict # type: ignore
14
+ except (ImportError , ModuleNotFoundError ):
15
+ # Python < 3.8
16
+ from typing_extensions import TypedDict # type: ignore
17
+
18
+
8
19
import bleach
9
20
from dash .development .base_component import Component
10
21
from dash .dependencies import Input , Output
11
22
import webviz_core_components as wcc
12
23
13
24
25
+ class FileDefinition (TypedDict , total = False ):
26
+ file_name : str
27
+ content : str
28
+ mime_type : str
29
+
30
+
14
31
class WebvizPluginABC (abc .ABC ):
15
32
"""All webviz plugins need to subclass this abstract base class,
16
33
e.g.
@@ -40,7 +57,6 @@ def layout(self):
40
57
TOOLBAR_BUTTONS = [
41
58
"screenshot" ,
42
59
"expand" ,
43
- "download_zip" ,
44
60
"contact_person" ,
45
61
"guided_tour" ,
46
62
]
@@ -62,6 +78,7 @@ def __init__(self, screenshot_filename: str = "webviz-screenshot.png") -> None:
62
78
63
79
self ._plugin_uuid = uuid4 ()
64
80
self ._screenshot_filename = screenshot_filename
81
+ self ._add_download_button = False
65
82
66
83
def uuid (self , element : str ) -> str :
67
84
"""Typically used to get a unique ID for some given element/component in
@@ -94,10 +111,8 @@ def _plugin_wrapper_id(self) -> str:
94
111
95
112
@property
96
113
def plugin_data_output (self ) -> Output :
97
- # pylint: disable=attribute-defined-outside-init
98
- # We do not have a __init__ method in this abstract base class
99
114
self ._add_download_button = True
100
- return Output (self ._plugin_wrapper_id , "zip_base64 " )
115
+ return Output (self ._plugin_wrapper_id , "download " )
101
116
102
117
@property
103
118
def plugin_data_requested (self ) -> Input :
@@ -110,16 +125,29 @@ def _reformat_tour_steps(steps: List[dict]) -> List[dict]:
110
125
]
111
126
112
127
@staticmethod
113
- def plugin_data_compress (content : List [dict ]) -> str :
128
+ def plugin_compressed_data (
129
+ file_name : str , content : List [FileDefinition ]
130
+ ) -> FileDefinition :
114
131
byte_io = io .BytesIO ()
115
132
116
133
with zipfile .ZipFile (byte_io , "w" ) as zipped_data :
117
134
for data in content :
118
- zipped_data .writestr (data ["filename " ], data ["content" ])
135
+ zipped_data .writestr (data ["file_name " ], data ["content" ])
119
136
120
137
byte_io .seek (0 )
138
+ return {
139
+ "file_name" : file_name ,
140
+ "content" : base64 .b64encode (byte_io .read ()).decode ("ascii" ),
141
+ "mime_type" : "application/zip" ,
142
+ }
121
143
122
- return base64 .b64encode (byte_io .read ()).decode ("ascii" )
144
+ @staticmethod
145
+ def plugin_data_compress (content : List [dict ]) -> FileDefinition :
146
+ warnings .warn (
147
+ "Use 'plugin_compressed_data' instead of 'plugin_data_compress'" ,
148
+ DeprecationWarning ,
149
+ )
150
+ return WebvizPluginABC .plugin_compressed_data ("webviz-data.zip" , content )
123
151
124
152
def plugin_layout (
125
153
self , contact_person : Optional [dict ] = None
@@ -145,8 +173,8 @@ def plugin_layout(
145
173
for key in contact_person :
146
174
contact_person [key ] = bleach .clean (str (contact_person [key ]))
147
175
148
- if "download_zip" in buttons and not hasattr ( self , " _add_download_button" ) :
149
- buttons .remove ( "download_zip " )
176
+ if self . _add_download_button :
177
+ buttons .append ( "download " )
150
178
151
179
if buttons :
152
180
# pylint: disable=no-member
0 commit comments