Skip to content

Commit f76d119

Browse files
committed
Merge remote-tracking branch 'origin/release/9.0' into experiment/mlflow-models
2 parents 447c082 + 83d26e5 commit f76d119

File tree

12 files changed

+669
-196
lines changed

12 files changed

+669
-196
lines changed

HISTORY.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,16 @@
11
Changelog
22
==========
33

4+
9.0.0 (2021-05-07)
5+
------------------
6+
7+
* Initial release for DSS 9.0
8+
9+
8.0.0 (2020-08-14)
10+
-------------------
11+
12+
* Initial release for DSS 8.0
13+
414
7.0.0 (2020-07-21)
515
------------------
616

LICENSE.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Copyright 2015-2017 Dataiku SAS
1+
Copyright 2015-2021 Dataiku SAS
22

33
Licensed under the Apache License, Version 2.0 (the "License");
44
you may not use this file except in compliance with the License.

dataikuapi/dss/apiservice.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,3 +106,16 @@ def download_package_to_file(self, package_id, path):
106106
f.write(chunk)
107107
f.flush()
108108

109+
def publish_package(self, package_id, published_service_id=None):
110+
"""
111+
Publish a package on the API Deployer.
112+
113+
:param string package_id: The identifier of the package
114+
:param string published_service_id: The identifier of the API service on the API Deployer where the package will be published.
115+
A new published API service will be created if none matches the identifier.
116+
If the parameter is not set, the identifier from the current :class:`DSSAPIService` is used.
117+
"""
118+
params = None
119+
if published_service_id is not None:
120+
params = {"publishedServiceId": published_service_id}
121+
self.client._perform_empty("POST", "/projects/%s/apiservices/%s/packages/%s/publish" % (self.project_key, self.service_id, package_id), params=params)

dataikuapi/dss/dataset.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -608,6 +608,11 @@ def test_and_detect(self, infer_storage_types=False):
608608
elif settings.type in self.__class__._SQL_TYPES:
609609
return self.client._perform_json("POST",
610610
"/projects/%s/datasets/%s/actions/testAndDetectSettings/externalSQL"% (self.project_key, self.dataset_name))
611+
612+
elif settings.type == "ElasticSearch":
613+
return self.client._perform_json("POST",
614+
"/projects/%s/datasets/%s/actions/testAndDetectSettings/elasticsearch"% (self.project_key, self.dataset_name))
615+
611616
else:
612617
raise ValueError("don't know how to test/detect on dataset type:%s" % settings.type)
613618

@@ -642,6 +647,15 @@ def autodetect_settings(self, infer_storage_types=False):
642647

643648
settings.get_raw()["schema"] = result["schemaDetection"]["newSchema"]
644649
return settings
650+
651+
elif settings.type == "ElasticSearch":
652+
result = self.test_and_detect()
653+
654+
if not "schemaDetection" in result:
655+
raise DataikuException("Format detection failed, complete response is " + json.dumps(result))
656+
657+
settings.get_raw()["schema"] = result["schemaDetection"]["newSchema"]
658+
return settings
645659

646660
else:
647661
raise ValueError("don't know how to test/detect on dataset type:%s" % settings.type)

dataikuapi/dss/future.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,8 @@ def wait_for_result(self):
7272
"""
7373
Wait and get the future result
7474
"""
75-
if self.state.get('hasResult', False):
75+
if self.state is not None and self.state.get('hasResult', False):
76+
# no future created in backend, result already in the state
7677
return self.result_wrapper(self.state.get('result', None))
7778
if self.state is None or not self.state.get('hasResult', False) or self.state_is_peek:
7879
self.get_state()

