Skip to content

Commit 01fe865

Browse files
committed
Add download featureset functionality
Improve downloaded featureset formatting
1 parent cdadbfe commit 01fe865

File tree

3 files changed

+31
-12
lines changed

3 files changed

+31
-12
lines changed

cesium_app/app_server.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@ def make_app(cfg, baselayer_handlers, baselayer_settings):
5656
handlers = baselayer_handlers + [
5757
(r'/project(/.*)?', ProjectHandler),
5858
(r'/dataset(/.*)?', DatasetHandler),
59-
(r'/features(/.*)?', FeatureHandler),
59+
(r'/features(/[0-9]+)?', FeatureHandler),
60+
(r'/features/([0-9]+)/(download)', FeatureHandler),
6061
(r'/models(/[0-9]+)?', ModelHandler),
6162
(r'/models/([0-9]+)/(download)', ModelHandler),
6263
(r'/predictions(/[0-9]+)?', PredictionHandler),

cesium_app/handlers/feature.py

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,20 +13,34 @@
1313
from os.path import join as pjoin
1414
import uuid
1515
import datetime
16+
import pandas as pd
1617

1718

1819
class FeatureHandler(BaseHandler):
1920
@auth_or_token
20-
def get(self, featureset_id=None):
21-
if featureset_id is not None:
22-
featureset_info = Featureset.get_if_owned_by(featureset_id,
23-
self.current_user)
21+
def get(self, featureset_id=None, action=None):
22+
if action == 'download':
23+
fset_path = Featureset.get_if_owned_by(featureset_id,
24+
self.current_user).file_uri
25+
print(fset_path)
26+
fset, data = featurize.load_featureset(fset_path)
27+
fset.index.name = 'ts_name'
28+
fset.columns = fset.columns.get_level_values(0)
29+
fset.columns.name = None
30+
self.set_header("Content-Type", 'text/csv; charset="utf-8"')
31+
self.set_header("Content-Disposition", "attachment; "
32+
"filename=cesium_featureset.csv")
33+
self.write(fset.to_csv(index=True))
2434
else:
25-
featureset_info = [f for p in self.current_user.projects
26-
for f in p.featuresets]
27-
featureset_info.sort(key=lambda f: f.created_at, reverse=True)
28-
29-
self.success(featureset_info)
35+
if featureset_id is not None:
36+
featureset_info = Featureset.get_if_owned_by(featureset_id,
37+
self.current_user)
38+
else:
39+
featureset_info = [f for p in self.current_user.projects
40+
for f in p.featuresets]
41+
featureset_info.sort(key=lambda f: f.created_at, reverse=True)
42+
43+
self.success(featureset_info)
3044

3145
@auth_or_token
3246
async def _await_featurization(self, future, fset):

static/js/components/Features.jsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import Plot from './Plot';
1313
import FoldableRow from './FoldableRow';
1414
import { reformatDatetime, contains } from '../utils';
1515
import Delete from './Delete';
16+
import Download from './Download';
1617

1718
const { Tab, Tabs, TabList, TabPanel } = { ...ReactTabs };
1819

@@ -257,7 +258,11 @@ export let FeatureTable = props => (
257258
<td>{featureset.name}</td>
258259
<td>{reformatDatetime(featureset.created_at)}</td>
259260
{status}
260-
<td><DeleteFeatureset ID={featureset.id} /></td>
261+
<td>
262+
<Download url={`/features/${featureset.id}/download`} />
263+
&nbsp;&nbsp;
264+
<DeleteFeatureset ID={featureset.id} />
265+
</td>
261266
</tr>
262267
{foldedContent}
263268
</FoldableRow>
@@ -290,7 +295,6 @@ FeatureTable = connect(ftMapStateToProps)(FeatureTable);
290295
const mapDispatchToProps = dispatch => (
291296
{ delete: id => dispatch(Action.deleteFeatureset(id)) }
292297
);
293-
294298
const DeleteFeatureset = connect(null, mapDispatchToProps)(Delete);
295299

296300
export default FeaturesTab;

0 commit comments

Comments
 (0)