dataikuapi/dss/jupyternotebook.py

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
from .discussion import DSSObjectDiscussions
2+
from .utils import DSSTaggableObjectListItem
3+
4+
class DSSJupyterNotebookListItem(DSSTaggableObjectListItem):
5+
"""An item in a list of Jupyter notebooks. Do not instantiate this class, use :meth:`dataikuapi.dss.project.DSSProject.list_jupyter_notebooks`"""
6+
def __init__(self, client, data):
7+
super(DSSJupyterNotebookListItem, self).__init__(data)
8+
self.client = client
9+
10+
def to_notebook(self):
11+
"""Gets the :class:`DSSJupyterNotebook` corresponding to this notebook"""
12+
return DSSJupyterNotebook(self.client, self._data["projectKey"], self._data["name"])
13+
14+
@property
15+
def name(self):
16+
return self._data["name"]
17+
@property
18+
def language(self):
19+
return self._data["language"]
20+
@property
21+
def kernel_spec(self):
22+
return self._data["kernelSpec"]
23+
24+
class DSSJupyterNotebook(object):
25+
def __init__(self, client, project_key, notebook_name):
26+
self.client = client
27+
self.project_key = project_key
28+
self.notebook_name = notebook_name
29+
30+
def unload(self, session_id=None):
31+
"""
32+
Stop this Jupyter notebook and release its resources
33+
"""
34+
sessions = self.get_sessions()
35+
if sessions is None:
36+
raise Exception("Notebook isn't running")
37+
if len(sessions) == 0:
38+
raise Exception("Notebook isn't running")
39+
if session_id is None:
40+
if len(sessions) > 1:
41+
raise Exception("Several sessions of the notebook are running, choose one")
42+
else:
43+
session_id = sessions[0].get('sessionId', None)
44+
return self.client._perform_json("DELETE",
45+
"/projects/%s/jupyter-notebooks/%s/sessions/%s" % (self.project_key, self.notebook_name, session_id))
46+
47+
def get_sessions(self, as_objects=False):
48+
"""
49+
Get the list of running sessions of this Jupyter notebook
50+
51+
:param boolean as_objects: if True, each returned item will be a :class:`dataikuapi.dss.notebook.DSSNotebookSession`
52+
:rtype: list of :class:`dataikuapi.dss.notebook.DSSNotebookSession` or list of dict
53+
"""
54+
sessions = self.client._perform_json("GET",
55+
"/projects/%s/jupyter-notebooks/%s/sessions" % (self.project_key, self.notebook_name))
56+
57+
if as_objects:
58+
return [DSSNotebookSession(self.client, session) for session in sessions]
59+
else:
60+
return sessions
61+
62+
def get_content(self):
63+
"""
64+
Get the content of this Jupyter notebook (metadata, cells, nbformat)
65+
"""
66+
raw_content = self.client._perform_json("GET", "/projects/%s/jupyter-notebooks/%s" % (self.project_key, self.notebook_name))
67+
return DSSNotebookContent(self.client, self.project_key, self.notebook_name, raw_content)
68+
69+
def delete(self):
70+
"""
71+
Delete this Jupyter notebook and stop all of its active sessions.
72+
"""
73+
return self.client._perform_json("DELETE",
74+
"/projects/%s/jupyter-notebooks/%s" % (self.project_key, self.notebook_name))
75+
76+
########################################################
77+
# Discussions
78+
########################################################
79+
def get_object_discussions(self):
80+
"""
81+
Get a handle to manage discussions on the notebook
82+
83+
:returns: the handle to manage discussions
84+
:rtype: :class:`dataikuapi.discussion.DSSObjectDiscussions`
85+
"""
86+
return DSSObjectDiscussions(self.client, self.project_key, "JUPYTER_NOTEBOOK", self.notebook_name)
87+
88+
class DSSNotebookContent(object):
89+
"""
90+
Content of a Jupyter Notebook. Do not create this directly, use :meth:`DSSJupyterNotebook.get_content`
91+
"""
92+
93+
"""
94+
A Python/R/Scala notebook on the DSS instance
95+
"""
96+
def __init__(self, client, project_key, notebook_name, content):
97+
self.client = client
98+
self.project_key = project_key
99+
self.notebook_name = notebook_name
100+
self.content = content
101+
102+
def get_raw(self):
103+
"""
104+
Get the content of this Jupyter notebook (metadata, cells, nbformat)
105+
:rtype: a dict containing the full content of a notebook
106+
"""
107+
return self.content
108+
109+
def get_metadata(self):
110+
"""
111+
Get the metadata associated to this Jupyter notebook
112+
:rtype: dict with metadata
113+
"""
114+
return self.content["metadata"]
115+
116+
def get_cells(self):
117+
"""
118+
Get the cells associated to this Jupyter notebook
119+
:rtype: list of cells
120+
"""
121+
return self.content["cells"]
122+
123+
def save(self):
124+
"""
125+
Save the content of this Jupyter notebook
126+
"""
127+
return self.client._perform_json("PUT",
128+
"/projects/%s/jupyter-notebooks/%s" % (self.project_key, self.notebook_name),
129+
body=self.content)
130+
131+
class DSSNotebookSession(object):
132+
"""
133+
Metadata associated to the session of a Jupyter Notebook. Do not create this directly, use :meth:`DSSJupyterNotebook.get_sessions()`
134+
"""
135+
136+
def __init__(self, client, session):
137+
self.client = client
138+
self.project_key = session.get("projectKey")
139+
self.notebook_name = session.get("notebookName")
140+
self.session_creator = session.get("sessionCreator")
141+
self.session_creator_display_name = session.get("sessionCreatorDisplayName")
142+
self.session_unix_owner = session.get("sessionUnixOwner")
143+
self.session_id = session.get("sessionId")
144+
self.kernel_id = session.get("kernelId")
145+
self.kernel_pid = session.get("kernelPid")
146+
self.kernel_connections = session.get("kernelConnections")
147+
self.kernel_last_activity_time = session.get("kernelLastActivityTime")
148+
self.kernel_execution_state = session.get("kernelExecutionState")
149+
self.session_start_time = session.get("sessionStartTime")
150+
151+
152+
def unload(self):
153+
"""
154+
Stop this Jupyter notebook and release its resources
155+
"""
156+
return self.client._perform_json("DELETE",
157+
"/projects/%s/jupyter-notebooks/%s/sessions/%s" % (self.project_key, self.notebook_name, self.session_id))

0 commit comments

Comments
 (0)